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, 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},
124 {SWAP, "swap", picGenericOne, NULL}
127 /*-----------------------------------------------------------------*/
128 /* checkConstantRange: check a constant against the type */
129 /*-----------------------------------------------------------------*/
132 /* pedantic=0: allmost anything is allowed as long as the absolute
133 value is within the bit range of the type, and -1 is treated as
134 0xf..f for unsigned types (e.g. in assign)
135 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
136 pedantic>1: "char c=200" is not allowed (evaluates to -56)
139 void checkConstantRange(sym_link *ltype, value *val, char *msg,
146 max = pow ((double)2.0, (double)bitsForType(ltype));
148 if (IS_LONG(val->type)) {
149 if (IS_UNSIGNED(val->type)) {
150 v=SPEC_CVAL(val->type).v_ulong;
152 v=SPEC_CVAL(val->type).v_long;
155 if (IS_UNSIGNED(val->type)) {
156 v=SPEC_CVAL(val->type).v_uint;
158 v=SPEC_CVAL(val->type).v_int;
164 // this could be a good idea
165 if (options.pedantic)
169 if (IS_FLOAT(ltype)) {
174 if (!IS_UNSIGNED(val->type) && v<0) {
176 if (IS_UNSIGNED(ltype) && (pedantic>1)) {
182 // if very pedantic: "char c=200" is not allowed
183 if (pedantic>1 && !IS_UNSIGNED(ltype)) {
184 max = max/2 + negative;
191 #if 0 // temporary disabled, leaving the warning as a reminder
193 SNPRINTF (message, sizeof(message), "for %s %s in %s",
194 IS_UNSIGNED(ltype) ? "unsigned" : "signed",
195 nounName(ltype), msg);
196 werror (W_CONST_RANGE, message);
204 /*-----------------------------------------------------------------*/
205 /* operandName - returns the name of the operand */
206 /*-----------------------------------------------------------------*/
208 printOperand (operand * op, FILE * file)
225 opetype = getSpec (operandType (op));
226 if (IS_FLOAT (opetype))
227 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
229 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
230 printTypeChain (operandType (op), file);
237 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d a2p%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}" , */
238 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
240 OP_LIVEFROM (op), OP_LIVETO (op),
241 OP_SYMBOL (op)->stack,
242 op->isaddr, op->aggr2ptr, OP_SYMBOL (op)->isreqv,
243 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
244 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
248 printTypeChain (operandType (op), file);
249 if (SPIL_LOC (op) && IS_ITEMP (op))
250 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
255 /* if assigned to registers */
256 if (OP_SYMBOL (op)->nRegs)
258 if (OP_SYMBOL (op)->isspilt)
260 if (!OP_SYMBOL (op)->remat)
261 if (OP_SYMBOL (op)->usl.spillLoc)
262 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
263 OP_SYMBOL (op)->usl.spillLoc->rname :
264 OP_SYMBOL (op)->usl.spillLoc->name));
266 fprintf (file, "[err]");
268 fprintf (file, "[remat]");
274 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
275 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
280 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
281 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
282 /* if assigned to registers */
283 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
287 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
288 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
289 OP_SYMBOL (op)->regs[i]->name :
298 printTypeChain (op->operand.typeOperand, file);
304 fprintf (file, "\n");
309 /*-----------------------------------------------------------------*/
310 /* print functions */
311 /*-----------------------------------------------------------------*/
312 PRINTFUNC (picGetValueAtAddr)
315 printOperand (IC_RESULT (ic), of);
318 printOperand (IC_LEFT (ic), of);
324 PRINTFUNC (picSetValueAtAddr)
328 printOperand (IC_LEFT (ic), of);
329 fprintf (of, "] = ");
330 printOperand (IC_RIGHT (ic), of);
334 PRINTFUNC (picAddrOf)
337 printOperand (IC_RESULT (ic), of);
338 if (IS_ITEMP (IC_LEFT (ic)))
341 fprintf (of, " = &[");
342 printOperand (IC_LEFT (ic), of);
345 if (IS_ITEMP (IC_LEFT (ic)))
346 fprintf (of, " offsetAdd ");
349 printOperand (IC_RIGHT (ic), of);
351 if (IS_ITEMP (IC_LEFT (ic)))
357 PRINTFUNC (picJumpTable)
362 fprintf (of, "%s\t", s);
363 printOperand (IC_JTCOND (ic), of);
365 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
366 sym = setNextItem (IC_JTLABELS (ic)))
367 fprintf (of, "\t\t\t%s\n", sym->name);
370 PRINTFUNC (picGeneric)
373 printOperand (IC_RESULT (ic), of);
375 printOperand (IC_LEFT (ic), of);
376 fprintf (of, " %s ", s);
377 printOperand (IC_RIGHT (ic), of);
381 PRINTFUNC (picGenericOne)
386 printOperand (IC_RESULT (ic), of);
392 fprintf (of, "%s ", s);
393 printOperand (IC_LEFT (ic), of);
396 if (!IC_RESULT (ic) && !IC_LEFT (ic))
399 if (ic->op == SEND || ic->op == RECEIVE) {
400 fprintf(of,"{argreg = %d}",ic->argreg);
402 if (ic->op == IPUSH) {
403 fprintf(of,"{parmPush = %d}",ic->parmPush);
411 printOperand (IC_RESULT (ic), of);
413 printOperand (IC_LEFT (ic), of);
414 printOperand (IC_RIGHT (ic), of);
419 PRINTFUNC (picAssign)
423 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
426 printOperand (IC_RESULT (ic), of);
428 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
431 fprintf (of, " %s ", s);
432 printOperand (IC_RIGHT (ic), of);
439 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
445 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
452 printOperand (IC_COND (ic), of);
455 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
458 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
460 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
464 PRINTFUNC (picInline)
466 fprintf (of, "%s", IC_INLINE (ic));
469 PRINTFUNC (picReceive)
471 printOperand (IC_RESULT (ic), of);
472 fprintf (of, " = %s ", s);
473 printOperand (IC_LEFT (ic), of);
477 PRINTFUNC (picDummyRead)
480 fprintf (of, "%s ", s);
481 printOperand (IC_RIGHT (ic), of);
485 PRINTFUNC (picCritical)
489 printOperand (IC_RESULT (ic), of);
491 fprintf (of, "(stack)");
492 fprintf (of, " = %s ", s);
496 PRINTFUNC (picEndCritical)
499 fprintf (of, "%s = ", s);
501 printOperand (IC_RIGHT (ic), of);
503 fprintf (of, "(stack)");
507 /*-----------------------------------------------------------------*/
508 /* piCode - prints one iCode */
509 /*-----------------------------------------------------------------*/
511 piCode (void *item, FILE * of)
519 icTab = getTableEntry (ic->op);
520 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
521 ic->filename, ic->lineno,
522 ic->seq, ic->key, ic->depth, ic->supportRtn);
523 icTab->iCodePrint (of, ic, icTab->printName);
529 printiCChain(ic,stdout);
531 /*-----------------------------------------------------------------*/
532 /* printiCChain - prints intermediate code for humans */
533 /*-----------------------------------------------------------------*/
535 printiCChain (iCode * icChain, FILE * of)
542 for (loop = icChain; loop; loop = loop->next)
544 if ((icTab = getTableEntry (loop->op)))
546 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
547 loop->filename, loop->lineno,
548 loop->seq, loop->key, loop->depth, loop->supportRtn);
550 icTab->iCodePrint (of, loop, icTab->printName);
556 /*-----------------------------------------------------------------*/
557 /* newOperand - allocate, init & return a new iCode */
558 /*-----------------------------------------------------------------*/
564 op = Safe_alloc ( sizeof (operand));
570 /*-----------------------------------------------------------------*/
571 /* newiCode - create and return a new iCode entry initialised */
572 /*-----------------------------------------------------------------*/
574 newiCode (int op, operand * left, operand * right)
578 ic = Safe_alloc ( sizeof (iCode));
580 ic->seqPoint = seqPoint;
582 ic->filename = filename;
584 ic->level = scopeLevel;
586 ic->key = iCodeKey++;
588 IC_RIGHT (ic) = right;
593 /*-----------------------------------------------------------------*/
594 /* newiCode for conditional statements */
595 /*-----------------------------------------------------------------*/
597 newiCodeCondition (operand * condition,
603 if (IS_VOID(operandType(condition))) {
604 werror(E_VOID_VALUE_USED);
607 ic = newiCode (IFX, NULL, NULL);
608 IC_COND (ic) = condition;
609 IC_TRUE (ic) = trueLabel;
610 IC_FALSE (ic) = falseLabel;
614 /*-----------------------------------------------------------------*/
615 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
616 /*-----------------------------------------------------------------*/
618 newiCodeLabelGoto (int op, symbol * label)
622 ic = newiCode (op, NULL, NULL);
626 IC_RIGHT (ic) = NULL;
627 IC_RESULT (ic) = NULL;
631 /*-----------------------------------------------------------------*/
632 /* newiTemp - allocate & return a newItemp Variable */
633 /*-----------------------------------------------------------------*/
641 SNPRINTF (buffer, sizeof(buffer), "%s", s);
645 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
648 itmp = newSymbol (buffer, 1);
649 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
655 /*-----------------------------------------------------------------*/
656 /* newiTempLabel - creates a temp variable label */
657 /*-----------------------------------------------------------------*/
659 newiTempLabel (char *s)
663 /* check if this already exists */
664 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
669 itmplbl = newSymbol (s, 1);
673 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
674 itmplbl = newSymbol (buffer, 1);
679 itmplbl->key = labelKey++;
680 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
684 /*-----------------------------------------------------------------*/
685 /* newiTempPreheaderLabel - creates a new preheader label */
686 /*-----------------------------------------------------------------*/
688 newiTempPreheaderLabel ()
692 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
693 itmplbl = newSymbol (buffer, 1);
697 itmplbl->key = labelKey++;
698 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
703 /*-----------------------------------------------------------------*/
704 /* initiCode - initialises some iCode related stuff */
705 /*-----------------------------------------------------------------*/
712 /*-----------------------------------------------------------------*/
713 /* copyiCode - make a copy of the iCode given */
714 /*-----------------------------------------------------------------*/
716 copyiCode (iCode * ic)
718 iCode *nic = newiCode (ic->op, NULL, NULL);
720 nic->lineno = ic->lineno;
721 nic->filename = ic->filename;
722 nic->block = ic->block;
723 nic->level = ic->level;
724 nic->parmBytes = ic->parmBytes;
726 /* deal with the special cases first */
730 IC_COND (nic) = operandFromOperand (IC_COND (ic));
731 IC_TRUE (nic) = IC_TRUE (ic);
732 IC_FALSE (nic) = IC_FALSE (ic);
736 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
737 IC_JTLABELS (nic) = IC_JTLABELS (ic);
742 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
743 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
747 IC_INLINE (nic) = IC_INLINE (ic);
751 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
755 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
756 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
757 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
763 /*-----------------------------------------------------------------*/
764 /* getTableEntry - gets the table entry for the given operator */
765 /*-----------------------------------------------------------------*/
767 getTableEntry (int oper)
771 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
772 if (oper == codeTable[i].icode)
773 return &codeTable[i];
778 /*-----------------------------------------------------------------*/
779 /* newiTempOperand - new intermediate temp operand */
780 /*-----------------------------------------------------------------*/
782 newiTempOperand (sym_link * type, char throwType)
785 operand *op = newOperand ();
789 itmp = newiTemp (NULL);
791 etype = getSpec (type);
793 if (IS_LITERAL (etype))
796 /* copy the type information */
798 itmp->etype = getSpec (itmp->type = (throwType ? type :
799 copyLinkChain (type)));
800 if (IS_LITERAL (itmp->etype))
802 SPEC_SCLS (itmp->etype) = S_REGISTER;
803 SPEC_OCLS (itmp->etype) = reg;
806 op->operand.symOperand = itmp;
807 op->key = itmp->key = ++operandKey;
811 /*-----------------------------------------------------------------*/
812 /* operandType - returns the type chain for an operand */
813 /*-----------------------------------------------------------------*/
815 operandType (operand * op)
817 /* depending on type of operand */
822 return op->operand.valOperand->type;
825 return op->operand.symOperand->type;
828 return op->operand.typeOperand;
830 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
831 " operand type not known ");
832 assert (0); /* should never come here */
833 /* Just to keep the compiler happy */
834 return (sym_link *) 0;
838 /*-----------------------------------------------------------------*/
839 /* isParamterToCall - will return 1 if op is a parameter to args */
840 /*-----------------------------------------------------------------*/
842 isParameterToCall (value * args, operand * op)
846 wassert (IS_SYMOP(op));
851 isSymbolEqual (op->operand.symOperand, tval->sym))
858 /*-----------------------------------------------------------------*/
859 /* isOperandGlobal - return 1 if operand is a global variable */
860 /*-----------------------------------------------------------------*/
862 isOperandGlobal (operand * op)
871 (op->operand.symOperand->level == 0 ||
872 IS_STATIC (op->operand.symOperand->etype) ||
873 IS_EXTERN (op->operand.symOperand->etype))
880 /*-----------------------------------------------------------------*/
881 /* isOperandVolatile - return 1 if the operand is volatile */
882 /*-----------------------------------------------------------------*/
884 isOperandVolatile (operand * op, bool chkTemp)
889 if (IS_ITEMP (op) && !chkTemp)
892 opetype = getSpec (optype = operandType (op));
894 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
897 if (IS_VOLATILE (opetype))
902 /*-----------------------------------------------------------------*/
903 /* isOperandLiteral - returns 1 if an operand contains a literal */
904 /*-----------------------------------------------------------------*/
906 isOperandLiteral (operand * op)
913 opetype = getSpec (operandType (op));
915 if (IS_LITERAL (opetype))
921 /*-----------------------------------------------------------------*/
922 /* isOperandInFarSpace - will return true if operand is in farSpace */
923 /*-----------------------------------------------------------------*/
925 isOperandInFarSpace (operand * op)
935 if (!IS_TRUE_SYMOP (op))
938 etype = SPIL_LOC (op)->etype;
944 etype = getSpec (operandType (op));
946 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
949 /*------------------------------------------------------------------*/
950 /* isOperandInDirSpace - will return true if operand is in dirSpace */
951 /*------------------------------------------------------------------*/
953 isOperandInDirSpace (operand * op)
963 if (!IS_TRUE_SYMOP (op))
966 etype = SPIL_LOC (op)->etype;
972 etype = getSpec (operandType (op));
974 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
977 /*--------------------------------------------------------------------*/
978 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
979 /*--------------------------------------------------------------------*/
981 isOperandInCodeSpace (operand * op)
991 etype = getSpec (operandType (op));
993 if (!IS_TRUE_SYMOP (op))
996 etype = SPIL_LOC (op)->etype;
1002 etype = getSpec (operandType (op));
1004 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1007 /*-----------------------------------------------------------------*/
1008 /* isOperandOnStack - will return true if operand is on stack */
1009 /*-----------------------------------------------------------------*/
1011 isOperandOnStack (operand * op)
1021 etype = getSpec (operandType (op));
1022 if (IN_STACK (etype) ||
1023 OP_SYMBOL(op)->onStack ||
1024 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1030 /*-----------------------------------------------------------------*/
1031 /* isOclsExpensive - will return true if accesses to an output */
1032 /* storage class are expensive */
1033 /*-----------------------------------------------------------------*/
1035 isOclsExpensive (struct memmap *oclass)
1037 if (port->oclsExpense)
1038 return port->oclsExpense (oclass) > 0;
1040 /* In the absence of port specific guidance, assume only */
1041 /* farspace is expensive. */
1042 return IN_FARSPACE (oclass);
1045 /*-----------------------------------------------------------------*/
1046 /* isiCodeInFunctionCall - return TRUE if an iCode is between a */
1047 /* CALL/PCALL and the first IPUSH/SEND associated with the call */
1048 /*-----------------------------------------------------------------*/
1050 isiCodeInFunctionCall (iCode * ic)
1054 /* Find the next CALL/PCALL */
1057 if (lic->op == CALL || lic->op == PCALL)
1065 /* A function call was found. Scan backwards and see if an */
1066 /* IPUSH or SEND is encountered */
1069 if (lic != ic && (ic->op == CALL || ic->op == PCALL))
1071 if (ic->op == SEND || (ic->op == IPUSH && ic->parmPush))
1079 /*-----------------------------------------------------------------*/
1080 /* operandLitValue - literal value of an operand */
1081 /*-----------------------------------------------------------------*/
1083 operandLitValue (operand * op)
1085 assert (isOperandLiteral (op));
1087 return floatFromVal (op->operand.valOperand);
1090 /*-----------------------------------------------------------------*/
1091 /* getBuiltInParms - returns parameters to a builtin functions */
1092 /*-----------------------------------------------------------------*/
1093 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1098 /* builtin functions uses only SEND for parameters */
1099 while (ic->op != CALL) {
1100 assert(ic->op == SEND && ic->builtinSEND);
1101 ic->generated = 1; /* mark the icode as generated */
1102 parms[*pcount] = IC_LEFT(ic);
1108 /* make sure this is a builtin function call */
1109 assert(IS_SYMOP(IC_LEFT(ic)));
1110 ftype = operandType(IC_LEFT(ic));
1111 assert(IFFUNC_ISBUILTIN(ftype));
1115 /*-----------------------------------------------------------------*/
1116 /* operandOperation - performs operations on operands */
1117 /*-----------------------------------------------------------------*/
1119 operandOperation (operand * left, operand * right,
1120 int op, sym_link * type)
1122 sym_link *let , *ret=NULL;
1123 operand *retval = (operand *) 0;
1125 assert (isOperandLiteral (left));
1126 let = getSpec(operandType(left));
1128 assert (isOperandLiteral (right));
1129 ret = getSpec(operandType(right));
1135 retval = operandFromValue (valCastLiteral (type,
1136 operandLitValue (left) +
1137 operandLitValue (right)));
1140 retval = operandFromValue (valCastLiteral (type,
1141 operandLitValue (left) -
1142 operandLitValue (right)));
1146 retval = operandFromValue (valCastLiteral (type,
1147 operandLitValue (left) *
1148 operandLitValue (right)));
1149 This could be all we've to do, but with gcc we've to take care about
1150 overflows. Two examples:
1151 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1152 significant bits are lost (52 in fraction, 63 bits would be
1153 necessary to keep full precision).
1154 If the resulting double value is greater than ULONG_MAX (resp.
1155 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1158 /* if it is not a specifier then we can assume that */
1159 /* it will be an unsigned long */
1160 if (IS_INT (type) ||
1163 /* long is handled here, because it can overflow with double */
1164 if (IS_LONG (type) ||
1166 /* signed and unsigned mul are the same, as long as the precision
1167 of the result isn't bigger than the precision of the operands. */
1168 retval = operandFromValue (valCastLiteral (type,
1169 (TYPE_UDWORD) operandLitValue (left) *
1170 (TYPE_UDWORD) operandLitValue (right)));
1171 else if (IS_UNSIGNED (type)) /* unsigned int */
1173 /* unsigned int is handled here in order to detect overflow */
1174 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1175 (TYPE_UWORD) operandLitValue (right);
1177 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1178 if (ul != (TYPE_UWORD) ul)
1181 else /* signed int */
1183 /* signed int is handled here in order to detect overflow */
1184 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1185 (TYPE_WORD) operandLitValue (right);
1187 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1188 if (l != (TYPE_WORD) l)
1193 /* all others go here: */
1194 retval = operandFromValue (valCastLiteral (type,
1195 operandLitValue (left) *
1196 operandLitValue (right)));
1199 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1201 werror (E_DIVIDE_BY_ZERO);
1207 if (IS_UNSIGNED (type))
1209 SPEC_USIGN (let) = 1;
1210 SPEC_USIGN (ret) = 1;
1211 retval = operandFromValue (valCastLiteral (type,
1212 (TYPE_UDWORD) operandLitValue (left) /
1213 (TYPE_UDWORD) operandLitValue (right)));
1217 retval = operandFromValue (valCastLiteral (type,
1218 operandLitValue (left) /
1219 operandLitValue (right)));
1224 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1226 werror (E_DIVIDE_BY_ZERO);
1231 if (IS_UNSIGNED (type))
1232 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1233 (TYPE_UDWORD) operandLitValue (right));
1235 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1236 (TYPE_DWORD) operandLitValue (right));
1240 /* The number of left shifts is always unsigned. Signed doesn't make
1241 sense here. Shifting by a negative number is impossible. */
1242 retval = operandFromValue (valCastLiteral (type,
1243 ((TYPE_UDWORD) operandLitValue (left) <<
1244 (TYPE_UDWORD) operandLitValue (right))));
1247 /* The number of right shifts is always unsigned. Signed doesn't make
1248 sense here. Shifting by a negative number is impossible. */
1249 if (IS_UNSIGNED(let))
1250 /* unsigned: logic shift right */
1251 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1252 (TYPE_UDWORD) operandLitValue (right));
1254 /* signed: arithmetic shift right */
1255 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1256 (TYPE_UDWORD) operandLitValue (right));
1259 if (IS_FLOAT (let) ||
1262 retval = operandFromLit (operandLitValue (left) ==
1263 operandLitValue (right));
1267 /* this op doesn't care about signedness */
1270 l = (TYPE_UDWORD) operandLitValue (left);
1271 r = (TYPE_UDWORD) operandLitValue (right);
1272 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1273 neccessary to strip them to 16 bit.
1274 Literals are reduced to their cheapest type, therefore left and
1275 right might have different types. It's neccessary to find a
1276 common type: int (used for char too) or long */
1277 if (!IS_LONG (let) &&
1283 retval = operandFromLit (l == r);
1287 retval = operandFromLit (operandLitValue (left) <
1288 operandLitValue (right));
1291 retval = operandFromLit (operandLitValue (left) <=
1292 operandLitValue (right));
1295 retval = operandFromLit (operandLitValue (left) !=
1296 operandLitValue (right));
1299 retval = operandFromLit (operandLitValue (left) >
1300 operandLitValue (right));
1303 retval = operandFromLit (operandLitValue (left) >=
1304 operandLitValue (right));
1307 retval = operandFromValue (valCastLiteral (type,
1308 (TYPE_UDWORD)operandLitValue(left) &
1309 (TYPE_UDWORD)operandLitValue(right)));
1312 retval = operandFromValue (valCastLiteral (type,
1313 (TYPE_UDWORD)operandLitValue(left) |
1314 (TYPE_UDWORD)operandLitValue(right)));
1317 retval = operandFromValue (valCastLiteral (type,
1318 (TYPE_UDWORD)operandLitValue(left) ^
1319 (TYPE_UDWORD)operandLitValue(right)));
1322 retval = operandFromLit (operandLitValue (left) &&
1323 operandLitValue (right));
1326 retval = operandFromLit (operandLitValue (left) ||
1327 operandLitValue (right));
1331 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1333 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1339 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1341 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1347 retval = operandFromValue (valCastLiteral (type,
1348 -1 * operandLitValue (left)));
1352 retval = operandFromValue (valCastLiteral (type,
1354 operandLitValue (left))));
1358 retval = operandFromLit (!operandLitValue (left));
1362 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1363 " operandOperation invalid operator ");
1371 /*-----------------------------------------------------------------*/
1372 /* isOperandEqual - compares two operand & return 1 if they r = */
1373 /*-----------------------------------------------------------------*/
1375 isOperandEqual (operand * left, operand * right)
1377 /* if the pointers are equal then they are equal */
1381 /* if either of them null then false */
1382 if (!left || !right)
1385 if (left->type != right->type)
1388 if (IS_SYMOP (left) && IS_SYMOP (right))
1389 return left->key == right->key;
1391 /* if types are the same */
1395 return isSymbolEqual (left->operand.symOperand,
1396 right->operand.symOperand);
1398 return (floatFromVal (left->operand.valOperand) ==
1399 floatFromVal (right->operand.valOperand));
1401 if (compareType (left->operand.typeOperand,
1402 right->operand.typeOperand) == 1)
1409 /*-------------------------------------------------------------------*/
1410 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1411 /*-------------------------------------------------------------------*/
1413 isiCodeEqual (iCode * left, iCode * right)
1415 /* if the same pointer */
1419 /* if either of them null */
1420 if (!left || !right)
1423 /* if operand are the same */
1424 if (left->op == right->op)
1427 /* compare all the elements depending on type */
1428 if (left->op != IFX)
1430 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1432 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1438 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1440 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1442 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1451 /*-----------------------------------------------------------------*/
1452 /* newiTempFromOp - create a temp Operand with same attributes */
1453 /*-----------------------------------------------------------------*/
1455 newiTempFromOp (operand * op)
1465 nop = newiTempOperand (operandType (op), TRUE);
1466 nop->isaddr = op->isaddr;
1467 nop->isvolatile = op->isvolatile;
1468 nop->isGlobal = op->isGlobal;
1469 nop->isLiteral = op->isLiteral;
1470 nop->usesDefs = op->usesDefs;
1471 nop->isParm = op->isParm;
1475 /*-----------------------------------------------------------------*/
1476 /* operand from operand - creates an operand holder for the type */
1477 /*-----------------------------------------------------------------*/
1479 operandFromOperand (operand * op)
1485 nop = newOperand ();
1486 nop->type = op->type;
1487 nop->isaddr = op->isaddr;
1489 nop->isvolatile = op->isvolatile;
1490 nop->isGlobal = op->isGlobal;
1491 nop->isLiteral = op->isLiteral;
1492 nop->usesDefs = op->usesDefs;
1493 nop->isParm = op->isParm;
1498 nop->operand.symOperand = op->operand.symOperand;
1501 nop->operand.valOperand = op->operand.valOperand;
1504 nop->operand.typeOperand = op->operand.typeOperand;
1511 /*-----------------------------------------------------------------*/
1512 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1513 /*-----------------------------------------------------------------*/
1515 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1517 operand *nop = operandFromOperand (op);
1519 if (nop->type == SYMBOL)
1521 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1522 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1528 /*-----------------------------------------------------------------*/
1529 /* operandFromSymbol - creates an operand from a symbol */
1530 /*-----------------------------------------------------------------*/
1532 operandFromSymbol (symbol * sym)
1537 /* if the symbol's type is a literal */
1538 /* then it is an enumerator type */
1539 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1540 return operandFromValue (valFromType (sym->etype));
1543 sym->key = ++operandKey;
1545 /* if this an implicit variable, means struct/union */
1546 /* member so just return it */
1547 if (sym->implicit || IS_FUNC (sym->type))
1551 op->operand.symOperand = sym;
1553 op->isvolatile = isOperandVolatile (op, TRUE);
1554 op->isGlobal = isOperandGlobal (op);
1558 /* under the following conditions create a
1559 register equivalent for a local symbol */
1560 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1561 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1563 (!(options.model == MODEL_FLAT24)) ) &&
1564 options.stackAuto == 0)
1567 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1568 !IS_FUNC (sym->type) && /* not a function */
1569 !sym->_isparm && /* not a parameter */
1570 IS_AUTO (sym) && /* is a local auto variable */
1571 !sym->addrtaken && /* whose address has not been taken */
1572 !sym->reqv && /* does not already have a reg equivalence */
1573 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1574 !sym->islbl && /* not a label */
1575 ok && /* farspace check */
1576 !IS_BITVAR (sym->etype) /* not a bit variable */
1580 /* we will use it after all optimizations
1581 and before liveRange calculation */
1582 sym->reqv = newiTempOperand (sym->type, 0);
1583 sym->reqv->key = sym->key;
1584 OP_SYMBOL (sym->reqv)->prereqv = sym;
1585 OP_SYMBOL (sym->reqv)->key = sym->key;
1586 OP_SYMBOL (sym->reqv)->isreqv = 1;
1587 OP_SYMBOL (sym->reqv)->islocal = 1;
1588 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1589 SPIL_LOC (sym->reqv) = sym;
1592 if (!IS_AGGREGATE (sym->type))
1596 op->operand.symOperand = sym;
1599 op->isvolatile = isOperandVolatile (op, TRUE);
1600 op->isGlobal = isOperandGlobal (op);
1601 op->isPtr = IS_PTR (operandType (op));
1602 op->isParm = sym->_isparm;
1607 /* itemp = &[_symbol] */
1609 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1610 IC_LEFT (ic)->type = SYMBOL;
1611 IC_LEFT (ic)->operand.symOperand = sym;
1612 IC_LEFT (ic)->key = sym->key;
1613 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1614 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1615 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1618 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1619 if (IS_ARRAY (sym->type))
1621 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1622 IC_RESULT (ic)->isaddr = 0;
1625 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1629 return IC_RESULT (ic);
1632 /*-----------------------------------------------------------------*/
1633 /* operandFromValue - creates an operand from value */
1634 /*-----------------------------------------------------------------*/
1636 operandFromValue (value * val)
1640 /* if this is a symbol then do the symbol thing */
1642 return operandFromSymbol (val->sym);
1644 /* this is not a symbol */
1647 op->operand.valOperand = val;
1648 op->isLiteral = isOperandLiteral (op);
1652 /*-----------------------------------------------------------------*/
1653 /* operandFromLink - operand from typeChain */
1654 /*-----------------------------------------------------------------*/
1656 operandFromLink (sym_link * type)
1660 /* operand from sym_link */
1666 op->operand.typeOperand = copyLinkChain (type);
1670 /*-----------------------------------------------------------------*/
1671 /* operandFromLit - makes an operand from a literal value */
1672 /*-----------------------------------------------------------------*/
1674 operandFromLit (double i)
1676 return operandFromValue (valueFromLit (i));
1679 /*-----------------------------------------------------------------*/
1680 /* operandFromAst - creates an operand from an ast */
1681 /*-----------------------------------------------------------------*/
1683 operandFromAst (ast * tree,int lvl)
1689 /* depending on type do */
1693 return ast2iCode (tree,lvl+1);
1697 return operandFromValue (tree->opval.val);
1701 return operandFromLink (tree->opval.lnk);
1708 /* Just to keep the compiler happy */
1709 return (operand *) 0;
1712 /*-----------------------------------------------------------------*/
1713 /* setOperandType - sets the operand's type to the given type */
1714 /*-----------------------------------------------------------------*/
1716 setOperandType (operand * op, sym_link * type)
1718 /* depending on the type of operand */
1723 op->operand.valOperand->etype =
1724 getSpec (op->operand.valOperand->type =
1725 copyLinkChain (type));
1729 if (op->operand.symOperand->isitmp)
1730 op->operand.symOperand->etype =
1731 getSpec (op->operand.symOperand->type =
1732 copyLinkChain (type));
1734 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1735 "attempt to modify type of source");
1739 op->operand.typeOperand = copyLinkChain (type);
1745 /*-----------------------------------------------------------------*/
1746 /* Get size in byte of ptr need to access an array */
1747 /*-----------------------------------------------------------------*/
1749 getArraySizePtr (operand * op)
1751 sym_link *ltype = operandType(op);
1755 int size = getSize(ltype);
1756 return(IS_GENPTR(ltype)?(size-1):size);
1761 sym_link *letype = getSpec(ltype);
1762 switch (PTR_TYPE (SPEC_OCLS (letype)))
1774 return (GPTRSIZE-1);
1783 /*-----------------------------------------------------------------*/
1784 /* perform "usual unary conversions" */
1785 /*-----------------------------------------------------------------*/
1788 usualUnaryConversions (operand * op)
1790 if (IS_INTEGRAL (operandType (op)))
1792 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1795 return geniCodeCast (INTTYPE, op, TRUE);
1802 /*-----------------------------------------------------------------*/
1803 /* perform "usual binary conversions" */
1804 /*-----------------------------------------------------------------*/
1807 usualBinaryConversions (operand ** op1, operand ** op2,
1808 RESULT_TYPE resultType, int op)
1811 sym_link *rtype = operandType (*op2);
1812 sym_link *ltype = operandType (*op1);
1814 ctype = computeType (ltype, rtype, resultType, op);
1821 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1823 /* one byte operations: keep signedness for code generator */
1831 *op1 = geniCodeCast (ctype, *op1, TRUE);
1832 *op2 = geniCodeCast (ctype, *op2, TRUE);
1837 /*-----------------------------------------------------------------*/
1838 /* geniCodeValueAtAddress - generate intermeditate code for value */
1840 /*-----------------------------------------------------------------*/
1842 geniCodeRValue (operand * op, bool force)
1845 sym_link *type = operandType (op);
1846 sym_link *etype = getSpec (type);
1848 /* if this is an array & already */
1849 /* an address then return this */
1850 if (IS_AGGREGATE (type) ||
1851 (IS_PTR (type) && !force && !op->isaddr))
1852 return operandFromOperand (op);
1854 /* if this is not an address then must be */
1855 /* rvalue already so return this one */
1859 /* if this is not a temp symbol then */
1860 if (!IS_ITEMP (op) &&
1862 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1864 op = operandFromOperand (op);
1869 if (IS_SPEC (type) &&
1870 IS_TRUE_SYMOP (op) &&
1871 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1872 (options.model == MODEL_FLAT24) ))
1874 op = operandFromOperand (op);
1879 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1880 if (IS_PTR (type) && op->isaddr && force)
1883 type = copyLinkChain (type);
1885 IC_RESULT (ic) = newiTempOperand (type, 1);
1886 IC_RESULT (ic)->isaddr = 0;
1888 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1892 return IC_RESULT (ic);
1895 /*-----------------------------------------------------------------*/
1896 /* geniCodeCast - changes the value from one type to another */
1897 /*-----------------------------------------------------------------*/
1899 geniCodeCast (sym_link * type, operand * op, bool implicit)
1903 sym_link *opetype = getSpec (optype = operandType (op));
1907 /* one of them has size zero then error */
1908 if (IS_VOID (optype))
1910 werror (E_CAST_ZERO);
1914 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1916 geniCodeArray2Ptr (op);
1920 /* if the operand is already the desired type then do nothing */
1921 if (compareType (type, optype) == 1)
1924 /* if this is a literal then just change the type & return */
1925 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1927 return operandFromValue (valCastLiteral (type,
1928 operandLitValue (op)));
1931 /* if casting to/from pointers, do some checking */
1932 if (IS_PTR(type)) { // to a pointer
1933 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1934 if (IS_INTEGRAL(optype)) {
1935 // maybe this is NULL, than it's ok.
1936 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1937 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1938 // no way to set the storage
1939 if (IS_LITERAL(optype)) {
1940 werror(E_LITERAL_GENERIC);
1943 werror(E_NONPTR2_GENPTR);
1946 } else if (implicit) {
1947 werror(W_INTEGRAL2PTR_NOCAST);
1952 // shouldn't do that with float, array or structure unless to void
1953 if (!IS_VOID(getSpec(type)) &&
1954 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1955 werror(E_INCOMPAT_TYPES);
1959 } else { // from a pointer to a pointer
1960 if (IS_GENPTR(type) && IS_VOID(type->next))
1961 { // cast to void* is always allowed
1963 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
1964 { // cast from void* is always allowed
1966 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1967 // if not a pointer to a function
1968 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1969 if (implicit) { // if not to generic, they have to match
1970 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1971 werror(E_INCOMPAT_PTYPES);
1978 } else { // to a non pointer
1979 if (IS_PTR(optype)) { // from a pointer
1980 if (implicit) { // sneaky
1981 if (IS_INTEGRAL(type)) {
1982 werror(W_PTR2INTEGRAL_NOCAST);
1984 } else { // shouldn't do that with float, array or structure
1985 werror(E_INCOMPAT_TYPES);
1992 printFromToType (optype, type);
1995 /* if they are the same size create an assignment */
1997 /* This seems very dangerous to me, since there are several */
1998 /* optimizations (for example, gcse) that don't notice the */
1999 /* cast hidden in this assignement and may simplify an */
2000 /* iCode to use the original (uncasted) operand. */
2001 /* Unfortunately, other things break when this cast is */
2002 /* made explicit. Need to fix this someday. */
2003 /* -- EEP, 2004/01/21 */
2004 if (getSize (type) == getSize (optype) &&
2005 !IS_BITFIELD (type) &&
2007 !IS_FLOAT (optype) &&
2008 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2009 (!IS_SPEC (type) && !IS_SPEC (optype))))
2011 ic = newiCode ('=', NULL, op);
2012 IC_RESULT (ic) = newiTempOperand (type, 0);
2013 SPIL_LOC (IC_RESULT (ic)) =
2014 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
2015 IC_RESULT (ic)->isaddr = 0;
2019 ic = newiCode (CAST, operandFromLink (type),
2020 geniCodeRValue (op, FALSE));
2022 IC_RESULT (ic) = newiTempOperand (type, 0);
2025 /* preserve the storage class & output class */
2026 /* of the original variable */
2027 restype = getSpec (operandType (IC_RESULT (ic)));
2028 if (!IS_LITERAL(opetype) &&
2031 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2032 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2035 return IC_RESULT (ic);
2038 /*-----------------------------------------------------------------*/
2039 /* geniCodeLabel - will create a Label */
2040 /*-----------------------------------------------------------------*/
2042 geniCodeLabel (symbol * label)
2046 ic = newiCodeLabelGoto (LABEL, label);
2050 /*-----------------------------------------------------------------*/
2051 /* geniCodeGoto - will create a Goto */
2052 /*-----------------------------------------------------------------*/
2054 geniCodeGoto (symbol * label)
2058 ic = newiCodeLabelGoto (GOTO, label);
2062 /*-----------------------------------------------------------------*/
2063 /* geniCodeMultiply - gen intermediate code for multiplication */
2064 /*-----------------------------------------------------------------*/
2066 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2073 /* if they are both literal then we know the result */
2074 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2075 return operandFromValue (valMult (left->operand.valOperand,
2076 right->operand.valOperand));
2078 if (IS_LITERAL(retype)) {
2079 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2082 resType = usualBinaryConversions (&left, &right, resultType, '*');
2084 rtype = operandType (right);
2085 retype = getSpec (rtype);
2086 ltype = operandType (left);
2087 letype = getSpec (ltype);
2090 /* if the right is a literal & power of 2 */
2091 /* then make it a left shift */
2092 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2093 efficient in most cases than 2 bytes result = 2 bytes << literal
2094 if port has 1 byte muldiv */
2095 if (p2 && !IS_FLOAT (letype)
2096 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2097 && (port->support.muldiv == 1))
2098 && strcmp (port->target, "pic14") != 0 /* don't shift for pic */
2099 && strcmp (port->target, "pic16") != 0)
2101 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2103 /* LEFT_OP need same size for left and result, */
2104 left = geniCodeCast (resType, left, TRUE);
2105 ltype = operandType (left);
2107 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2111 ic = newiCode ('*', left, right); /* normal multiplication */
2112 /* if the size left or right > 1 then support routine */
2113 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2117 IC_RESULT (ic) = newiTempOperand (resType, 1);
2120 return IC_RESULT (ic);
2123 /*-----------------------------------------------------------------*/
2124 /* geniCodeDivision - gen intermediate code for division */
2125 /*-----------------------------------------------------------------*/
2127 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2132 sym_link *rtype = operandType (right);
2133 sym_link *retype = getSpec (rtype);
2134 sym_link *ltype = operandType (left);
2135 sym_link *letype = getSpec (ltype);
2137 resType = usualBinaryConversions (&left, &right, resultType, '/');
2139 /* if the right is a literal & power of 2
2140 and left is unsigned then make it a
2142 if (IS_LITERAL (retype) &&
2143 !IS_FLOAT (letype) &&
2144 IS_UNSIGNED(letype) &&
2145 (p2 = powof2 ((TYPE_UDWORD)
2146 floatFromVal (right->operand.valOperand)))) {
2147 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2151 ic = newiCode ('/', left, right); /* normal division */
2152 /* if the size left or right > 1 then support routine */
2153 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2156 IC_RESULT (ic) = newiTempOperand (resType, 0);
2159 return IC_RESULT (ic);
2161 /*-----------------------------------------------------------------*/
2162 /* geniCodeModulus - gen intermediate code for modulus */
2163 /*-----------------------------------------------------------------*/
2165 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2171 /* if they are both literal then we know the result */
2172 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2173 return operandFromValue (valMod (left->operand.valOperand,
2174 right->operand.valOperand));
2176 resType = usualBinaryConversions (&left, &right, resultType, '%');
2178 /* now they are the same size */
2179 ic = newiCode ('%', left, right);
2181 /* if the size left or right > 1 then support routine */
2182 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2184 IC_RESULT (ic) = newiTempOperand (resType, 0);
2187 return IC_RESULT (ic);
2190 /*-----------------------------------------------------------------*/
2191 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2192 /*-----------------------------------------------------------------*/
2194 geniCodePtrPtrSubtract (operand * left, operand * right)
2200 /* if they are both literals then */
2201 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2203 result = operandFromValue (valMinus (left->operand.valOperand,
2204 right->operand.valOperand));
2208 ic = newiCode ('-', left, right);
2210 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2214 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2218 // should we really do this? is this ANSI?
2219 return geniCodeDivision (result,
2220 operandFromLit (getSize (ltype->next)),
2224 /*-----------------------------------------------------------------*/
2225 /* geniCodeSubtract - generates code for subtraction */
2226 /*-----------------------------------------------------------------*/
2228 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2235 /* if they both pointers then */
2236 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2237 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2238 return geniCodePtrPtrSubtract (left, right);
2240 /* if they are both literal then we know the result */
2241 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2242 && left->isLiteral && right->isLiteral)
2243 return operandFromValue (valMinus (left->operand.valOperand,
2244 right->operand.valOperand));
2246 /* if left is an array or pointer */
2247 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2249 isarray = left->isaddr;
2250 right = geniCodeMultiply (right,
2251 operandFromLit (getSize (ltype->next)),
2252 (getArraySizePtr(left) >= INTSIZE) ?
2255 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2258 { /* make them the same size */
2259 resType = usualBinaryConversions (&left, &right, resultType, '-');
2262 ic = newiCode ('-', left, right);
2264 IC_RESULT (ic) = newiTempOperand (resType, 1);
2265 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2267 /* if left or right is a float */
2268 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2272 return IC_RESULT (ic);
2275 /*-----------------------------------------------------------------*/
2276 /* geniCodeAdd - generates iCode for addition */
2277 /*-----------------------------------------------------------------*/
2279 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2288 /* if the right side is LITERAL zero */
2289 /* return the left side */
2290 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2293 /* if left is literal zero return right */
2294 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2297 /* if left is a pointer then size */
2298 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2300 isarray = left->isaddr;
2301 // there is no need to multiply with 1
2302 if (getSize (ltype->next) != 1)
2304 size = operandFromLit (getSize (ltype->next));
2305 SPEC_USIGN (getSpec (operandType (size))) = 1;
2306 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2307 right = geniCodeMultiply (right,
2309 (getArraySizePtr(left) >= INTSIZE) ?
2312 /* Even if right is a 'unsigned char',
2313 the result will be a 'signed int' due to the promotion rules.
2314 It doesn't make sense when accessing arrays, so let's fix it here: */
2316 SPEC_USIGN (getSpec (operandType (right))) = 1;
2318 resType = copyLinkChain (ltype);
2321 { // make them the same size
2322 resType = usualBinaryConversions (&left, &right, resultType, '+');
2325 /* if they are both literals then we know */
2326 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2327 && left->isLiteral && right->isLiteral)
2328 return operandFromValue (valPlus (valFromType (ltype),
2329 valFromType (rtype)));
2331 ic = newiCode ('+', left, right);
2333 IC_RESULT (ic) = newiTempOperand (resType, 1);
2334 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2336 /* if left or right is a float then support
2338 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2343 return IC_RESULT (ic);
2347 /*-----------------------------------------------------------------*/
2348 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2349 /*-----------------------------------------------------------------*/
2351 aggrToPtr (sym_link * type, bool force)
2356 if (IS_PTR (type) && !force)
2359 etype = getSpec (type);
2360 ptype = newLink (DECLARATOR);
2364 /* set the pointer depending on the storage class */
2365 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2369 /*------------------------------------------------------------------*/
2370 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2371 /*------------------------------------------------------------------*/
2373 aggrToPtrDclType (sym_link * type, bool force)
2375 if (IS_PTR (type) && !force)
2376 return DCL_TYPE (type);
2378 /* return the pointer depending on the storage class */
2379 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2382 /*-----------------------------------------------------------------*/
2383 /* geniCodeArray2Ptr - array to pointer */
2384 /*-----------------------------------------------------------------*/
2386 geniCodeArray2Ptr (operand * op)
2388 sym_link *optype = operandType (op);
2389 sym_link *opetype = getSpec (optype);
2391 /* set the pointer depending on the storage class */
2392 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2399 /*-----------------------------------------------------------------*/
2400 /* geniCodeArray - array access */
2401 /*-----------------------------------------------------------------*/
2403 geniCodeArray (operand * left, operand * right, int lvl)
2407 sym_link *ltype = operandType (left);
2412 if (IS_PTR (ltype->next) && left->isaddr)
2414 left = geniCodeRValue (left, FALSE);
2417 return geniCodeDerefPtr (geniCodeAdd (left,
2419 (getArraySizePtr(left) >= INTSIZE) ?
2425 size = operandFromLit (getSize (ltype->next));
2426 SPEC_USIGN (getSpec (operandType (size))) = 1;
2427 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2428 right = geniCodeMultiply (right,
2430 (getArraySizePtr(left) >= INTSIZE) ?
2433 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2434 It doesn't make sense when accessing arrays, so let's fix it here: */
2436 SPEC_USIGN (getSpec (operandType (right))) = 1;
2437 /* we can check for limits here */
2438 /* already done in SDCCast.c
2439 if (isOperandLiteral (right) &&
2442 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2444 werror (W_IDX_OUT_OF_BOUNDS,
2445 (int) operandLitValue (right) / getSize (ltype->next),
2450 ic = newiCode ('+', left, right);
2452 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2453 !IS_AGGREGATE (ltype->next) &&
2454 !IS_PTR (ltype->next))
2455 ? ltype : ltype->next), 0);
2457 if (!IS_AGGREGATE (ltype->next))
2459 IC_RESULT (ic)->isaddr = 1;
2460 IC_RESULT (ic)->aggr2ptr = 1;
2464 return IC_RESULT (ic);
2467 /*-----------------------------------------------------------------*/
2468 /* geniCodeStruct - generates intermediate code for structures */
2469 /*-----------------------------------------------------------------*/
2471 geniCodeStruct (operand * left, operand * right, bool islval)
2474 sym_link *type = operandType (left);
2475 sym_link *etype = getSpec (type);
2477 symbol *element = getStructElement (SPEC_STRUCT (etype),
2478 right->operand.symOperand);
2480 wassert(IS_SYMOP(right));
2482 /* add the offset */
2483 ic = newiCode ('+', left, operandFromLit (element->offset));
2485 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2487 /* preserve the storage & output class of the struct */
2488 /* as well as the volatile attribute */
2489 retype = getSpec (operandType (IC_RESULT (ic)));
2490 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2491 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2492 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2493 SPEC_CONST (retype) |= SPEC_CONST (etype);
2495 if (IS_PTR (element->type))
2496 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2498 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2501 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2504 /*-----------------------------------------------------------------*/
2505 /* geniCodePostInc - generate int code for Post increment */
2506 /*-----------------------------------------------------------------*/
2508 geniCodePostInc (operand * op)
2512 sym_link *optype = operandType (op);
2514 operand *rv = (IS_ITEMP (op) ?
2515 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2517 sym_link *rvtype = operandType (rv);
2520 /* if this is not an address we have trouble */
2523 werror (E_LVALUE_REQUIRED, "++");
2527 rOp = newiTempOperand (rvtype, 0);
2528 OP_SYMBOL(rOp)->noSpilLoc = 1;
2531 OP_SYMBOL(rv)->noSpilLoc = 1;
2533 geniCodeAssign (rOp, rv, 0, 0);
2535 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2537 werror(W_SIZEOF_VOID);
2538 if (IS_FLOAT (rvtype))
2539 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2541 ic = newiCode ('+', rv, operandFromLit (size));
2543 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2546 geniCodeAssign (op, result, 0, 0);
2552 /*-----------------------------------------------------------------*/
2553 /* geniCodePreInc - generate code for preIncrement */
2554 /*-----------------------------------------------------------------*/
2556 geniCodePreInc (operand * op, bool lvalue)
2559 sym_link *optype = operandType (op);
2560 operand *rop = (IS_ITEMP (op) ?
2561 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2563 sym_link *roptype = operandType (rop);
2569 werror (E_LVALUE_REQUIRED, "++");
2573 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2575 werror(W_SIZEOF_VOID);
2576 if (IS_FLOAT (roptype))
2577 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2579 ic = newiCode ('+', rop, operandFromLit (size));
2580 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2583 (void) geniCodeAssign (op, result, 0, 0);
2584 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2590 /*-----------------------------------------------------------------*/
2591 /* geniCodePostDec - generates code for Post decrement */
2592 /*-----------------------------------------------------------------*/
2594 geniCodePostDec (operand * op)
2598 sym_link *optype = operandType (op);
2600 operand *rv = (IS_ITEMP (op) ?
2601 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2603 sym_link *rvtype = operandType (rv);
2606 /* if this is not an address we have trouble */
2609 werror (E_LVALUE_REQUIRED, "--");
2613 rOp = newiTempOperand (rvtype, 0);
2614 OP_SYMBOL(rOp)->noSpilLoc = 1;
2617 OP_SYMBOL(rv)->noSpilLoc = 1;
2619 geniCodeAssign (rOp, rv, 0, 0);
2621 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2623 werror(W_SIZEOF_VOID);
2624 if (IS_FLOAT (rvtype))
2625 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2627 ic = newiCode ('-', rv, operandFromLit (size));
2629 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2632 geniCodeAssign (op, result, 0, 0);
2638 /*-----------------------------------------------------------------*/
2639 /* geniCodePreDec - generate code for pre decrement */
2640 /*-----------------------------------------------------------------*/
2642 geniCodePreDec (operand * op, bool lvalue)
2645 sym_link *optype = operandType (op);
2646 operand *rop = (IS_ITEMP (op) ?
2647 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2649 sym_link *roptype = operandType (rop);
2655 werror (E_LVALUE_REQUIRED, "--");
2659 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2661 werror(W_SIZEOF_VOID);
2662 if (IS_FLOAT (roptype))
2663 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2665 ic = newiCode ('-', rop, operandFromLit (size));
2666 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2669 (void) geniCodeAssign (op, result, 0, 0);
2670 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2677 /*-----------------------------------------------------------------*/
2678 /* geniCodeBitwise - gen int code for bitWise operators */
2679 /*-----------------------------------------------------------------*/
2681 geniCodeBitwise (operand * left, operand * right,
2682 int oper, sym_link * resType)
2686 left = geniCodeCast (resType, left, TRUE);
2687 right = geniCodeCast (resType, right, TRUE);
2689 ic = newiCode (oper, left, right);
2690 IC_RESULT (ic) = newiTempOperand (resType, 0);
2693 return IC_RESULT (ic);
2696 /*-----------------------------------------------------------------*/
2697 /* geniCodeAddressOf - gens icode for '&' address of operator */
2698 /*-----------------------------------------------------------------*/
2700 geniCodeAddressOf (operand * op)
2704 sym_link *optype = operandType (op);
2705 sym_link *opetype = getSpec (optype);
2707 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2709 op = operandFromOperand (op);
2714 /* lvalue check already done in decorateType */
2715 /* this must be a lvalue */
2716 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2717 /* werror (E_LVALUE_REQUIRED,"&"); */
2721 p = newLink (DECLARATOR);
2723 /* set the pointer depending on the storage class */
2724 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2726 p->next = copyLinkChain (optype);
2728 /* if already a temp */
2731 setOperandType (op, p);
2736 /* other wise make this of the type coming in */
2737 ic = newiCode (ADDRESS_OF, op, NULL);
2738 IC_RESULT (ic) = newiTempOperand (p, 1);
2739 IC_RESULT (ic)->isaddr = 0;
2741 return IC_RESULT (ic);
2743 /*-----------------------------------------------------------------*/
2744 /* setOClass - sets the output class depending on the pointer type */
2745 /*-----------------------------------------------------------------*/
2747 setOClass (sym_link * ptr, sym_link * spec)
2749 switch (DCL_TYPE (ptr))
2752 SPEC_OCLS (spec) = data;
2756 SPEC_OCLS (spec) = generic;
2760 SPEC_OCLS (spec) = xdata;
2764 SPEC_OCLS (spec) = code;
2768 SPEC_OCLS (spec) = idata;
2772 SPEC_OCLS (spec) = xstack;
2776 SPEC_OCLS (spec) = eeprom;
2785 /*-----------------------------------------------------------------*/
2786 /* geniCodeDerefPtr - dereference pointer with '*' */
2787 /*-----------------------------------------------------------------*/
2789 geniCodeDerefPtr (operand * op,int lvl)
2791 sym_link *rtype, *retype;
2792 sym_link *optype = operandType (op);
2794 // if this is an array then array access
2795 if (IS_ARRAY (optype)) {
2796 // don't worry, this will be optimized out later
2797 return geniCodeArray (op, operandFromLit (0), lvl);
2800 // just in case someone screws up
2801 wassert (IS_PTR (optype));
2803 if (IS_TRUE_SYMOP (op))
2806 op = geniCodeRValue (op, TRUE);
2809 /* now get rid of the pointer part */
2810 if (isLvaluereq(lvl) && IS_ITEMP (op))
2812 retype = getSpec (rtype = copyLinkChain (optype));
2816 retype = getSpec (rtype = copyLinkChain (optype->next));
2817 /* outputclass needs 2b updated */
2818 setOClass (optype, retype);
2821 op->isGptr = IS_GENPTR (optype);
2823 op->isaddr = (IS_PTR (rtype) ||
2824 IS_STRUCT (rtype) ||
2829 if (!isLvaluereq(lvl))
2830 op = geniCodeRValue (op, TRUE);
2832 setOperandType (op, rtype);
2837 /*-----------------------------------------------------------------*/
2838 /* geniCodeUnaryMinus - does a unary minus of the operand */
2839 /*-----------------------------------------------------------------*/
2841 geniCodeUnaryMinus (operand * op)
2844 sym_link *optype = operandType (op);
2846 if (IS_LITERAL (optype))
2847 return operandFromLit (-floatFromVal (op->operand.valOperand));
2849 ic = newiCode (UNARYMINUS, op, NULL);
2850 IC_RESULT (ic) = newiTempOperand (optype, 0);
2852 return IC_RESULT (ic);
2855 /*-----------------------------------------------------------------*/
2856 /* geniCodeLeftShift - gen i code for left shift */
2857 /*-----------------------------------------------------------------*/
2859 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2864 ic = newiCode (LEFT_OP, left, right);
2866 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2867 IC_RESULT (ic) = newiTempOperand (resType, 0);
2869 return IC_RESULT (ic);
2872 /*-----------------------------------------------------------------*/
2873 /* geniCodeRightShift - gen i code for right shift */
2874 /*-----------------------------------------------------------------*/
2876 geniCodeRightShift (operand * left, operand * right)
2880 ic = newiCode (RIGHT_OP, left, right);
2881 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2883 return IC_RESULT (ic);
2886 /*-----------------------------------------------------------------*/
2887 /* geniCodeLogic- logic code */
2888 /*-----------------------------------------------------------------*/
2890 geniCodeLogic (operand * left, operand * right, int op)
2894 sym_link *rtype = operandType (right);
2895 sym_link *ltype = operandType (left);
2897 /* left is integral type and right is literal then
2898 check if the literal value is within bounds */
2899 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2901 checkConstantRange(ltype,
2902 OP_VALUE(right), "compare operation", 1);
2905 /* if one operand is a pointer and the other is a literal generic void pointer,
2906 change the type of the literal generic void pointer to match the other pointer */
2907 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2908 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2910 /* find left's definition */
2911 ic = (iCode *) setFirstItem (iCodeChain);
2914 if (((ic->op == CAST) || (ic->op == '='))
2915 && isOperandEqual(left, IC_RESULT (ic)))
2918 ic = setNextItem (iCodeChain);
2920 /* if casting literal to generic pointer, then cast to rtype instead */
2921 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2923 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2924 ltype = operandType(left);
2927 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2928 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2930 /* find right's definition */
2931 ic = (iCode *) setFirstItem (iCodeChain);
2934 if (((ic->op == CAST) || (ic->op == '='))
2935 && isOperandEqual(right, IC_RESULT (ic)))
2938 ic = setNextItem (iCodeChain);
2940 /* if casting literal to generic pointer, then cast to rtype instead */
2941 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2943 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2944 rtype = operandType(right);
2948 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
2950 ic = newiCode (op, left, right);
2951 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2953 /* if comparing float
2954 and not a '==' || '!=' || '&&' || '||' (these
2956 if (IS_FLOAT(ctype) &&
2964 return IC_RESULT (ic);
2967 /*-----------------------------------------------------------------*/
2968 /* geniCodeLogicAndOr - && || operations */
2969 /*-----------------------------------------------------------------*/
2971 geniCodeLogicAndOr (ast *tree, int lvl)
2974 symbol *falseLabel = newiTempLabel (NULL);
2975 symbol *trueLabel = newiTempLabel (NULL);
2976 symbol *exitLabel = newiTempLabel (NULL);
2977 operand *op, *result, *condition;
2979 /* AND_OP and OR_OP are no longer generated because of bug-905492.
2980 They can be reenabled by executing the following block. If you find
2981 a decent optimization you could start right here:
2986 operand *leftOp, *rightOp;
2988 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
2989 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
2991 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
2995 /* generate two IFX for the '&&' or '||' op */
2997 /* evaluate left operand */
2998 condition = ast2iCode (tree->left, lvl + 1);
2999 op = geniCodeRValue (condition, FALSE);
3001 /* test left operand */
3002 if (tree->opval.op == AND_OP)
3003 ic = newiCodeCondition (op, NULL, falseLabel);
3005 ic = newiCodeCondition (op, trueLabel, NULL);
3008 /* evaluate right operand */
3009 condition = ast2iCode (tree->right, lvl + 1);
3010 op = geniCodeRValue (condition, FALSE);
3012 /* test right operand */
3013 ic = newiCodeCondition (op, trueLabel, NULL);
3016 /* store 0 or 1 in result */
3017 result = newiTempOperand (newCharLink(), 1);
3019 geniCodeLabel (falseLabel);
3020 geniCodeAssign (result, operandFromLit (0), 0, 0);
3021 /* generate an unconditional goto */
3022 geniCodeGoto (exitLabel);
3024 geniCodeLabel (trueLabel);
3025 geniCodeAssign (result, operandFromLit (1), 0, 0);
3027 geniCodeLabel (exitLabel);
3032 /*-----------------------------------------------------------------*/
3033 /* geniCodeUnary - for a a generic unary operation */
3034 /*-----------------------------------------------------------------*/
3036 geniCodeUnary (operand * op, int oper)
3038 iCode *ic = newiCode (oper, op, NULL);
3040 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3042 return IC_RESULT (ic);
3045 /*-----------------------------------------------------------------*/
3046 /* geniCodeConditional - geniCode for '?' ':' operation */
3047 /*-----------------------------------------------------------------*/
3049 geniCodeConditional (ast * tree,int lvl)
3052 symbol *falseLabel = newiTempLabel (NULL);
3053 symbol *exitLabel = newiTempLabel (NULL);
3054 operand *cond = ast2iCode (tree->left,lvl+1);
3055 operand *true, *false, *result;
3057 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3061 true = ast2iCode (tree->right->left,lvl+1);
3063 /* move the value to a new Operand */
3064 result = newiTempOperand (tree->right->ftype, 0);
3065 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3067 /* generate an unconditional goto */
3068 geniCodeGoto (exitLabel);
3070 /* now for the right side */
3071 geniCodeLabel (falseLabel);
3073 false = ast2iCode (tree->right->right,lvl+1);
3074 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3076 /* create the exit label */
3077 geniCodeLabel (exitLabel);
3082 /*-----------------------------------------------------------------*/
3083 /* geniCodeAssign - generate code for assignment */
3084 /*-----------------------------------------------------------------*/
3086 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3089 sym_link *ltype = operandType (left);
3090 sym_link *rtype = operandType (right);
3092 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3094 werror (E_LVALUE_REQUIRED, "assignment");
3098 /* left is integral type and right is literal then
3099 check if the literal value is within bounds */
3100 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3102 checkConstantRange(ltype,
3103 OP_VALUE(right), "= operation", 0);
3106 /* if the left & right type don't exactly match */
3107 /* if pointer set then make sure the check is
3108 done with the type & not the pointer */
3109 /* then cast rights type to left */
3111 /* first check the type for pointer assignement */
3112 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3113 compareType (ltype, rtype) <= 0)
3115 if (compareType (ltype->next, rtype) < 0)
3116 right = geniCodeCast (ltype->next, right, TRUE);
3118 else if (compareType (ltype, rtype) < 0)
3119 right = geniCodeCast (ltype, right, TRUE);
3121 /* If left is a true symbol & ! volatile
3122 create an assignment to temporary for
3123 the right & then assign this temporary
3124 to the symbol. This is SSA (static single
3125 assignment). Isn't it simple and folks have
3126 published mountains of paper on it */
3127 if (IS_TRUE_SYMOP (left) &&
3128 !isOperandVolatile (left, FALSE) &&
3129 isOperandGlobal (left))
3133 if (IS_TRUE_SYMOP (right))
3134 sym = OP_SYMBOL (right);
3135 ic = newiCode ('=', NULL, right);
3136 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3137 SPIL_LOC (right) = sym;
3141 ic = newiCode ('=', NULL, right);
3142 IC_RESULT (ic) = left;
3145 /* if left isgptr flag is set then support
3146 routine will be required */
3150 ic->nosupdate = nosupdate;
3154 /*-----------------------------------------------------------------*/
3155 /* geniCodeDummyRead - generate code for dummy read */
3156 /*-----------------------------------------------------------------*/
3158 geniCodeDummyRead (operand * op)
3161 sym_link *type = operandType (op);
3163 if (!IS_VOLATILE(type))
3166 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3172 /*-----------------------------------------------------------------*/
3173 /* geniCodeSEParms - generate code for side effecting fcalls */
3174 /*-----------------------------------------------------------------*/
3176 geniCodeSEParms (ast * parms,int lvl)
3181 if (parms->type == EX_OP && parms->opval.op == PARAM)
3183 geniCodeSEParms (parms->left,lvl);
3184 geniCodeSEParms (parms->right,lvl);
3188 /* hack don't like this but too lazy to think of
3190 if (IS_ADDRESS_OF_OP (parms))
3191 parms->left->lvalue = 1;
3193 if (IS_CAST_OP (parms) &&
3194 IS_PTR (parms->ftype) &&
3195 IS_ADDRESS_OF_OP (parms->right))
3196 parms->right->left->lvalue = 1;
3198 parms->opval.oprnd =
3199 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3201 parms->type = EX_OPERAND;
3202 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3203 SPEC_ARGREG(parms->ftype);
3206 /*-----------------------------------------------------------------*/
3207 /* geniCodeParms - generates parameters */
3208 /*-----------------------------------------------------------------*/
3210 geniCodeParms (ast * parms, value *argVals, int *stack,
3211 sym_link * ftype, int lvl)
3219 if (argVals==NULL) {
3221 argVals = FUNC_ARGS (ftype);
3224 /* if this is a param node then do the left & right */
3225 if (parms->type == EX_OP && parms->opval.op == PARAM)
3227 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3228 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3232 /* get the parameter value */
3233 if (parms->type == EX_OPERAND)
3234 pval = parms->opval.oprnd;
3237 /* maybe this else should go away ?? */
3238 /* hack don't like this but too lazy to think of
3240 if (IS_ADDRESS_OF_OP (parms))
3241 parms->left->lvalue = 1;
3243 if (IS_CAST_OP (parms) &&
3244 IS_PTR (parms->ftype) &&
3245 IS_ADDRESS_OF_OP (parms->right))
3246 parms->right->left->lvalue = 1;
3248 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3251 /* if register parm then make it a send */
3252 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3253 IFFUNC_ISBUILTIN(ftype))
3255 ic = newiCode (SEND, pval, NULL);
3256 ic->argreg = SPEC_ARGREG(parms->etype);
3257 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3262 /* now decide whether to push or assign */
3263 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3267 operand *top = operandFromSymbol (argVals->sym);
3268 /* clear useDef and other bitVectors */
3269 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3270 geniCodeAssign (top, pval, 1, 0);
3274 sym_link *p = operandType (pval);
3276 ic = newiCode (IPUSH, pval, NULL);
3278 /* update the stack adjustment */
3279 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3284 argVals=argVals->next;
3288 /*-----------------------------------------------------------------*/
3289 /* geniCodeCall - generates temp code for calling */
3290 /*-----------------------------------------------------------------*/
3292 geniCodeCall (operand * left, ast * parms,int lvl)
3296 sym_link *type, *etype;
3300 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3301 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3302 werror (E_FUNCTION_EXPECTED);
3303 return operandFromValue(valueFromLit(0));
3306 /* take care of parameters with side-effecting
3307 function calls in them, this is required to take care
3308 of overlaying function parameters */
3309 geniCodeSEParms (parms,lvl);
3311 ftype = operandType (left);
3312 if (IS_CODEPTR (ftype))
3313 ftype = ftype->next;
3315 /* first the parameters */
3316 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3318 /* now call : if symbol then pcall */
3319 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3320 ic = newiCode (PCALL, left, NULL);
3322 ic = newiCode (CALL, left, NULL);
3325 type = copyLinkChain (ftype->next);
3326 etype = getSpec (type);
3327 SPEC_EXTR (etype) = 0;
3328 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3332 /* stack adjustment after call */
3333 ic->parmBytes = stack;
3338 /*-----------------------------------------------------------------*/
3339 /* geniCodeReceive - generate intermediate code for "receive" */
3340 /*-----------------------------------------------------------------*/
3342 geniCodeReceive (value * args)
3344 /* for all arguments that are passed in registers */
3348 if (IS_REGPARM (args->etype))
3350 operand *opr = operandFromValue (args);
3352 symbol *sym = OP_SYMBOL (opr);
3355 /* we will use it after all optimizations
3356 and before liveRange calculation */
3357 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3360 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3361 options.stackAuto == 0 &&
3362 (!(options.model == MODEL_FLAT24)) )
3367 opl = newiTempOperand (args->type, 0);
3369 sym->reqv->key = sym->key;
3370 OP_SYMBOL (sym->reqv)->key = sym->key;
3371 OP_SYMBOL (sym->reqv)->isreqv = 1;
3372 OP_SYMBOL (sym->reqv)->islocal = 0;
3373 SPIL_LOC (sym->reqv) = sym;
3377 ic = newiCode (RECEIVE, NULL, NULL);
3378 ic->argreg = SPEC_ARGREG(args->etype);
3380 currFunc->recvSize = getSize (sym->type);
3383 IC_RESULT (ic) = opr;
3391 /*-----------------------------------------------------------------*/
3392 /* geniCodeFunctionBody - create the function body */
3393 /*-----------------------------------------------------------------*/
3395 geniCodeFunctionBody (ast * tree,int lvl)
3402 /* reset the auto generation */
3408 func = ast2iCode (tree->left,lvl+1);
3409 fetype = getSpec (operandType (func));
3411 savelineno = lineno;
3412 lineno = OP_SYMBOL (func)->lineDef;
3413 /* create an entry label */
3414 geniCodeLabel (entryLabel);
3415 lineno = savelineno;
3417 /* create a proc icode */
3418 ic = newiCode (FUNCTION, func, NULL);
3419 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3424 /* for all parameters that are passed
3425 on registers add a "receive" */
3426 geniCodeReceive (tree->values.args);
3428 /* generate code for the body */
3429 ast2iCode (tree->right,lvl+1);
3431 /* create a label for return */
3432 geniCodeLabel (returnLabel);
3434 /* now generate the end proc */
3435 ic = newiCode (ENDFUNCTION, func, NULL);
3441 /*-----------------------------------------------------------------*/
3442 /* geniCodeReturn - gen icode for 'return' statement */
3443 /*-----------------------------------------------------------------*/
3445 geniCodeReturn (operand * op)
3449 /* if the operand is present force an rvalue */
3451 op = geniCodeRValue (op, FALSE);
3453 ic = newiCode (RETURN, op, NULL);
3457 /*-----------------------------------------------------------------*/
3458 /* geniCodeIfx - generates code for extended if statement */
3459 /*-----------------------------------------------------------------*/
3461 geniCodeIfx (ast * tree,int lvl)
3464 operand *condition = ast2iCode (tree->left,lvl+1);
3467 /* if condition is null then exit */
3471 condition = geniCodeRValue (condition, FALSE);
3473 cetype = getSpec (operandType (condition));
3474 /* if the condition is a literal */
3475 if (IS_LITERAL (cetype))
3477 if (floatFromVal (condition->operand.valOperand))
3479 if (tree->trueLabel)
3480 geniCodeGoto (tree->trueLabel);
3486 if (tree->falseLabel)
3487 geniCodeGoto (tree->falseLabel);
3494 if (tree->trueLabel)
3496 ic = newiCodeCondition (condition,
3501 if (tree->falseLabel)
3502 geniCodeGoto (tree->falseLabel);
3506 ic = newiCodeCondition (condition,
3513 ast2iCode (tree->right,lvl+1);
3516 /*-----------------------------------------------------------------*/
3517 /* geniCodeJumpTable - tries to create a jump table for switch */
3518 /*-----------------------------------------------------------------*/
3520 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3522 int min, max, cnt = 1;
3529 int needRangeCheck = !optimize.noJTabBoundary
3530 || tree->values.switchVals.swDefault;
3531 sym_link *cetype = getSpec (operandType (cond));
3532 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3533 int sizeofMatchJump, sizeofJumpTable;
3536 if (!tree || !caseVals)
3539 /* the criteria for creating a jump table is */
3540 /* all integer numbers between the maximum & minimum must */
3541 /* be present , the maximum value should not exceed 255 */
3542 /* If not all integer numbers are present the algorithm */
3543 /* inserts jumps to the default label for the missing numbers */
3544 /* and decides later whether it is worth it */
3545 min = (int) floatFromVal (vch = caseVals);
3552 max = (int) floatFromVal (vch);
3554 /* Exit if the range is too large to handle with a jump table. */
3555 if (1 + max - min > port->jumptableCost.maxCount)
3558 switch (getSize (operandType (cond)))
3560 case 1: sizeIndex = 0; break;
3561 case 2: sizeIndex = 1; break;
3562 case 4: sizeIndex = 2; break;
3566 /* Compute the size cost of the range check and subtraction. */
3568 sizeofZeroMinCost = 0;
3572 if (!(min==0 && IS_UNSIGNED (cetype)))
3573 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3574 if (!IS_UNSIGNED (cetype))
3575 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3576 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3579 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3581 /* If the size cost of handling a non-zero minimum exceeds the */
3582 /* cost of extending the range down to zero, then it might be */
3583 /* better to extend the range to zero. */
3584 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3585 >= (min * port->jumptableCost.sizeofElement))
3587 /* Only extend the jump table if it would still be manageable. */
3588 if (1 + max <= port->jumptableCost.maxCount)
3591 if (IS_UNSIGNED (cetype))
3594 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3598 /* Compute the total size cost of a jump table. */
3599 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3600 + port->jumptableCost.sizeofDispatch
3601 + sizeofMinCost + sizeofMaxCost;
3603 /* Compute the total size cost of a match & jump sequence */
3604 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3606 /* If the size cost of the jump table is uneconomical then exit */
3607 if (sizeofMatchJump < sizeofJumpTable)
3610 /* The jump table is preferable. */
3612 /* First, a label for the default or missing cases. */
3613 if (tree->values.switchVals.swDefault)
3615 SNPRINTF (buffer, sizeof(buffer),
3617 tree->values.switchVals.swNum);
3621 SNPRINTF (buffer, sizeof(buffer),
3623 tree->values.switchVals.swNum);
3625 falseLabel = newiTempLabel (buffer);
3627 /* Build the list of labels for the jump table. */
3629 t = (int) floatFromVal (vch);
3630 for (i=min; i<=max; i++)
3634 /* Explicit case: make a new label for it. */
3635 SNPRINTF (buffer, sizeof(buffer),
3637 tree->values.switchVals.swNum,
3639 addSet (&labels, newiTempLabel (buffer));
3642 t = (int) floatFromVal (vch);
3646 /* Implicit case: use the default label. */
3647 addSet (&labels, falseLabel);
3651 /* If cond is volatile, it might change after the boundary */
3652 /* conditions are tested to an out of bounds value, causing */
3653 /* a jump to a location outside of the jump table. To avoid */
3654 /* this possibility, use a non-volatile copy of it instead. */
3655 if (IS_OP_VOLATILE (cond))
3660 newcond = newiTempOperand (operandType (cond), TRUE);
3661 newcond->isvolatile = 0;
3662 ic = newiCode ('=', NULL, cond);
3663 IC_RESULT (ic) = newcond;
3668 /* first we rule out the boundary conditions */
3669 /* if only optimization says so */
3672 sym_link *cetype = getSpec (operandType (cond));
3673 /* no need to check the lower bound if
3674 the condition is unsigned & minimum value is zero */
3675 if (!(min == 0 && IS_UNSIGNED (cetype)))
3677 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3678 ic = newiCodeCondition (boundary, falseLabel, NULL);
3682 /* now for upper bounds */
3683 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3684 ic = newiCodeCondition (boundary, falseLabel, NULL);
3688 /* if the min is not zero then we no make it zero */
3691 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3692 if (!IS_LITERAL(getSpec(operandType(cond))))
3693 setOperandType (cond, UCHARTYPE);
3696 /* now create the jumptable */
3697 ic = newiCode (JUMPTABLE, NULL, NULL);
3698 IC_JTCOND (ic) = cond;
3699 IC_JTLABELS (ic) = labels;
3704 /*-----------------------------------------------------------------*/
3705 /* geniCodeSwitch - changes a switch to a if statement */
3706 /*-----------------------------------------------------------------*/
3708 geniCodeSwitch (ast * tree,int lvl)
3711 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3712 value *caseVals = tree->values.switchVals.swVals;
3713 symbol *trueLabel, *falseLabel;
3715 /* If the condition is a literal, then just jump to the */
3716 /* appropriate case label. */
3717 if (IS_LITERAL(getSpec(operandType(cond))))
3719 int switchVal, caseVal;
3721 switchVal = (int) floatFromVal (cond->operand.valOperand);
3724 caseVal = (int) floatFromVal (caseVals);
3725 if (caseVal == switchVal)
3727 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3728 tree->values.switchVals.swNum, caseVal);
3729 trueLabel = newiTempLabel (buffer);
3730 geniCodeGoto (trueLabel);
3733 caseVals = caseVals->next;
3735 goto defaultOrBreak;
3738 /* if we can make this a jump table */
3739 if (geniCodeJumpTable (cond, caseVals, tree))
3740 goto jumpTable; /* no need for the comparison */
3742 /* for the cases defined do */
3746 operand *compare = geniCodeLogic (cond,
3747 operandFromValue (caseVals),
3750 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3751 tree->values.switchVals.swNum,
3752 (int) floatFromVal (caseVals));
3753 trueLabel = newiTempLabel (buffer);
3755 ic = newiCodeCondition (compare, trueLabel, NULL);
3757 caseVals = caseVals->next;
3762 /* if default is present then goto break else break */
3763 if (tree->values.switchVals.swDefault)
3765 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3769 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3772 falseLabel = newiTempLabel (buffer);
3773 geniCodeGoto (falseLabel);
3776 ast2iCode (tree->right,lvl+1);
3779 /*-----------------------------------------------------------------*/
3780 /* geniCodeInline - intermediate code for inline assembler */
3781 /*-----------------------------------------------------------------*/
3783 geniCodeInline (ast * tree)
3787 ic = newiCode (INLINEASM, NULL, NULL);
3788 IC_INLINE (ic) = tree->values.inlineasm;
3792 /*-----------------------------------------------------------------*/
3793 /* geniCodeArrayInit - intermediate code for array initializer */
3794 /*-----------------------------------------------------------------*/
3796 geniCodeArrayInit (ast * tree, operand *array)
3800 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3801 ic = newiCode (ARRAYINIT, array, NULL);
3802 IC_ARRAYILIST (ic) = tree->values.constlist;
3804 operand *left=newOperand(), *right=newOperand();
3805 left->type=right->type=SYMBOL;
3806 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3807 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3808 ic = newiCode (ARRAYINIT, left, right);
3813 /*-----------------------------------------------------------------*/
3814 /* geniCodeCritical - intermediate code for a critical statement */
3815 /*-----------------------------------------------------------------*/
3817 geniCodeCritical (ast *tree, int lvl)
3823 if (!options.stackAuto)
3825 type = newLink(SPECIFIER);
3826 SPEC_VOLATILE(type) = 1;
3827 SPEC_NOUN(type) = V_BIT;
3828 SPEC_SCLS(type) = S_BIT;
3829 SPEC_BLEN(type) = 1;
3830 SPEC_BSTR(type) = 0;
3831 op = newiTempOperand(type, 1);
3834 /* If op is NULL, the original interrupt state will saved on */
3835 /* the stack. Otherwise, it will be saved in op. */
3837 /* Generate a save of the current interrupt state & disable */
3838 ic = newiCode (CRITICAL, NULL, NULL);
3839 IC_RESULT (ic) = op;
3842 /* Generate the critical code sequence */
3843 if (tree->left && tree->left->type == EX_VALUE)
3844 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3846 ast2iCode (tree->left,lvl+1);
3848 /* Generate a restore of the original interrupt state */
3849 ic = newiCode (ENDCRITICAL, NULL, op);
3853 /*-----------------------------------------------------------------*/
3854 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3855 /* particular case. Ie : assigning or dereferencing array or ptr */
3856 /*-----------------------------------------------------------------*/
3857 set * lvaluereqSet = NULL;
3858 typedef struct lvalItem
3865 /*-----------------------------------------------------------------*/
3866 /* addLvaluereq - add a flag for lvalreq for current ast level */
3867 /*-----------------------------------------------------------------*/
3868 void addLvaluereq(int lvl)
3870 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3873 addSetHead(&lvaluereqSet,lpItem);
3876 /*-----------------------------------------------------------------*/
3877 /* delLvaluereq - del a flag for lvalreq for current ast level */
3878 /*-----------------------------------------------------------------*/
3882 lpItem = getSet(&lvaluereqSet);
3883 if(lpItem) Safe_free(lpItem);
3885 /*-----------------------------------------------------------------*/
3886 /* clearLvaluereq - clear lvalreq flag */
3887 /*-----------------------------------------------------------------*/
3888 void clearLvaluereq()
3891 lpItem = peekSet(lvaluereqSet);
3892 if(lpItem) lpItem->req = 0;
3894 /*-----------------------------------------------------------------*/
3895 /* getLvaluereq - get the last lvalreq level */
3896 /*-----------------------------------------------------------------*/
3897 int getLvaluereqLvl()
3900 lpItem = peekSet(lvaluereqSet);
3901 if(lpItem) return lpItem->lvl;
3904 /*-----------------------------------------------------------------*/
3905 /* isLvaluereq - is lvalreq valid for this level ? */
3906 /*-----------------------------------------------------------------*/
3907 int isLvaluereq(int lvl)
3910 lpItem = peekSet(lvaluereqSet);
3911 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3915 /*-----------------------------------------------------------------*/
3916 /* ast2iCode - creates an icodeList from an ast */
3917 /*-----------------------------------------------------------------*/
3919 ast2iCode (ast * tree,int lvl)
3921 operand *left = NULL;
3922 operand *right = NULL;
3926 /* set the global variables for filename & line number */
3928 filename = tree->filename;
3930 lineno = tree->lineno;
3932 block = tree->block;
3934 scopeLevel = tree->level;
3936 seqPoint = tree->seqPoint;
3938 if (tree->type == EX_VALUE)
3939 return operandFromValue (tree->opval.val);
3941 if (tree->type == EX_LINK)
3942 return operandFromLink (tree->opval.lnk);
3944 /* if we find a nullop */
3945 if (tree->type == EX_OP &&
3946 (tree->opval.op == NULLOP ||
3947 tree->opval.op == BLOCK))
3949 if (tree->left && tree->left->type == EX_VALUE)
3950 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3952 ast2iCode (tree->left,lvl+1);
3953 if (tree->right && tree->right->type == EX_VALUE)
3954 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3956 ast2iCode (tree->right,lvl+1);
3960 /* special cases for not evaluating */
3961 if (tree->opval.op != ':' &&
3962 tree->opval.op != '?' &&
3963 tree->opval.op != CALL &&
3964 tree->opval.op != IFX &&
3965 tree->opval.op != AND_OP &&
3966 tree->opval.op != OR_OP &&
3967 tree->opval.op != LABEL &&
3968 tree->opval.op != GOTO &&
3969 tree->opval.op != SWITCH &&
3970 tree->opval.op != FUNCTION &&
3971 tree->opval.op != INLINEASM &&
3972 tree->opval.op != CRITICAL)
3975 if (IS_ASSIGN_OP (tree->opval.op) ||
3976 IS_DEREF_OP (tree) ||
3977 (tree->opval.op == '&' && !tree->right) ||
3978 tree->opval.op == PTR_OP)
3981 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3982 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3985 left = operandFromAst (tree->left,lvl);
3987 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3988 left = geniCodeRValue (left, TRUE);
3992 left = operandFromAst (tree->left,lvl);
3994 if (tree->opval.op == INC_OP ||
3995 tree->opval.op == DEC_OP)
3998 right = operandFromAst (tree->right,lvl);
4003 right = operandFromAst (tree->right,lvl);
4007 /* now depending on the type of operand */
4008 /* this will be a biggy */
4009 switch (tree->opval.op)
4012 case '[': /* array operation */
4014 //sym_link *ltype = operandType (left);
4015 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4016 left = geniCodeRValue (left, FALSE);
4017 right = geniCodeRValue (right, TRUE);
4020 return geniCodeArray (left, right,lvl);
4022 case '.': /* structure dereference */
4023 if (IS_PTR (operandType (left)))
4024 left = geniCodeRValue (left, TRUE);
4026 left = geniCodeRValue (left, FALSE);
4028 return geniCodeStruct (left, right, tree->lvalue);
4030 case PTR_OP: /* structure pointer dereference */
4033 pType = operandType (left);
4034 left = geniCodeRValue (left, TRUE);
4036 setOClass (pType, getSpec (operandType (left)));
4039 return geniCodeStruct (left, right, tree->lvalue);
4041 case INC_OP: /* increment operator */
4043 return geniCodePostInc (left);
4045 return geniCodePreInc (right, tree->lvalue);
4047 case DEC_OP: /* decrement operator */
4049 return geniCodePostDec (left);
4051 return geniCodePreDec (right, tree->lvalue);
4053 case '&': /* bitwise and or address of operator */
4055 { /* this is a bitwise operator */
4056 left = geniCodeRValue (left, FALSE);
4057 right = geniCodeRValue (right, FALSE);
4058 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4061 return geniCodeAddressOf (left);
4063 case '|': /* bitwise or & xor */
4065 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4066 geniCodeRValue (right, FALSE),
4071 return geniCodeDivision (geniCodeRValue (left, FALSE),
4072 geniCodeRValue (right, FALSE),
4073 getResultTypeFromType (tree->ftype));
4076 return geniCodeModulus (geniCodeRValue (left, FALSE),
4077 geniCodeRValue (right, FALSE),
4078 getResultTypeFromType (tree->ftype));
4081 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4082 geniCodeRValue (right, FALSE),
4083 getResultTypeFromType (tree->ftype));
4085 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4089 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4090 geniCodeRValue (right, FALSE),
4091 getResultTypeFromType (tree->ftype));
4093 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4097 return geniCodeAdd (geniCodeRValue (left, FALSE),
4098 geniCodeRValue (right, FALSE),
4099 getResultTypeFromType (tree->ftype),
4102 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4105 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4106 geniCodeRValue (right, FALSE),
4107 getResultTypeFromType (tree->ftype));
4110 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4111 geniCodeRValue (right, FALSE));
4113 #if 0 // this indeed needs a second thought
4117 // let's keep this simple: get the rvalue we need
4118 op=geniCodeRValue (right, FALSE);
4119 // now cast it to whatever we want
4120 op=geniCodeCast (operandType(left), op, FALSE);
4121 // if this is going to be used as an lvalue, make it so
4127 #else // bug #604575, is it a bug ????
4128 return geniCodeCast (operandType (left),
4129 geniCodeRValue (right, FALSE), FALSE);
4136 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4141 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4142 setOperandType (op, UCHARTYPE);
4147 return geniCodeLogicAndOr (tree, lvl);
4154 /* different compilers (even different gccs) evaluate
4155 the two calls in a different order. to get the same
4156 result on all machines we've to specify a clear sequence.
4157 return geniCodeLogic (geniCodeRValue (left, FALSE),
4158 geniCodeRValue (right, FALSE),
4162 operand *leftOp, *rightOp;
4164 leftOp = geniCodeRValue (left , FALSE);
4165 rightOp = geniCodeRValue (right, FALSE);
4167 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4170 return geniCodeConditional (tree,lvl);
4173 return operandFromLit (getSize (tree->right->ftype));
4177 sym_link *rtype = operandType (right);
4178 sym_link *ltype = operandType (left);
4179 if (IS_PTR (rtype) && IS_ITEMP (right)
4180 && right->isaddr && compareType (rtype->next, ltype) == 1)
4181 right = geniCodeRValue (right, TRUE);
4183 right = geniCodeRValue (right, FALSE);
4185 geniCodeAssign (left, right, 0, 1);
4190 geniCodeAssign (left,
4191 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4193 geniCodeRValue (right, FALSE),
4194 getResultTypeFromType (tree->ftype)),
4199 geniCodeAssign (left,
4200 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4202 geniCodeRValue (right, FALSE),
4203 getResultTypeFromType (tree->ftype)),
4207 geniCodeAssign (left,
4208 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4210 geniCodeRValue (right, FALSE),
4211 getResultTypeFromType (tree->ftype)),
4215 sym_link *rtype = operandType (right);
4216 sym_link *ltype = operandType (left);
4217 if (IS_PTR (rtype) && IS_ITEMP (right)
4218 && right->isaddr && compareType (rtype->next, ltype) == 1)
4219 right = geniCodeRValue (right, TRUE);
4221 right = geniCodeRValue (right, FALSE);
4224 return geniCodeAssign (left,
4225 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4228 getResultTypeFromType (tree->ftype),
4234 sym_link *rtype = operandType (right);
4235 sym_link *ltype = operandType (left);
4236 if (IS_PTR (rtype) && IS_ITEMP (right)
4237 && right->isaddr && compareType (rtype->next, ltype) == 1)
4239 right = geniCodeRValue (right, TRUE);
4243 right = geniCodeRValue (right, FALSE);
4246 geniCodeAssign (left,
4247 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4250 getResultTypeFromType (tree->ftype)),
4255 geniCodeAssign (left,
4256 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4258 geniCodeRValue (right, FALSE),
4259 getResultTypeFromType (tree->ftype)),
4263 geniCodeAssign (left,
4264 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4266 geniCodeRValue (right, FALSE)), 0, 1);
4269 geniCodeAssign (left,
4270 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4272 geniCodeRValue (right, FALSE),
4274 operandType (left)), 0, 1);
4277 geniCodeAssign (left,
4278 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4280 geniCodeRValue (right, FALSE),
4282 operandType (left)), 0, 1);
4285 geniCodeAssign (left,
4286 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4288 geniCodeRValue (right, FALSE),
4290 operandType (left)), 0, 1);
4292 return geniCodeRValue (right, FALSE);
4295 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4298 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4299 return ast2iCode (tree->right,lvl+1);
4302 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4303 return ast2iCode (tree->right,lvl+1);
4306 geniCodeFunctionBody (tree,lvl);
4310 geniCodeReturn (right);
4314 geniCodeIfx (tree,lvl);
4318 geniCodeSwitch (tree,lvl);
4322 geniCodeInline (tree);
4326 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4330 geniCodeCritical (tree, lvl);
4336 /*-----------------------------------------------------------------*/
4337 /* reverseICChain - gets from the list and creates a linkedlist */
4338 /*-----------------------------------------------------------------*/
4345 while ((loop = getSet (&iCodeChain)))
4357 /*-----------------------------------------------------------------*/
4358 /* iCodeFromAst - given an ast will convert it to iCode */
4359 /*-----------------------------------------------------------------*/
4361 iCodeFromAst (ast * tree)
4363 returnLabel = newiTempLabel ("_return");
4364 entryLabel = newiTempLabel ("_entry");
4366 return reverseiCChain ();
4369 static const char *opTypeToStr(OPTYPE op)
4373 case SYMBOL: return "symbol";
4374 case VALUE: return "value";
4375 case TYPE: return "type";
4377 return "undefined type";
4381 operand *validateOpType(operand *op,
4388 if (op && op->type == type)
4393 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4394 " expected %s, got %s\n",
4395 macro, args, file, line,
4396 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4398 return op; // never reached, makes compiler happy.