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 if(REGA && !getenv("PRINT_SHORT_OPERANDS")) {
238 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}" , */
239 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
241 OP_LIVEFROM (op), OP_LIVETO (op),
242 OP_SYMBOL (op)->stack,
243 op->isaddr, op->aggr2ptr, OP_SYMBOL (op)->isreqv,
244 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
245 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
249 printTypeChain (operandType (op), file);
250 if (SPIL_LOC (op) && IS_ITEMP (op))
251 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
256 /* if assigned to registers */
257 if (OP_SYMBOL (op)->nRegs)
259 if (OP_SYMBOL (op)->isspilt)
261 if (!OP_SYMBOL (op)->remat)
262 if (OP_SYMBOL (op)->usl.spillLoc)
263 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
264 OP_SYMBOL (op)->usl.spillLoc->rname :
265 OP_SYMBOL (op)->usl.spillLoc->name));
267 fprintf (file, "[err]");
269 fprintf (file, "[remat]");
275 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
276 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
280 //#else /* } else { */
282 /* (getenv("PRINT_SHORT_OPERANDS") != NULL) */
283 fprintf (file, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
285 if(getenv("PRINT_SHORT_OPERANDS")[0] < '1')
287 fprintf (file, "[lr%d:%d so:%d]",
288 OP_LIVEFROM (op), OP_LIVETO (op),
289 OP_SYMBOL (op)->stack);
292 if(getenv("PRINT_SHORT_OPERANDS")[0] < '2')
295 printTypeChain (operandType (op), file);
296 if (SPIL_LOC (op) && IS_ITEMP (op))
297 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
301 /* if assigned to registers */
302 if (OP_SYMBOL (op)->nRegs)
304 if (OP_SYMBOL (op)->isspilt)
306 if (!OP_SYMBOL (op)->remat)
307 if (OP_SYMBOL (op)->usl.spillLoc)
308 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
309 OP_SYMBOL (op)->usl.spillLoc->rname :
310 OP_SYMBOL (op)->usl.spillLoc->name));
312 fprintf (file, "[err]");
314 fprintf (file, "[remat]");
320 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
321 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
331 printTypeChain (op->operand.typeOperand, file);
337 fprintf (file, "\n");
342 /*-----------------------------------------------------------------*/
343 /* print functions */
344 /*-----------------------------------------------------------------*/
345 PRINTFUNC (picGetValueAtAddr)
348 printOperand (IC_RESULT (ic), of);
351 printOperand (IC_LEFT (ic), of);
357 PRINTFUNC (picSetValueAtAddr)
361 printOperand (IC_LEFT (ic), of);
362 fprintf (of, "] = ");
363 printOperand (IC_RIGHT (ic), of);
367 PRINTFUNC (picAddrOf)
370 printOperand (IC_RESULT (ic), of);
371 if (IS_ITEMP (IC_LEFT (ic)))
374 fprintf (of, " = &[");
375 printOperand (IC_LEFT (ic), of);
378 if (IS_ITEMP (IC_LEFT (ic)))
379 fprintf (of, " offsetAdd ");
382 printOperand (IC_RIGHT (ic), of);
384 if (IS_ITEMP (IC_LEFT (ic)))
390 PRINTFUNC (picJumpTable)
395 fprintf (of, "%s\t", s);
396 printOperand (IC_JTCOND (ic), of);
398 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
399 sym = setNextItem (IC_JTLABELS (ic)))
400 fprintf (of, "\t\t\t%s\n", sym->name);
403 PRINTFUNC (picGeneric)
406 printOperand (IC_RESULT (ic), of);
408 printOperand (IC_LEFT (ic), of);
409 fprintf (of, " %s ", s);
410 printOperand (IC_RIGHT (ic), of);
414 PRINTFUNC (picGenericOne)
419 printOperand (IC_RESULT (ic), of);
425 fprintf (of, "%s ", s);
426 printOperand (IC_LEFT (ic), of);
429 if (!IC_RESULT (ic) && !IC_LEFT (ic))
432 if (ic->op == SEND || ic->op == RECEIVE) {
433 fprintf(of,"{argreg = %d}",ic->argreg);
435 if (ic->op == IPUSH) {
436 fprintf(of,"{parmPush = %d}",ic->parmPush);
444 printOperand (IC_RESULT (ic), of);
446 printOperand (IC_LEFT (ic), of);
447 printOperand (IC_RIGHT (ic), of);
452 PRINTFUNC (picAssign)
456 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
459 printOperand (IC_RESULT (ic), of);
461 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
464 fprintf (of, " %s ", s);
465 printOperand (IC_RIGHT (ic), of);
472 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
478 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
485 printOperand (IC_COND (ic), of);
488 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
491 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
493 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
497 PRINTFUNC (picInline)
499 fprintf (of, "%s", IC_INLINE (ic));
502 PRINTFUNC (picReceive)
504 printOperand (IC_RESULT (ic), of);
505 fprintf (of, " = %s ", s);
506 printOperand (IC_LEFT (ic), of);
510 PRINTFUNC (picDummyRead)
513 fprintf (of, "%s ", s);
514 printOperand (IC_RIGHT (ic), of);
518 PRINTFUNC (picCritical)
522 printOperand (IC_RESULT (ic), of);
524 fprintf (of, "(stack)");
525 fprintf (of, " = %s ", s);
529 PRINTFUNC (picEndCritical)
532 fprintf (of, "%s = ", s);
534 printOperand (IC_RIGHT (ic), of);
536 fprintf (of, "(stack)");
540 /*-----------------------------------------------------------------*/
541 /* piCode - prints one iCode */
542 /*-----------------------------------------------------------------*/
544 piCode (void *item, FILE * of)
552 icTab = getTableEntry (ic->op);
553 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
554 ic->filename, ic->lineno,
555 ic->seq, ic->key, ic->depth, ic->supportRtn);
556 icTab->iCodePrint (of, ic, icTab->printName);
562 printiCChain(ic,stdout);
564 /*-----------------------------------------------------------------*/
565 /* printiCChain - prints intermediate code for humans */
566 /*-----------------------------------------------------------------*/
568 printiCChain (iCode * icChain, FILE * of)
575 for (loop = icChain; loop; loop = loop->next)
577 if ((icTab = getTableEntry (loop->op)))
579 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
580 loop->filename, loop->lineno,
581 loop->seq, loop->key, loop->depth, loop->supportRtn);
583 icTab->iCodePrint (of, loop, icTab->printName);
589 /*-----------------------------------------------------------------*/
590 /* newOperand - allocate, init & return a new iCode */
591 /*-----------------------------------------------------------------*/
597 op = Safe_alloc ( sizeof (operand));
603 /*-----------------------------------------------------------------*/
604 /* newiCode - create and return a new iCode entry initialised */
605 /*-----------------------------------------------------------------*/
607 newiCode (int op, operand * left, operand * right)
611 ic = Safe_alloc ( sizeof (iCode));
613 ic->seqPoint = seqPoint;
615 ic->filename = filename;
617 ic->level = scopeLevel;
619 ic->key = iCodeKey++;
621 IC_RIGHT (ic) = right;
626 /*-----------------------------------------------------------------*/
627 /* newiCode for conditional statements */
628 /*-----------------------------------------------------------------*/
630 newiCodeCondition (operand * condition,
636 if (IS_VOID(operandType(condition))) {
637 werror(E_VOID_VALUE_USED);
640 ic = newiCode (IFX, NULL, NULL);
641 IC_COND (ic) = condition;
642 IC_TRUE (ic) = trueLabel;
643 IC_FALSE (ic) = falseLabel;
647 /*-----------------------------------------------------------------*/
648 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
649 /*-----------------------------------------------------------------*/
651 newiCodeLabelGoto (int op, symbol * label)
655 ic = newiCode (op, NULL, NULL);
659 IC_RIGHT (ic) = NULL;
660 IC_RESULT (ic) = NULL;
664 /*-----------------------------------------------------------------*/
665 /* newiTemp - allocate & return a newItemp Variable */
666 /*-----------------------------------------------------------------*/
674 SNPRINTF (buffer, sizeof(buffer), "%s", s);
678 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
681 itmp = newSymbol (buffer, 1);
682 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
688 /*-----------------------------------------------------------------*/
689 /* newiTempLabel - creates a temp variable label */
690 /*-----------------------------------------------------------------*/
692 newiTempLabel (char *s)
696 /* check if this already exists */
697 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
702 itmplbl = newSymbol (s, 1);
706 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
707 itmplbl = newSymbol (buffer, 1);
712 itmplbl->key = labelKey++;
713 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
717 /*-----------------------------------------------------------------*/
718 /* newiTempPreheaderLabel - creates a new preheader label */
719 /*-----------------------------------------------------------------*/
721 newiTempPreheaderLabel ()
725 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
726 itmplbl = newSymbol (buffer, 1);
730 itmplbl->key = labelKey++;
731 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
736 /*-----------------------------------------------------------------*/
737 /* initiCode - initialises some iCode related stuff */
738 /*-----------------------------------------------------------------*/
745 /*-----------------------------------------------------------------*/
746 /* copyiCode - make a copy of the iCode given */
747 /*-----------------------------------------------------------------*/
749 copyiCode (iCode * ic)
751 iCode *nic = newiCode (ic->op, NULL, NULL);
753 nic->lineno = ic->lineno;
754 nic->filename = ic->filename;
755 nic->block = ic->block;
756 nic->level = ic->level;
757 nic->parmBytes = ic->parmBytes;
759 /* deal with the special cases first */
763 IC_COND (nic) = operandFromOperand (IC_COND (ic));
764 IC_TRUE (nic) = IC_TRUE (ic);
765 IC_FALSE (nic) = IC_FALSE (ic);
769 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
770 IC_JTLABELS (nic) = IC_JTLABELS (ic);
775 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
776 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
780 IC_INLINE (nic) = IC_INLINE (ic);
784 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
788 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
789 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
790 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
796 /*-----------------------------------------------------------------*/
797 /* getTableEntry - gets the table entry for the given operator */
798 /*-----------------------------------------------------------------*/
800 getTableEntry (int oper)
804 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
805 if (oper == codeTable[i].icode)
806 return &codeTable[i];
811 /*-----------------------------------------------------------------*/
812 /* newiTempOperand - new intermediate temp operand */
813 /*-----------------------------------------------------------------*/
815 newiTempOperand (sym_link * type, char throwType)
818 operand *op = newOperand ();
822 itmp = newiTemp (NULL);
824 etype = getSpec (type);
826 if (IS_LITERAL (etype))
829 /* copy the type information */
831 itmp->etype = getSpec (itmp->type = (throwType ? type :
832 copyLinkChain (type)));
833 if (IS_LITERAL (itmp->etype))
835 SPEC_SCLS (itmp->etype) = S_REGISTER;
836 SPEC_OCLS (itmp->etype) = reg;
839 op->operand.symOperand = itmp;
840 op->key = itmp->key = ++operandKey;
844 /*-----------------------------------------------------------------*/
845 /* operandType - returns the type chain for an operand */
846 /*-----------------------------------------------------------------*/
848 operandType (operand * op)
850 /* depending on type of operand */
855 return op->operand.valOperand->type;
858 return op->operand.symOperand->type;
861 return op->operand.typeOperand;
863 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
864 " operand type not known ");
865 assert (0); /* should never come here */
866 /* Just to keep the compiler happy */
867 return (sym_link *) 0;
871 /*-----------------------------------------------------------------*/
872 /* isParamterToCall - will return 1 if op is a parameter to args */
873 /*-----------------------------------------------------------------*/
875 isParameterToCall (value * args, operand * op)
879 wassert (IS_SYMOP(op));
884 isSymbolEqual (op->operand.symOperand, tval->sym))
891 /*-----------------------------------------------------------------*/
892 /* isOperandGlobal - return 1 if operand is a global variable */
893 /*-----------------------------------------------------------------*/
895 isOperandGlobal (operand * op)
904 (op->operand.symOperand->level == 0 ||
905 IS_STATIC (op->operand.symOperand->etype) ||
906 IS_EXTERN (op->operand.symOperand->etype))
913 /*-----------------------------------------------------------------*/
914 /* isOperandVolatile - return 1 if the operand is volatile */
915 /*-----------------------------------------------------------------*/
917 isOperandVolatile (operand * op, bool chkTemp)
922 if (IS_ITEMP (op) && !chkTemp)
925 opetype = getSpec (optype = operandType (op));
927 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
930 if (IS_VOLATILE (opetype))
935 /*-----------------------------------------------------------------*/
936 /* isOperandLiteral - returns 1 if an operand contains a literal */
937 /*-----------------------------------------------------------------*/
939 isOperandLiteral (operand * op)
946 opetype = getSpec (operandType (op));
948 if (IS_LITERAL (opetype))
954 /*-----------------------------------------------------------------*/
955 /* isOperandInFarSpace - will return true if operand is in farSpace */
956 /*-----------------------------------------------------------------*/
958 isOperandInFarSpace (operand * op)
968 if (!IS_TRUE_SYMOP (op))
971 etype = SPIL_LOC (op)->etype;
977 etype = getSpec (operandType (op));
979 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
982 /*------------------------------------------------------------------*/
983 /* isOperandInDirSpace - will return true if operand is in dirSpace */
984 /*------------------------------------------------------------------*/
986 isOperandInDirSpace (operand * op)
996 if (!IS_TRUE_SYMOP (op))
999 etype = SPIL_LOC (op)->etype;
1005 etype = getSpec (operandType (op));
1007 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1010 /*--------------------------------------------------------------------*/
1011 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
1012 /*--------------------------------------------------------------------*/
1014 isOperandInCodeSpace (operand * op)
1024 etype = getSpec (operandType (op));
1026 if (!IS_TRUE_SYMOP (op))
1029 etype = SPIL_LOC (op)->etype;
1035 etype = getSpec (operandType (op));
1037 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1040 /*-----------------------------------------------------------------*/
1041 /* isOperandOnStack - will return true if operand is on stack */
1042 /*-----------------------------------------------------------------*/
1044 isOperandOnStack (operand * op)
1054 etype = getSpec (operandType (op));
1055 if (IN_STACK (etype) ||
1056 OP_SYMBOL(op)->onStack ||
1057 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1063 /*-----------------------------------------------------------------*/
1064 /* isOclsExpensive - will return true if accesses to an output */
1065 /* storage class are expensive */
1066 /*-----------------------------------------------------------------*/
1068 isOclsExpensive (struct memmap *oclass)
1070 if (port->oclsExpense)
1071 return port->oclsExpense (oclass) > 0;
1073 /* In the absence of port specific guidance, assume only */
1074 /* farspace is expensive. */
1075 return IN_FARSPACE (oclass);
1078 /*-----------------------------------------------------------------*/
1079 /* isiCodeInFunctionCall - return TRUE if an iCode is between a */
1080 /* CALL/PCALL and the first IPUSH/SEND associated with the call */
1081 /*-----------------------------------------------------------------*/
1083 isiCodeInFunctionCall (iCode * ic)
1087 /* Find the next CALL/PCALL */
1090 if (lic->op == CALL || lic->op == PCALL)
1098 /* A function call was found. Scan backwards and see if an */
1099 /* IPUSH or SEND is encountered */
1102 if (lic != ic && (ic->op == CALL || ic->op == PCALL))
1104 if (ic->op == SEND || (ic->op == IPUSH && ic->parmPush))
1112 /*-----------------------------------------------------------------*/
1113 /* operandLitValue - literal value of an operand */
1114 /*-----------------------------------------------------------------*/
1116 operandLitValue (operand * op)
1118 assert (isOperandLiteral (op));
1120 return floatFromVal (op->operand.valOperand);
1123 /*-----------------------------------------------------------------*/
1124 /* getBuiltInParms - returns parameters to a builtin functions */
1125 /*-----------------------------------------------------------------*/
1126 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1131 /* builtin functions uses only SEND for parameters */
1132 while (ic->op != CALL) {
1133 assert(ic->op == SEND && ic->builtinSEND);
1134 ic->generated = 1; /* mark the icode as generated */
1135 parms[*pcount] = IC_LEFT(ic);
1141 /* make sure this is a builtin function call */
1142 assert(IS_SYMOP(IC_LEFT(ic)));
1143 ftype = operandType(IC_LEFT(ic));
1144 assert(IFFUNC_ISBUILTIN(ftype));
1148 /*-----------------------------------------------------------------*/
1149 /* operandOperation - performs operations on operands */
1150 /*-----------------------------------------------------------------*/
1152 operandOperation (operand * left, operand * right,
1153 int op, sym_link * type)
1155 sym_link *let , *ret=NULL;
1156 operand *retval = (operand *) 0;
1158 assert (isOperandLiteral (left));
1159 let = getSpec(operandType(left));
1161 assert (isOperandLiteral (right));
1162 ret = getSpec(operandType(right));
1168 retval = operandFromValue (valCastLiteral (type,
1169 operandLitValue (left) +
1170 operandLitValue (right)));
1173 retval = operandFromValue (valCastLiteral (type,
1174 operandLitValue (left) -
1175 operandLitValue (right)));
1179 retval = operandFromValue (valCastLiteral (type,
1180 operandLitValue (left) *
1181 operandLitValue (right)));
1182 This could be all we've to do, but with gcc we've to take care about
1183 overflows. Two examples:
1184 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1185 significant bits are lost (52 in fraction, 63 bits would be
1186 necessary to keep full precision).
1187 If the resulting double value is greater than ULONG_MAX (resp.
1188 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1191 /* if it is not a specifier then we can assume that */
1192 /* it will be an unsigned long */
1193 if (IS_INT (type) ||
1196 /* long is handled here, because it can overflow with double */
1197 if (IS_LONG (type) ||
1199 /* signed and unsigned mul are the same, as long as the precision
1200 of the result isn't bigger than the precision of the operands. */
1201 retval = operandFromValue (valCastLiteral (type,
1202 (TYPE_UDWORD) operandLitValue (left) *
1203 (TYPE_UDWORD) operandLitValue (right)));
1204 else if (IS_UNSIGNED (type)) /* unsigned int */
1206 /* unsigned int is handled here in order to detect overflow */
1207 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1208 (TYPE_UWORD) operandLitValue (right);
1210 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1211 if (ul != (TYPE_UWORD) ul)
1214 else /* signed int */
1216 /* signed int is handled here in order to detect overflow */
1217 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1218 (TYPE_WORD) operandLitValue (right);
1220 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1221 if (l != (TYPE_WORD) l)
1226 /* all others go here: */
1227 retval = operandFromValue (valCastLiteral (type,
1228 operandLitValue (left) *
1229 operandLitValue (right)));
1232 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1234 werror (E_DIVIDE_BY_ZERO);
1240 if (IS_UNSIGNED (type))
1242 SPEC_USIGN (let) = 1;
1243 SPEC_USIGN (ret) = 1;
1244 retval = operandFromValue (valCastLiteral (type,
1245 (TYPE_UDWORD) operandLitValue (left) /
1246 (TYPE_UDWORD) operandLitValue (right)));
1250 retval = operandFromValue (valCastLiteral (type,
1251 operandLitValue (left) /
1252 operandLitValue (right)));
1257 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1259 werror (E_DIVIDE_BY_ZERO);
1264 if (IS_UNSIGNED (type))
1265 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1266 (TYPE_UDWORD) operandLitValue (right));
1268 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1269 (TYPE_DWORD) operandLitValue (right));
1273 /* The number of left shifts is always unsigned. Signed doesn't make
1274 sense here. Shifting by a negative number is impossible. */
1275 retval = operandFromValue (valCastLiteral (type,
1276 ((TYPE_UDWORD) operandLitValue (left) <<
1277 (TYPE_UDWORD) operandLitValue (right))));
1280 /* The number of right shifts is always unsigned. Signed doesn't make
1281 sense here. Shifting by a negative number is impossible. */
1282 if (IS_UNSIGNED(let))
1283 /* unsigned: logic shift right */
1284 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1285 (TYPE_UDWORD) operandLitValue (right));
1287 /* signed: arithmetic shift right */
1288 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1289 (TYPE_UDWORD) operandLitValue (right));
1292 if (IS_FLOAT (let) ||
1295 retval = operandFromLit (operandLitValue (left) ==
1296 operandLitValue (right));
1300 /* this op doesn't care about signedness */
1303 l = (TYPE_UDWORD) operandLitValue (left);
1304 r = (TYPE_UDWORD) operandLitValue (right);
1305 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1306 neccessary to strip them to 16 bit.
1307 Literals are reduced to their cheapest type, therefore left and
1308 right might have different types. It's neccessary to find a
1309 common type: int (used for char too) or long */
1310 if (!IS_LONG (let) &&
1316 retval = operandFromLit (l == r);
1320 retval = operandFromLit (operandLitValue (left) <
1321 operandLitValue (right));
1324 retval = operandFromLit (operandLitValue (left) <=
1325 operandLitValue (right));
1328 retval = operandFromLit (operandLitValue (left) !=
1329 operandLitValue (right));
1332 retval = operandFromLit (operandLitValue (left) >
1333 operandLitValue (right));
1336 retval = operandFromLit (operandLitValue (left) >=
1337 operandLitValue (right));
1340 retval = operandFromValue (valCastLiteral (type,
1341 (TYPE_UDWORD)operandLitValue(left) &
1342 (TYPE_UDWORD)operandLitValue(right)));
1345 retval = operandFromValue (valCastLiteral (type,
1346 (TYPE_UDWORD)operandLitValue(left) |
1347 (TYPE_UDWORD)operandLitValue(right)));
1350 retval = operandFromValue (valCastLiteral (type,
1351 (TYPE_UDWORD)operandLitValue(left) ^
1352 (TYPE_UDWORD)operandLitValue(right)));
1355 retval = operandFromLit (operandLitValue (left) &&
1356 operandLitValue (right));
1359 retval = operandFromLit (operandLitValue (left) ||
1360 operandLitValue (right));
1364 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1366 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1372 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1374 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1380 retval = operandFromValue (valCastLiteral (type,
1381 -1 * operandLitValue (left)));
1385 retval = operandFromValue (valCastLiteral (type,
1387 operandLitValue (left))));
1391 retval = operandFromLit (!operandLitValue (left));
1395 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1396 " operandOperation invalid operator ");
1404 /*-----------------------------------------------------------------*/
1405 /* isOperandEqual - compares two operand & return 1 if they r = */
1406 /*-----------------------------------------------------------------*/
1408 isOperandEqual (operand * left, operand * right)
1410 /* if the pointers are equal then they are equal */
1414 /* if either of them null then false */
1415 if (!left || !right)
1418 if (left->type != right->type)
1421 if (IS_SYMOP (left) && IS_SYMOP (right))
1422 return left->key == right->key;
1424 /* if types are the same */
1428 return isSymbolEqual (left->operand.symOperand,
1429 right->operand.symOperand);
1431 return (floatFromVal (left->operand.valOperand) ==
1432 floatFromVal (right->operand.valOperand));
1434 if (compareType (left->operand.typeOperand,
1435 right->operand.typeOperand) == 1)
1442 /*-------------------------------------------------------------------*/
1443 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1444 /*-------------------------------------------------------------------*/
1446 isiCodeEqual (iCode * left, iCode * right)
1448 /* if the same pointer */
1452 /* if either of them null */
1453 if (!left || !right)
1456 /* if operand are the same */
1457 if (left->op == right->op)
1460 /* compare all the elements depending on type */
1461 if (left->op != IFX)
1463 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1465 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1471 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1473 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1475 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1484 /*-----------------------------------------------------------------*/
1485 /* newiTempFromOp - create a temp Operand with same attributes */
1486 /*-----------------------------------------------------------------*/
1488 newiTempFromOp (operand * op)
1498 nop = newiTempOperand (operandType (op), TRUE);
1499 nop->isaddr = op->isaddr;
1500 nop->isvolatile = op->isvolatile;
1501 nop->isGlobal = op->isGlobal;
1502 nop->isLiteral = op->isLiteral;
1503 nop->usesDefs = op->usesDefs;
1504 nop->isParm = op->isParm;
1508 /*-----------------------------------------------------------------*/
1509 /* operand from operand - creates an operand holder for the type */
1510 /*-----------------------------------------------------------------*/
1512 operandFromOperand (operand * op)
1518 nop = newOperand ();
1519 nop->type = op->type;
1520 nop->isaddr = op->isaddr;
1522 nop->isvolatile = op->isvolatile;
1523 nop->isGlobal = op->isGlobal;
1524 nop->isLiteral = op->isLiteral;
1525 nop->usesDefs = op->usesDefs;
1526 nop->isParm = op->isParm;
1531 nop->operand.symOperand = op->operand.symOperand;
1534 nop->operand.valOperand = op->operand.valOperand;
1537 nop->operand.typeOperand = op->operand.typeOperand;
1544 /*-----------------------------------------------------------------*/
1545 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1546 /*-----------------------------------------------------------------*/
1548 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1550 operand *nop = operandFromOperand (op);
1552 if (nop->type == SYMBOL)
1554 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1555 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1561 /*-----------------------------------------------------------------*/
1562 /* operandFromSymbol - creates an operand from a symbol */
1563 /*-----------------------------------------------------------------*/
1565 operandFromSymbol (symbol * sym)
1570 /* if the symbol's type is a literal */
1571 /* then it is an enumerator type */
1572 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1573 return operandFromValue (valFromType (sym->etype));
1576 sym->key = ++operandKey;
1578 /* if this an implicit variable, means struct/union */
1579 /* member so just return it */
1580 if (sym->implicit || IS_FUNC (sym->type))
1584 op->operand.symOperand = sym;
1586 op->isvolatile = isOperandVolatile (op, TRUE);
1587 op->isGlobal = isOperandGlobal (op);
1591 /* under the following conditions create a
1592 register equivalent for a local symbol */
1593 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1594 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1596 (!(options.model == MODEL_FLAT24)) ) &&
1597 options.stackAuto == 0)
1600 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1601 !IS_FUNC (sym->type) && /* not a function */
1602 !sym->_isparm && /* not a parameter */
1603 IS_AUTO (sym) && /* is a local auto variable */
1604 !sym->addrtaken && /* whose address has not been taken */
1605 !sym->reqv && /* does not already have a reg equivalence */
1606 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1607 !sym->islbl && /* not a label */
1608 ok && /* farspace check */
1609 !IS_BITVAR (sym->etype) /* not a bit variable */
1613 /* we will use it after all optimizations
1614 and before liveRange calculation */
1615 sym->reqv = newiTempOperand (sym->type, 0);
1616 sym->reqv->key = sym->key;
1617 OP_SYMBOL (sym->reqv)->prereqv = sym;
1618 OP_SYMBOL (sym->reqv)->key = sym->key;
1619 OP_SYMBOL (sym->reqv)->isreqv = 1;
1620 OP_SYMBOL (sym->reqv)->islocal = 1;
1621 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1622 SPIL_LOC (sym->reqv) = sym;
1625 if (!IS_AGGREGATE (sym->type))
1629 op->operand.symOperand = sym;
1632 op->isvolatile = isOperandVolatile (op, TRUE);
1633 op->isGlobal = isOperandGlobal (op);
1634 op->isPtr = IS_PTR (operandType (op));
1635 op->isParm = sym->_isparm;
1640 /* itemp = &[_symbol] */
1642 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1643 IC_LEFT (ic)->type = SYMBOL;
1644 IC_LEFT (ic)->operand.symOperand = sym;
1645 IC_LEFT (ic)->key = sym->key;
1646 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1647 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1648 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1651 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1652 if (IS_ARRAY (sym->type))
1654 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1655 IC_RESULT (ic)->isaddr = 0;
1658 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1662 return IC_RESULT (ic);
1665 /*-----------------------------------------------------------------*/
1666 /* operandFromValue - creates an operand from value */
1667 /*-----------------------------------------------------------------*/
1669 operandFromValue (value * val)
1673 /* if this is a symbol then do the symbol thing */
1675 return operandFromSymbol (val->sym);
1677 /* this is not a symbol */
1680 op->operand.valOperand = val;
1681 op->isLiteral = isOperandLiteral (op);
1685 /*-----------------------------------------------------------------*/
1686 /* operandFromLink - operand from typeChain */
1687 /*-----------------------------------------------------------------*/
1689 operandFromLink (sym_link * type)
1693 /* operand from sym_link */
1699 op->operand.typeOperand = copyLinkChain (type);
1703 /*-----------------------------------------------------------------*/
1704 /* operandFromLit - makes an operand from a literal value */
1705 /*-----------------------------------------------------------------*/
1707 operandFromLit (double i)
1709 return operandFromValue (valueFromLit (i));
1712 /*-----------------------------------------------------------------*/
1713 /* operandFromAst - creates an operand from an ast */
1714 /*-----------------------------------------------------------------*/
1716 operandFromAst (ast * tree,int lvl)
1722 /* depending on type do */
1726 return ast2iCode (tree,lvl+1);
1730 return operandFromValue (tree->opval.val);
1734 return operandFromLink (tree->opval.lnk);
1741 /* Just to keep the compiler happy */
1742 return (operand *) 0;
1745 /*-----------------------------------------------------------------*/
1746 /* setOperandType - sets the operand's type to the given type */
1747 /*-----------------------------------------------------------------*/
1749 setOperandType (operand * op, sym_link * type)
1751 /* depending on the type of operand */
1756 op->operand.valOperand->etype =
1757 getSpec (op->operand.valOperand->type =
1758 copyLinkChain (type));
1762 if (op->operand.symOperand->isitmp)
1763 op->operand.symOperand->etype =
1764 getSpec (op->operand.symOperand->type =
1765 copyLinkChain (type));
1767 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1768 "attempt to modify type of source");
1772 op->operand.typeOperand = copyLinkChain (type);
1778 /*-----------------------------------------------------------------*/
1779 /* Get size in byte of ptr need to access an array */
1780 /*-----------------------------------------------------------------*/
1782 getArraySizePtr (operand * op)
1784 sym_link *ltype = operandType(op);
1788 int size = getSize(ltype);
1789 return((IS_GENPTR(ltype) && GPTRSIZE > FPTRSIZE) ? (size-1) : size);
1794 sym_link *letype = getSpec(ltype);
1795 switch (PTR_TYPE (SPEC_OCLS (letype)))
1807 if (GPTRSIZE > FPTRSIZE)
1808 return (GPTRSIZE-1);
1819 /*-----------------------------------------------------------------*/
1820 /* perform "usual unary conversions" */
1821 /*-----------------------------------------------------------------*/
1824 usualUnaryConversions (operand * op)
1826 if (IS_INTEGRAL (operandType (op)))
1828 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1831 return geniCodeCast (INTTYPE, op, TRUE);
1838 /*-----------------------------------------------------------------*/
1839 /* perform "usual binary conversions" */
1840 /*-----------------------------------------------------------------*/
1843 usualBinaryConversions (operand ** op1, operand ** op2,
1844 RESULT_TYPE resultType, int op)
1847 sym_link *rtype = operandType (*op2);
1848 sym_link *ltype = operandType (*op1);
1850 ctype = computeType (ltype, rtype, resultType, op);
1857 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1859 /* one byte operations: keep signedness for code generator */
1867 *op1 = geniCodeCast (ctype, *op1, TRUE);
1868 *op2 = geniCodeCast (ctype, *op2, TRUE);
1873 /*-----------------------------------------------------------------*/
1874 /* geniCodeValueAtAddress - generate intermeditate code for value */
1876 /*-----------------------------------------------------------------*/
1878 geniCodeRValue (operand * op, bool force)
1881 sym_link *type = operandType (op);
1882 sym_link *etype = getSpec (type);
1884 /* if this is an array & already */
1885 /* an address then return this */
1886 if (IS_AGGREGATE (type) ||
1887 (IS_PTR (type) && !force && !op->isaddr))
1888 return operandFromOperand (op);
1890 /* if this is not an address then must be */
1891 /* rvalue already so return this one */
1895 /* if this is not a temp symbol then */
1896 if (!IS_ITEMP (op) &&
1898 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1900 op = operandFromOperand (op);
1905 if (IS_SPEC (type) &&
1906 IS_TRUE_SYMOP (op) &&
1907 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1908 (options.model == MODEL_FLAT24) ))
1910 op = operandFromOperand (op);
1915 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1916 if (IS_PTR (type) && op->isaddr && force)
1919 type = copyLinkChain (type);
1921 IC_RESULT (ic) = newiTempOperand (type, 1);
1922 IC_RESULT (ic)->isaddr = 0;
1924 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1928 return IC_RESULT (ic);
1931 /*-----------------------------------------------------------------*/
1932 /* geniCodeCast - changes the value from one type to another */
1933 /*-----------------------------------------------------------------*/
1935 geniCodeCast (sym_link * type, operand * op, bool implicit)
1939 sym_link *opetype = getSpec (optype = operandType (op));
1943 /* one of them has size zero then error */
1944 if (IS_VOID (optype))
1946 werror (E_CAST_ZERO);
1950 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1952 geniCodeArray2Ptr (op);
1956 /* if the operand is already the desired type then do nothing */
1957 if (compareType (type, optype) == 1)
1960 /* if this is a literal then just change the type & return */
1961 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1963 return operandFromValue (valCastLiteral (type,
1964 operandLitValue (op)));
1967 /* if casting to/from pointers, do some checking */
1968 if (IS_PTR(type)) { // to a pointer
1969 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1970 if (IS_INTEGRAL(optype)) {
1971 // maybe this is NULL, than it's ok.
1972 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1973 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1974 // no way to set the storage
1975 if (IS_LITERAL(optype)) {
1976 werror(E_LITERAL_GENERIC);
1979 werror(E_NONPTR2_GENPTR);
1982 } else if (implicit) {
1983 werror(W_INTEGRAL2PTR_NOCAST);
1988 // shouldn't do that with float, array or structure unless to void
1989 if (!IS_VOID(getSpec(type)) &&
1990 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1991 werror(E_INCOMPAT_TYPES);
1995 } else { // from a pointer to a pointer
1996 if (IS_GENPTR(type) && IS_VOID(type->next))
1997 { // cast to void* is always allowed
1999 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
2000 { // cast from void* is always allowed
2002 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2003 // if not a pointer to a function
2004 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2005 if (implicit) { // if not to generic, they have to match
2006 if (!IS_GENPTR(type) &&
2007 !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
2008 ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
2012 werror(E_INCOMPAT_PTYPES);
2019 } else { // to a non pointer
2020 if (IS_PTR(optype)) { // from a pointer
2021 if (implicit) { // sneaky
2022 if (IS_INTEGRAL(type)) {
2023 werror(W_PTR2INTEGRAL_NOCAST);
2025 } else { // shouldn't do that with float, array or structure
2026 werror(E_INCOMPAT_TYPES);
2033 printFromToType (optype, type);
2036 /* if they are the same size create an assignment */
2038 /* This seems very dangerous to me, since there are several */
2039 /* optimizations (for example, gcse) that don't notice the */
2040 /* cast hidden in this assignement and may simplify an */
2041 /* iCode to use the original (uncasted) operand. */
2042 /* Unfortunately, other things break when this cast is */
2043 /* made explicit. Need to fix this someday. */
2044 /* -- EEP, 2004/01/21 */
2045 if (getSize (type) == getSize (optype) &&
2046 !IS_BITFIELD (type) &&
2048 !IS_FLOAT (optype) &&
2049 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2050 (!IS_SPEC (type) && !IS_SPEC (optype))))
2052 ic = newiCode ('=', NULL, op);
2053 IC_RESULT (ic) = newiTempOperand (type, 0);
2054 SPIL_LOC (IC_RESULT (ic)) =
2055 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
2056 IC_RESULT (ic)->isaddr = 0;
2060 ic = newiCode (CAST, operandFromLink (type),
2061 geniCodeRValue (op, FALSE));
2063 IC_RESULT (ic) = newiTempOperand (type, 0);
2066 /* preserve the storage class & output class */
2067 /* of the original variable */
2068 restype = getSpec (operandType (IC_RESULT (ic)));
2069 if (!IS_LITERAL(opetype) &&
2072 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2073 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2076 return IC_RESULT (ic);
2079 /*-----------------------------------------------------------------*/
2080 /* geniCodeLabel - will create a Label */
2081 /*-----------------------------------------------------------------*/
2083 geniCodeLabel (symbol * label)
2087 ic = newiCodeLabelGoto (LABEL, label);
2091 /*-----------------------------------------------------------------*/
2092 /* geniCodeGoto - will create a Goto */
2093 /*-----------------------------------------------------------------*/
2095 geniCodeGoto (symbol * label)
2099 ic = newiCodeLabelGoto (GOTO, label);
2103 /*-----------------------------------------------------------------*/
2104 /* geniCodeMultiply - gen intermediate code for multiplication */
2105 /*-----------------------------------------------------------------*/
2107 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2114 /* if they are both literal then we know the result */
2115 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2116 return operandFromValue (valMult (left->operand.valOperand,
2117 right->operand.valOperand));
2119 if (IS_LITERAL(retype)) {
2120 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2123 resType = usualBinaryConversions (&left, &right, resultType, '*');
2125 rtype = operandType (right);
2126 retype = getSpec (rtype);
2127 ltype = operandType (left);
2128 letype = getSpec (ltype);
2131 /* if the right is a literal & power of 2 */
2132 /* then make it a left shift */
2133 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2134 efficient in most cases than 2 bytes result = 2 bytes << literal
2135 if port has 1 byte muldiv */
2136 if (p2 && !IS_FLOAT (letype)
2137 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2138 && (port->support.muldiv == 1))
2139 && strcmp (port->target, "pic16") != 0 /* don't shift for pic */
2140 && strcmp (port->target, "pic14") != 0)
2142 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2144 /* LEFT_OP need same size for left and result, */
2145 left = geniCodeCast (resType, left, TRUE);
2146 ltype = operandType (left);
2148 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2152 ic = newiCode ('*', left, right); /* normal multiplication */
2153 /* if the size left or right > 1 then support routine */
2154 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2158 IC_RESULT (ic) = newiTempOperand (resType, 1);
2161 return IC_RESULT (ic);
2164 /*-----------------------------------------------------------------*/
2165 /* geniCodeDivision - gen intermediate code for division */
2166 /*-----------------------------------------------------------------*/
2168 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2173 sym_link *rtype = operandType (right);
2174 sym_link *retype = getSpec (rtype);
2175 sym_link *ltype = operandType (left);
2176 sym_link *letype = getSpec (ltype);
2178 resType = usualBinaryConversions (&left, &right, resultType, '/');
2180 /* if the right is a literal & power of 2
2181 and left is unsigned then make it a
2183 if (IS_LITERAL (retype) &&
2184 !IS_FLOAT (letype) &&
2185 IS_UNSIGNED(letype) &&
2186 (p2 = powof2 ((TYPE_UDWORD)
2187 floatFromVal (right->operand.valOperand)))) {
2188 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2192 ic = newiCode ('/', left, right); /* normal division */
2193 /* if the size left or right > 1 then support routine */
2194 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2197 IC_RESULT (ic) = newiTempOperand (resType, 0);
2200 return IC_RESULT (ic);
2202 /*-----------------------------------------------------------------*/
2203 /* geniCodeModulus - gen intermediate code for modulus */
2204 /*-----------------------------------------------------------------*/
2206 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2212 /* if they are both literal then we know the result */
2213 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2214 return operandFromValue (valMod (left->operand.valOperand,
2215 right->operand.valOperand));
2217 resType = usualBinaryConversions (&left, &right, resultType, '%');
2219 /* now they are the same size */
2220 ic = newiCode ('%', left, right);
2222 /* if the size left or right > 1 then support routine */
2223 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2225 IC_RESULT (ic) = newiTempOperand (resType, 0);
2228 return IC_RESULT (ic);
2231 /*-----------------------------------------------------------------*/
2232 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2233 /*-----------------------------------------------------------------*/
2235 geniCodePtrPtrSubtract (operand * left, operand * right)
2241 /* if they are both literals then */
2242 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2244 result = operandFromValue (valMinus (left->operand.valOperand,
2245 right->operand.valOperand));
2249 ic = newiCode ('-', left, right);
2251 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2255 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2259 // should we really do this? is this ANSI?
2260 return geniCodeDivision (result,
2261 operandFromLit (getSize (ltype->next)),
2265 /*-----------------------------------------------------------------*/
2266 /* geniCodeSubtract - generates code for subtraction */
2267 /*-----------------------------------------------------------------*/
2269 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2276 /* if they both pointers then */
2277 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2278 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2279 return geniCodePtrPtrSubtract (left, right);
2281 /* if they are both literal then we know the result */
2282 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2283 && left->isLiteral && right->isLiteral)
2284 return operandFromValue (valMinus (left->operand.valOperand,
2285 right->operand.valOperand));
2287 /* if left is an array or pointer */
2288 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2290 isarray = left->isaddr;
2291 right = geniCodeMultiply (right,
2292 operandFromLit (getSize (ltype->next)),
2293 (getArraySizePtr(left) >= INTSIZE) ?
2296 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2299 { /* make them the same size */
2300 resType = usualBinaryConversions (&left, &right, resultType, '-');
2303 ic = newiCode ('-', left, right);
2305 IC_RESULT (ic) = newiTempOperand (resType, 1);
2306 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2308 /* if left or right is a float */
2309 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2313 return IC_RESULT (ic);
2316 /*-----------------------------------------------------------------*/
2317 /* geniCodeAdd - generates iCode for addition */
2318 /*-----------------------------------------------------------------*/
2320 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2329 /* if the right side is LITERAL zero */
2330 /* return the left side */
2331 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2334 /* if left is literal zero return right */
2335 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2338 /* if left is a pointer then size */
2339 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2341 isarray = left->isaddr;
2342 // there is no need to multiply with 1
2343 if (getSize (ltype->next) != 1)
2345 size = operandFromLit (getSize (ltype->next));
2346 SPEC_USIGN (getSpec (operandType (size))) = 1;
2347 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2348 right = geniCodeMultiply (right,
2350 (getArraySizePtr(left) >= INTSIZE) ?
2353 /* Even if right is a 'unsigned char',
2354 the result will be a 'signed int' due to the promotion rules.
2355 It doesn't make sense when accessing arrays, so let's fix it here: */
2357 SPEC_USIGN (getSpec (operandType (right))) = 1;
2359 resType = copyLinkChain (ltype);
2362 { // make them the same size
2363 resType = usualBinaryConversions (&left, &right, resultType, '+');
2366 /* if they are both literals then we know */
2367 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2368 && left->isLiteral && right->isLiteral)
2369 return operandFromValue (valPlus (valFromType (ltype),
2370 valFromType (rtype)));
2372 ic = newiCode ('+', left, right);
2374 IC_RESULT (ic) = newiTempOperand (resType, 1);
2375 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2377 /* if left or right is a float then support
2379 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2384 return IC_RESULT (ic);
2388 /*-----------------------------------------------------------------*/
2389 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2390 /*-----------------------------------------------------------------*/
2392 aggrToPtr (sym_link * type, bool force)
2397 if (IS_PTR (type) && !force)
2400 etype = getSpec (type);
2401 ptype = newLink (DECLARATOR);
2405 /* set the pointer depending on the storage class */
2406 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2410 /*------------------------------------------------------------------*/
2411 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2412 /*------------------------------------------------------------------*/
2414 aggrToPtrDclType (sym_link * type, bool force)
2416 if (IS_PTR (type) && !force)
2417 return DCL_TYPE (type);
2419 /* return the pointer depending on the storage class */
2420 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2423 /*-----------------------------------------------------------------*/
2424 /* geniCodeArray2Ptr - array to pointer */
2425 /*-----------------------------------------------------------------*/
2427 geniCodeArray2Ptr (operand * op)
2429 sym_link *optype = operandType (op);
2430 sym_link *opetype = getSpec (optype);
2432 /* set the pointer depending on the storage class */
2433 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2440 /*-----------------------------------------------------------------*/
2441 /* geniCodeArray - array access */
2442 /*-----------------------------------------------------------------*/
2444 geniCodeArray (operand * left, operand * right, int lvl)
2448 sym_link *ltype = operandType (left);
2453 if (IS_PTR (ltype->next) && left->isaddr)
2455 left = geniCodeRValue (left, FALSE);
2458 return geniCodeDerefPtr (geniCodeAdd (left,
2460 (getArraySizePtr(left) >= INTSIZE) ?
2466 size = operandFromLit (getSize (ltype->next));
2467 SPEC_USIGN (getSpec (operandType (size))) = 1;
2468 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2469 right = geniCodeMultiply (right,
2471 (getArraySizePtr(left) >= INTSIZE) ?
2474 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2475 It doesn't make sense when accessing arrays, so let's fix it here: */
2477 SPEC_USIGN (getSpec (operandType (right))) = 1;
2478 /* we can check for limits here */
2479 /* already done in SDCCast.c
2480 if (isOperandLiteral (right) &&
2483 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2485 werror (W_IDX_OUT_OF_BOUNDS,
2486 (int) operandLitValue (right) / getSize (ltype->next),
2491 ic = newiCode ('+', left, right);
2493 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2494 !IS_AGGREGATE (ltype->next) &&
2495 !IS_PTR (ltype->next))
2496 ? ltype : ltype->next), 0);
2498 if (!IS_AGGREGATE (ltype->next))
2500 IC_RESULT (ic)->isaddr = 1;
2501 IC_RESULT (ic)->aggr2ptr = 1;
2505 return IC_RESULT (ic);
2508 /*-----------------------------------------------------------------*/
2509 /* geniCodeStruct - generates intermediate code for structures */
2510 /*-----------------------------------------------------------------*/
2512 geniCodeStruct (operand * left, operand * right, bool islval)
2515 sym_link *type = operandType (left);
2516 sym_link *etype = getSpec (type);
2518 symbol *element = getStructElement (SPEC_STRUCT (etype),
2519 right->operand.symOperand);
2521 wassert(IS_SYMOP(right));
2523 /* add the offset */
2524 ic = newiCode ('+', left, operandFromLit (element->offset));
2526 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2528 /* preserve the storage & output class of the struct */
2529 /* as well as the volatile attribute */
2530 retype = getSpec (operandType (IC_RESULT (ic)));
2531 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2532 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2533 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2534 SPEC_CONST (retype) |= SPEC_CONST (etype);
2536 if (IS_PTR (element->type))
2537 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2539 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2542 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2545 /*-----------------------------------------------------------------*/
2546 /* geniCodePostInc - generate int code for Post increment */
2547 /*-----------------------------------------------------------------*/
2549 geniCodePostInc (operand * op)
2553 sym_link *optype = operandType (op);
2555 operand *rv = (IS_ITEMP (op) ?
2556 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2558 sym_link *rvtype = operandType (rv);
2561 /* if this is not an address we have trouble */
2564 werror (E_LVALUE_REQUIRED, "++");
2568 rOp = newiTempOperand (rvtype, 0);
2569 OP_SYMBOL(rOp)->noSpilLoc = 1;
2572 OP_SYMBOL(rv)->noSpilLoc = 1;
2574 geniCodeAssign (rOp, rv, 0, 0);
2576 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2578 werror(W_SIZEOF_VOID);
2579 if (IS_FLOAT (rvtype))
2580 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2582 ic = newiCode ('+', rv, operandFromLit (size));
2584 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2587 geniCodeAssign (op, result, 0, 0);
2593 /*-----------------------------------------------------------------*/
2594 /* geniCodePreInc - generate code for preIncrement */
2595 /*-----------------------------------------------------------------*/
2597 geniCodePreInc (operand * op, bool lvalue)
2600 sym_link *optype = operandType (op);
2601 operand *rop = (IS_ITEMP (op) ?
2602 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2604 sym_link *roptype = operandType (rop);
2610 werror (E_LVALUE_REQUIRED, "++");
2614 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2616 werror(W_SIZEOF_VOID);
2617 if (IS_FLOAT (roptype))
2618 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2620 ic = newiCode ('+', rop, operandFromLit (size));
2621 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2624 (void) geniCodeAssign (op, result, 0, 0);
2625 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2631 /*-----------------------------------------------------------------*/
2632 /* geniCodePostDec - generates code for Post decrement */
2633 /*-----------------------------------------------------------------*/
2635 geniCodePostDec (operand * op)
2639 sym_link *optype = operandType (op);
2641 operand *rv = (IS_ITEMP (op) ?
2642 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2644 sym_link *rvtype = operandType (rv);
2647 /* if this is not an address we have trouble */
2650 werror (E_LVALUE_REQUIRED, "--");
2654 rOp = newiTempOperand (rvtype, 0);
2655 OP_SYMBOL(rOp)->noSpilLoc = 1;
2658 OP_SYMBOL(rv)->noSpilLoc = 1;
2660 geniCodeAssign (rOp, rv, 0, 0);
2662 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2664 werror(W_SIZEOF_VOID);
2665 if (IS_FLOAT (rvtype))
2666 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2668 ic = newiCode ('-', rv, operandFromLit (size));
2670 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2673 geniCodeAssign (op, result, 0, 0);
2679 /*-----------------------------------------------------------------*/
2680 /* geniCodePreDec - generate code for pre decrement */
2681 /*-----------------------------------------------------------------*/
2683 geniCodePreDec (operand * op, bool lvalue)
2686 sym_link *optype = operandType (op);
2687 operand *rop = (IS_ITEMP (op) ?
2688 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2690 sym_link *roptype = operandType (rop);
2696 werror (E_LVALUE_REQUIRED, "--");
2700 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2702 werror(W_SIZEOF_VOID);
2703 if (IS_FLOAT (roptype))
2704 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2706 ic = newiCode ('-', rop, operandFromLit (size));
2707 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2710 (void) geniCodeAssign (op, result, 0, 0);
2711 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2718 /*-----------------------------------------------------------------*/
2719 /* geniCodeBitwise - gen int code for bitWise operators */
2720 /*-----------------------------------------------------------------*/
2722 geniCodeBitwise (operand * left, operand * right,
2723 int oper, sym_link * resType)
2727 left = geniCodeCast (resType, left, TRUE);
2728 right = geniCodeCast (resType, right, TRUE);
2730 ic = newiCode (oper, left, right);
2731 IC_RESULT (ic) = newiTempOperand (resType, 0);
2734 return IC_RESULT (ic);
2737 /*-----------------------------------------------------------------*/
2738 /* geniCodeAddressOf - gens icode for '&' address of operator */
2739 /*-----------------------------------------------------------------*/
2741 geniCodeAddressOf (operand * op)
2745 sym_link *optype = operandType (op);
2746 sym_link *opetype = getSpec (optype);
2748 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2750 op = operandFromOperand (op);
2755 /* lvalue check already done in decorateType */
2756 /* this must be a lvalue */
2757 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2758 /* werror (E_LVALUE_REQUIRED,"&"); */
2762 p = newLink (DECLARATOR);
2764 /* set the pointer depending on the storage class */
2765 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2767 p->next = copyLinkChain (optype);
2769 /* if already a temp */
2772 setOperandType (op, p);
2777 /* other wise make this of the type coming in */
2778 ic = newiCode (ADDRESS_OF, op, NULL);
2779 IC_RESULT (ic) = newiTempOperand (p, 1);
2780 IC_RESULT (ic)->isaddr = 0;
2782 return IC_RESULT (ic);
2784 /*-----------------------------------------------------------------*/
2785 /* setOClass - sets the output class depending on the pointer type */
2786 /*-----------------------------------------------------------------*/
2788 setOClass (sym_link * ptr, sym_link * spec)
2790 switch (DCL_TYPE (ptr))
2793 SPEC_OCLS (spec) = data;
2797 SPEC_OCLS (spec) = generic;
2801 SPEC_OCLS (spec) = xdata;
2805 SPEC_OCLS (spec) = code;
2809 SPEC_OCLS (spec) = idata;
2813 SPEC_OCLS (spec) = xstack;
2817 SPEC_OCLS (spec) = eeprom;
2826 /*-----------------------------------------------------------------*/
2827 /* geniCodeDerefPtr - dereference pointer with '*' */
2828 /*-----------------------------------------------------------------*/
2830 geniCodeDerefPtr (operand * op,int lvl)
2832 sym_link *rtype, *retype;
2833 sym_link *optype = operandType (op);
2835 // if this is an array then array access
2836 if (IS_ARRAY (optype)) {
2837 // don't worry, this will be optimized out later
2838 return geniCodeArray (op, operandFromLit (0), lvl);
2841 // just in case someone screws up
2842 wassert (IS_PTR (optype));
2844 if (IS_TRUE_SYMOP (op))
2847 op = geniCodeRValue (op, TRUE);
2850 /* now get rid of the pointer part */
2851 if (isLvaluereq(lvl) && IS_ITEMP (op))
2853 retype = getSpec (rtype = copyLinkChain (optype));
2857 retype = getSpec (rtype = copyLinkChain (optype->next));
2858 /* outputclass needs 2b updated */
2859 setOClass (optype, retype);
2862 op->isGptr = IS_GENPTR (optype);
2864 op->isaddr = (IS_PTR (rtype) ||
2865 IS_STRUCT (rtype) ||
2870 if (!isLvaluereq(lvl))
2871 op = geniCodeRValue (op, TRUE);
2873 setOperandType (op, rtype);
2878 /*-----------------------------------------------------------------*/
2879 /* geniCodeUnaryMinus - does a unary minus of the operand */
2880 /*-----------------------------------------------------------------*/
2882 geniCodeUnaryMinus (operand * op)
2885 sym_link *optype = operandType (op);
2887 if (IS_LITERAL (optype))
2888 return operandFromLit (-floatFromVal (op->operand.valOperand));
2890 ic = newiCode (UNARYMINUS, op, NULL);
2891 IC_RESULT (ic) = newiTempOperand (optype, 0);
2893 return IC_RESULT (ic);
2896 /*-----------------------------------------------------------------*/
2897 /* geniCodeLeftShift - gen i code for left shift */
2898 /*-----------------------------------------------------------------*/
2900 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2905 ic = newiCode (LEFT_OP, left, right);
2907 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2908 IC_RESULT (ic) = newiTempOperand (resType, 0);
2910 return IC_RESULT (ic);
2913 /*-----------------------------------------------------------------*/
2914 /* geniCodeRightShift - gen i code for right shift */
2915 /*-----------------------------------------------------------------*/
2917 geniCodeRightShift (operand * left, operand * right)
2921 ic = newiCode (RIGHT_OP, left, right);
2922 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2924 return IC_RESULT (ic);
2927 /*-----------------------------------------------------------------*/
2928 /* geniCodeLogic- logic code */
2929 /*-----------------------------------------------------------------*/
2931 geniCodeLogic (operand * left, operand * right, int op)
2935 sym_link *rtype = operandType (right);
2936 sym_link *ltype = operandType (left);
2938 /* left is integral type and right is literal then
2939 check if the literal value is within bounds */
2940 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2942 checkConstantRange(ltype,
2943 OP_VALUE(right), "compare operation", 1);
2946 /* if one operand is a pointer and the other is a literal generic void pointer,
2947 change the type of the literal generic void pointer to match the other pointer */
2948 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2949 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2951 /* find left's definition */
2952 ic = (iCode *) setFirstItem (iCodeChain);
2955 if (((ic->op == CAST) || (ic->op == '='))
2956 && isOperandEqual(left, IC_RESULT (ic)))
2959 ic = setNextItem (iCodeChain);
2961 /* if casting literal to generic pointer, then cast to rtype instead */
2962 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2964 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2965 ltype = operandType(left);
2968 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2969 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2971 /* find right's definition */
2972 ic = (iCode *) setFirstItem (iCodeChain);
2975 if (((ic->op == CAST) || (ic->op == '='))
2976 && isOperandEqual(right, IC_RESULT (ic)))
2979 ic = setNextItem (iCodeChain);
2981 /* if casting literal to generic pointer, then cast to rtype instead */
2982 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2984 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2985 rtype = operandType(right);
2989 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
2991 ic = newiCode (op, left, right);
2992 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2994 /* if comparing float
2995 and not a '==' || '!=' || '&&' || '||' (these
2997 if (IS_FLOAT(ctype) &&
3005 return IC_RESULT (ic);
3008 /*-----------------------------------------------------------------*/
3009 /* geniCodeLogicAndOr - && || operations */
3010 /*-----------------------------------------------------------------*/
3012 geniCodeLogicAndOr (ast *tree, int lvl)
3015 symbol *falseLabel = newiTempLabel (NULL);
3016 symbol *trueLabel = newiTempLabel (NULL);
3017 symbol *exitLabel = newiTempLabel (NULL);
3018 operand *op, *result, *condition;
3020 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3021 They can be reenabled by executing the following block. If you find
3022 a decent optimization you could start right here:
3027 operand *leftOp, *rightOp;
3029 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3030 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3032 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3036 /* generate two IFX for the '&&' or '||' op */
3038 /* evaluate left operand */
3039 condition = ast2iCode (tree->left, lvl + 1);
3040 op = geniCodeRValue (condition, FALSE);
3042 /* test left operand */
3043 if (tree->opval.op == AND_OP)
3044 ic = newiCodeCondition (op, NULL, falseLabel);
3046 ic = newiCodeCondition (op, trueLabel, NULL);
3049 /* evaluate right operand */
3050 condition = ast2iCode (tree->right, lvl + 1);
3051 op = geniCodeRValue (condition, FALSE);
3053 /* test right operand */
3054 ic = newiCodeCondition (op, trueLabel, NULL);
3057 /* store 0 or 1 in result */
3058 result = newiTempOperand (newCharLink(), 1);
3060 geniCodeLabel (falseLabel);
3061 geniCodeAssign (result, operandFromLit (0), 0, 0);
3062 /* generate an unconditional goto */
3063 geniCodeGoto (exitLabel);
3065 geniCodeLabel (trueLabel);
3066 geniCodeAssign (result, operandFromLit (1), 0, 0);
3068 geniCodeLabel (exitLabel);
3073 /*-----------------------------------------------------------------*/
3074 /* geniCodeUnary - for a a generic unary operation */
3075 /*-----------------------------------------------------------------*/
3077 geniCodeUnary (operand * op, int oper)
3079 iCode *ic = newiCode (oper, op, NULL);
3081 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3083 return IC_RESULT (ic);
3086 /*-----------------------------------------------------------------*/
3087 /* geniCodeConditional - geniCode for '?' ':' operation */
3088 /*-----------------------------------------------------------------*/
3090 geniCodeConditional (ast * tree,int lvl)
3093 symbol *falseLabel = newiTempLabel (NULL);
3094 symbol *exitLabel = newiTempLabel (NULL);
3095 operand *cond = ast2iCode (tree->left,lvl+1);
3096 operand *true, *false, *result;
3098 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3102 true = ast2iCode (tree->right->left,lvl+1);
3104 /* move the value to a new Operand */
3105 result = newiTempOperand (tree->right->ftype, 0);
3106 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3108 /* generate an unconditional goto */
3109 geniCodeGoto (exitLabel);
3111 /* now for the right side */
3112 geniCodeLabel (falseLabel);
3114 false = ast2iCode (tree->right->right,lvl+1);
3115 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3117 /* create the exit label */
3118 geniCodeLabel (exitLabel);
3123 /*-----------------------------------------------------------------*/
3124 /* geniCodeAssign - generate code for assignment */
3125 /*-----------------------------------------------------------------*/
3127 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3130 sym_link *ltype = operandType (left);
3131 sym_link *rtype = operandType (right);
3133 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3135 werror (E_LVALUE_REQUIRED, "assignment");
3139 /* left is integral type and right is literal then
3140 check if the literal value is within bounds */
3141 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3143 checkConstantRange(ltype,
3144 OP_VALUE(right), "= operation", 0);
3147 /* if the left & right type don't exactly match */
3148 /* if pointer set then make sure the check is
3149 done with the type & not the pointer */
3150 /* then cast rights type to left */
3152 /* first check the type for pointer assignement */
3153 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3154 compareType (ltype, rtype) <= 0)
3156 if (compareType (ltype->next, rtype) < 0)
3157 right = geniCodeCast (ltype->next, right, TRUE);
3159 else if (compareType (ltype, rtype) < 0)
3160 right = geniCodeCast (ltype, right, TRUE);
3162 /* If left is a true symbol & ! volatile
3163 create an assignment to temporary for
3164 the right & then assign this temporary
3165 to the symbol. This is SSA (static single
3166 assignment). Isn't it simple and folks have
3167 published mountains of paper on it */
3168 if (IS_TRUE_SYMOP (left) &&
3169 !isOperandVolatile (left, FALSE) &&
3170 isOperandGlobal (left))
3174 if (IS_TRUE_SYMOP (right))
3175 sym = OP_SYMBOL (right);
3176 ic = newiCode ('=', NULL, right);
3177 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3178 SPIL_LOC (right) = sym;
3182 ic = newiCode ('=', NULL, right);
3183 IC_RESULT (ic) = left;
3186 /* if left isgptr flag is set then support
3187 routine will be required */
3191 ic->nosupdate = nosupdate;
3195 /*-----------------------------------------------------------------*/
3196 /* geniCodeDummyRead - generate code for dummy read */
3197 /*-----------------------------------------------------------------*/
3199 geniCodeDummyRead (operand * op)
3202 sym_link *type = operandType (op);
3204 if (!IS_VOLATILE(type))
3207 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3213 /*-----------------------------------------------------------------*/
3214 /* geniCodeSEParms - generate code for side effecting fcalls */
3215 /*-----------------------------------------------------------------*/
3217 geniCodeSEParms (ast * parms,int lvl)
3222 if (parms->type == EX_OP && parms->opval.op == PARAM)
3224 geniCodeSEParms (parms->left,lvl);
3225 geniCodeSEParms (parms->right,lvl);
3229 /* hack don't like this but too lazy to think of
3231 if (IS_ADDRESS_OF_OP (parms))
3232 parms->left->lvalue = 1;
3234 if (IS_CAST_OP (parms) &&
3235 IS_PTR (parms->ftype) &&
3236 IS_ADDRESS_OF_OP (parms->right))
3237 parms->right->left->lvalue = 1;
3239 parms->opval.oprnd =
3240 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3242 parms->type = EX_OPERAND;
3243 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3244 SPEC_ARGREG(parms->ftype);
3247 /*-----------------------------------------------------------------*/
3248 /* geniCodeParms - generates parameters */
3249 /*-----------------------------------------------------------------*/
3251 geniCodeParms (ast * parms, value *argVals, int *stack,
3252 sym_link * ftype, int lvl)
3260 if (argVals==NULL) {
3262 argVals = FUNC_ARGS (ftype);
3265 /* if this is a param node then do the left & right */
3266 if (parms->type == EX_OP && parms->opval.op == PARAM)
3268 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3269 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3273 /* get the parameter value */
3274 if (parms->type == EX_OPERAND)
3275 pval = parms->opval.oprnd;
3278 /* maybe this else should go away ?? */
3279 /* hack don't like this but too lazy to think of
3281 if (IS_ADDRESS_OF_OP (parms))
3282 parms->left->lvalue = 1;
3284 if (IS_CAST_OP (parms) &&
3285 IS_PTR (parms->ftype) &&
3286 IS_ADDRESS_OF_OP (parms->right))
3287 parms->right->left->lvalue = 1;
3289 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3292 /* if register parm then make it a send */
3293 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3294 IFFUNC_ISBUILTIN(ftype))
3296 ic = newiCode (SEND, pval, NULL);
3297 ic->argreg = SPEC_ARGREG(parms->etype);
3298 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3303 /* now decide whether to push or assign */
3304 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3308 operand *top = operandFromSymbol (argVals->sym);
3309 /* clear useDef and other bitVectors */
3310 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3311 geniCodeAssign (top, pval, 1, 0);
3315 sym_link *p = operandType (pval);
3317 ic = newiCode (IPUSH, pval, NULL);
3319 /* update the stack adjustment */
3320 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3325 argVals=argVals->next;
3329 /*-----------------------------------------------------------------*/
3330 /* geniCodeCall - generates temp code for calling */
3331 /*-----------------------------------------------------------------*/
3333 geniCodeCall (operand * left, ast * parms,int lvl)
3337 sym_link *type, *etype;
3341 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3342 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3343 werror (E_FUNCTION_EXPECTED);
3344 return operandFromValue(valueFromLit(0));
3347 /* take care of parameters with side-effecting
3348 function calls in them, this is required to take care
3349 of overlaying function parameters */
3350 geniCodeSEParms (parms,lvl);
3352 ftype = operandType (left);
3353 if (IS_CODEPTR (ftype))
3354 ftype = ftype->next;
3356 /* first the parameters */
3357 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3359 /* now call : if symbol then pcall */
3360 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3361 ic = newiCode (PCALL, left, NULL);
3363 ic = newiCode (CALL, left, NULL);
3366 type = copyLinkChain (ftype->next);
3367 etype = getSpec (type);
3368 SPEC_EXTR (etype) = 0;
3369 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3373 /* stack adjustment after call */
3374 ic->parmBytes = stack;
3379 /*-----------------------------------------------------------------*/
3380 /* geniCodeReceive - generate intermediate code for "receive" */
3381 /*-----------------------------------------------------------------*/
3383 geniCodeReceive (value * args)
3385 unsigned char paramByteCounter = 0;
3387 /* for all arguments that are passed in registers */
3391 if (IS_REGPARM (args->etype))
3393 operand *opr = operandFromValue (args);
3395 symbol *sym = OP_SYMBOL (opr);
3398 /* we will use it after all optimizations
3399 and before liveRange calculation */
3400 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3403 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3404 options.stackAuto == 0 &&
3405 (!(options.model == MODEL_FLAT24)) )
3410 opl = newiTempOperand (args->type, 0);
3412 sym->reqv->key = sym->key;
3413 OP_SYMBOL (sym->reqv)->key = sym->key;
3414 OP_SYMBOL (sym->reqv)->isreqv = 1;
3415 OP_SYMBOL (sym->reqv)->islocal = 0;
3416 SPIL_LOC (sym->reqv) = sym;
3420 ic = newiCode (RECEIVE, NULL, NULL);
3421 ic->argreg = SPEC_ARGREG(args->etype);
3423 currFunc->recvSize = getSize (sym->type);
3426 IC_RESULT (ic) = opr;
3428 /* misuse of parmBytes (normally used for functions)
3429 * to save estimated stack position of this argument.
3430 * Normally this should be zero for RECEIVE iCodes.
3431 * No idea if this causes side effects on other ports. - dw
3433 ic->parmBytes = paramByteCounter;
3435 /* what stack position do we have? */
3436 paramByteCounter += getSize (sym->type);
3445 /*-----------------------------------------------------------------*/
3446 /* geniCodeFunctionBody - create the function body */
3447 /*-----------------------------------------------------------------*/
3449 geniCodeFunctionBody (ast * tree,int lvl)
3456 /* reset the auto generation */
3462 func = ast2iCode (tree->left,lvl+1);
3463 fetype = getSpec (operandType (func));
3465 savelineno = lineno;
3466 lineno = OP_SYMBOL (func)->lineDef;
3467 /* create an entry label */
3468 geniCodeLabel (entryLabel);
3469 lineno = savelineno;
3471 /* create a proc icode */
3472 ic = newiCode (FUNCTION, func, NULL);
3473 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3478 /* for all parameters that are passed
3479 on registers add a "receive" */
3480 geniCodeReceive (tree->values.args);
3482 /* generate code for the body */
3483 ast2iCode (tree->right,lvl+1);
3485 /* create a label for return */
3486 geniCodeLabel (returnLabel);
3488 /* now generate the end proc */
3489 ic = newiCode (ENDFUNCTION, func, NULL);
3495 /*-----------------------------------------------------------------*/
3496 /* geniCodeReturn - gen icode for 'return' statement */
3497 /*-----------------------------------------------------------------*/
3499 geniCodeReturn (operand * op)
3503 /* if the operand is present force an rvalue */
3505 op = geniCodeRValue (op, FALSE);
3507 ic = newiCode (RETURN, op, NULL);
3511 /*-----------------------------------------------------------------*/
3512 /* geniCodeIfx - generates code for extended if statement */
3513 /*-----------------------------------------------------------------*/
3515 geniCodeIfx (ast * tree,int lvl)
3518 operand *condition = ast2iCode (tree->left,lvl+1);
3521 /* if condition is null then exit */
3525 condition = geniCodeRValue (condition, FALSE);
3527 cetype = getSpec (operandType (condition));
3528 /* if the condition is a literal */
3529 if (IS_LITERAL (cetype))
3531 if (floatFromVal (condition->operand.valOperand))
3533 if (tree->trueLabel)
3534 geniCodeGoto (tree->trueLabel);
3540 if (tree->falseLabel)
3541 geniCodeGoto (tree->falseLabel);
3548 if (tree->trueLabel)
3550 ic = newiCodeCondition (condition,
3555 if (tree->falseLabel)
3556 geniCodeGoto (tree->falseLabel);
3560 ic = newiCodeCondition (condition,
3567 ast2iCode (tree->right,lvl+1);
3570 /*-----------------------------------------------------------------*/
3571 /* geniCodeJumpTable - tries to create a jump table for switch */
3572 /*-----------------------------------------------------------------*/
3574 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3576 int min, max, cnt = 1;
3583 int needRangeCheck = !optimize.noJTabBoundary
3584 || tree->values.switchVals.swDefault;
3585 sym_link *cetype = getSpec (operandType (cond));
3586 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3587 int sizeofMatchJump, sizeofJumpTable;
3590 if (!tree || !caseVals)
3593 /* the criteria for creating a jump table is */
3594 /* all integer numbers between the maximum & minimum must */
3595 /* be present , the maximum value should not exceed 255 */
3596 /* If not all integer numbers are present the algorithm */
3597 /* inserts jumps to the default label for the missing numbers */
3598 /* and decides later whether it is worth it */
3599 min = (int) floatFromVal (vch = caseVals);
3606 max = (int) floatFromVal (vch);
3608 /* Exit if the range is too large to handle with a jump table. */
3609 if (1 + max - min > port->jumptableCost.maxCount)
3612 switch (getSize (operandType (cond)))
3614 case 1: sizeIndex = 0; break;
3615 case 2: sizeIndex = 1; break;
3616 case 4: sizeIndex = 2; break;
3620 /* Compute the size cost of the range check and subtraction. */
3622 sizeofZeroMinCost = 0;
3626 if (!(min==0 && IS_UNSIGNED (cetype)))
3627 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3628 if (!IS_UNSIGNED (cetype))
3629 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3630 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3633 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3635 /* If the size cost of handling a non-zero minimum exceeds the */
3636 /* cost of extending the range down to zero, then it might be */
3637 /* better to extend the range to zero. */
3638 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3639 >= (min * port->jumptableCost.sizeofElement))
3641 /* Only extend the jump table if it would still be manageable. */
3642 if (1 + max <= port->jumptableCost.maxCount)
3645 if (IS_UNSIGNED (cetype))
3648 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3652 /* Compute the total size cost of a jump table. */
3653 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3654 + port->jumptableCost.sizeofDispatch
3655 + sizeofMinCost + sizeofMaxCost;
3657 /* Compute the total size cost of a match & jump sequence */
3658 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3660 /* If the size cost of the jump table is uneconomical then exit */
3661 if (sizeofMatchJump < sizeofJumpTable)
3664 /* The jump table is preferable. */
3666 /* First, a label for the default or missing cases. */
3667 if (tree->values.switchVals.swDefault)
3669 SNPRINTF (buffer, sizeof(buffer),
3671 tree->values.switchVals.swNum);
3675 SNPRINTF (buffer, sizeof(buffer),
3677 tree->values.switchVals.swNum);
3679 falseLabel = newiTempLabel (buffer);
3681 /* Build the list of labels for the jump table. */
3683 t = (int) floatFromVal (vch);
3684 for (i=min; i<=max; i++)
3688 /* Explicit case: make a new label for it. */
3689 SNPRINTF (buffer, sizeof(buffer),
3691 tree->values.switchVals.swNum,
3693 addSet (&labels, newiTempLabel (buffer));
3696 t = (int) floatFromVal (vch);
3700 /* Implicit case: use the default label. */
3701 addSet (&labels, falseLabel);
3705 /* first we rule out the boundary conditions */
3706 /* if only optimization says so */
3709 sym_link *cetype = getSpec (operandType (cond));
3710 /* no need to check the lower bound if
3711 the condition is unsigned & minimum value is zero */
3712 if (!(min == 0 && IS_UNSIGNED (cetype)))
3714 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3715 ic = newiCodeCondition (boundary, falseLabel, NULL);
3719 /* now for upper bounds */
3720 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3721 ic = newiCodeCondition (boundary, falseLabel, NULL);
3725 /* if the min is not zero then we no make it zero */
3728 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3729 if (!IS_LITERAL(getSpec(operandType(cond))))
3730 setOperandType (cond, UCHARTYPE);
3733 /* now create the jumptable */
3734 ic = newiCode (JUMPTABLE, NULL, NULL);
3735 IC_JTCOND (ic) = cond;
3736 IC_JTLABELS (ic) = labels;
3741 /*-----------------------------------------------------------------*/
3742 /* geniCodeSwitch - changes a switch to a if statement */
3743 /*-----------------------------------------------------------------*/
3745 geniCodeSwitch (ast * tree,int lvl)
3748 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3749 value *caseVals = tree->values.switchVals.swVals;
3750 symbol *trueLabel, *falseLabel;
3752 /* If the condition is a literal, then just jump to the */
3753 /* appropriate case label. */
3754 if (IS_LITERAL(getSpec(operandType(cond))))
3756 int switchVal, caseVal;
3758 switchVal = (int) floatFromVal (cond->operand.valOperand);
3761 caseVal = (int) floatFromVal (caseVals);
3762 if (caseVal == switchVal)
3764 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3765 tree->values.switchVals.swNum, caseVal);
3766 trueLabel = newiTempLabel (buffer);
3767 geniCodeGoto (trueLabel);
3770 caseVals = caseVals->next;
3772 goto defaultOrBreak;
3775 /* If cond is volatile, it might change while we are trying to */
3776 /* find the matching case. To avoid this possibility, make a */
3777 /* non-volatile copy to use instead. */
3778 if (IS_OP_VOLATILE (cond))
3783 newcond = newiTempOperand (operandType (cond), TRUE);
3784 newcond->isvolatile = 0;
3785 ic = newiCode ('=', NULL, cond);
3786 IC_RESULT (ic) = newcond;
3791 /* if we can make this a jump table */
3792 if (geniCodeJumpTable (cond, caseVals, tree))
3793 goto jumpTable; /* no need for the comparison */
3795 /* for the cases defined do */
3799 operand *compare = geniCodeLogic (cond,
3800 operandFromValue (caseVals),
3803 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3804 tree->values.switchVals.swNum,
3805 (int) floatFromVal (caseVals));
3806 trueLabel = newiTempLabel (buffer);
3808 ic = newiCodeCondition (compare, trueLabel, NULL);
3810 caseVals = caseVals->next;
3815 /* if default is present then goto break else break */
3816 if (tree->values.switchVals.swDefault)
3818 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3822 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3825 falseLabel = newiTempLabel (buffer);
3826 geniCodeGoto (falseLabel);
3829 ast2iCode (tree->right,lvl+1);
3832 /*-----------------------------------------------------------------*/
3833 /* geniCodeInline - intermediate code for inline assembler */
3834 /*-----------------------------------------------------------------*/
3836 geniCodeInline (ast * tree)
3840 ic = newiCode (INLINEASM, NULL, NULL);
3841 IC_INLINE (ic) = tree->values.inlineasm;
3845 /*-----------------------------------------------------------------*/
3846 /* geniCodeArrayInit - intermediate code for array initializer */
3847 /*-----------------------------------------------------------------*/
3849 geniCodeArrayInit (ast * tree, operand *array)
3853 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3854 ic = newiCode (ARRAYINIT, array, NULL);
3855 IC_ARRAYILIST (ic) = tree->values.constlist;
3857 operand *left=newOperand(), *right=newOperand();
3858 left->type=right->type=SYMBOL;
3859 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3860 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3861 ic = newiCode (ARRAYINIT, left, right);
3866 /*-----------------------------------------------------------------*/
3867 /* geniCodeCritical - intermediate code for a critical statement */
3868 /*-----------------------------------------------------------------*/
3870 geniCodeCritical (ast *tree, int lvl)
3876 if (!options.stackAuto)
3878 type = newLink(SPECIFIER);
3879 SPEC_VOLATILE(type) = 1;
3880 SPEC_NOUN(type) = V_BIT;
3881 SPEC_SCLS(type) = S_BIT;
3882 SPEC_BLEN(type) = 1;
3883 SPEC_BSTR(type) = 0;
3884 op = newiTempOperand(type, 1);
3887 /* If op is NULL, the original interrupt state will saved on */
3888 /* the stack. Otherwise, it will be saved in op. */
3890 /* Generate a save of the current interrupt state & disable */
3891 ic = newiCode (CRITICAL, NULL, NULL);
3892 IC_RESULT (ic) = op;
3895 /* Generate the critical code sequence */
3896 if (tree->left && tree->left->type == EX_VALUE)
3897 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3899 ast2iCode (tree->left,lvl+1);
3901 /* Generate a restore of the original interrupt state */
3902 ic = newiCode (ENDCRITICAL, NULL, op);
3906 /*-----------------------------------------------------------------*/
3907 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3908 /* particular case. Ie : assigning or dereferencing array or ptr */
3909 /*-----------------------------------------------------------------*/
3910 set * lvaluereqSet = NULL;
3911 typedef struct lvalItem
3918 /*-----------------------------------------------------------------*/
3919 /* addLvaluereq - add a flag for lvalreq for current ast level */
3920 /*-----------------------------------------------------------------*/
3921 void addLvaluereq(int lvl)
3923 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3926 addSetHead(&lvaluereqSet,lpItem);
3929 /*-----------------------------------------------------------------*/
3930 /* delLvaluereq - del a flag for lvalreq for current ast level */
3931 /*-----------------------------------------------------------------*/
3935 lpItem = getSet(&lvaluereqSet);
3936 if(lpItem) Safe_free(lpItem);
3938 /*-----------------------------------------------------------------*/
3939 /* clearLvaluereq - clear lvalreq flag */
3940 /*-----------------------------------------------------------------*/
3941 void clearLvaluereq()
3944 lpItem = peekSet(lvaluereqSet);
3945 if(lpItem) lpItem->req = 0;
3947 /*-----------------------------------------------------------------*/
3948 /* getLvaluereq - get the last lvalreq level */
3949 /*-----------------------------------------------------------------*/
3950 int getLvaluereqLvl()
3953 lpItem = peekSet(lvaluereqSet);
3954 if(lpItem) return lpItem->lvl;
3957 /*-----------------------------------------------------------------*/
3958 /* isLvaluereq - is lvalreq valid for this level ? */
3959 /*-----------------------------------------------------------------*/
3960 int isLvaluereq(int lvl)
3963 lpItem = peekSet(lvaluereqSet);
3964 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3968 /*-----------------------------------------------------------------*/
3969 /* ast2iCode - creates an icodeList from an ast */
3970 /*-----------------------------------------------------------------*/
3972 ast2iCode (ast * tree,int lvl)
3974 operand *left = NULL;
3975 operand *right = NULL;
3979 /* set the global variables for filename & line number */
3981 filename = tree->filename;
3983 lineno = tree->lineno;
3985 block = tree->block;
3987 scopeLevel = tree->level;
3989 seqPoint = tree->seqPoint;
3991 if (tree->type == EX_VALUE)
3992 return operandFromValue (tree->opval.val);
3994 if (tree->type == EX_LINK)
3995 return operandFromLink (tree->opval.lnk);
3997 /* if we find a nullop */
3998 if (tree->type == EX_OP &&
3999 (tree->opval.op == NULLOP ||
4000 tree->opval.op == BLOCK))
4002 if (tree->left && tree->left->type == EX_VALUE)
4003 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4005 ast2iCode (tree->left,lvl+1);
4006 if (tree->right && tree->right->type == EX_VALUE)
4007 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4009 ast2iCode (tree->right,lvl+1);
4013 /* special cases for not evaluating */
4014 if (tree->opval.op != ':' &&
4015 tree->opval.op != '?' &&
4016 tree->opval.op != CALL &&
4017 tree->opval.op != IFX &&
4018 tree->opval.op != AND_OP &&
4019 tree->opval.op != OR_OP &&
4020 tree->opval.op != LABEL &&
4021 tree->opval.op != GOTO &&
4022 tree->opval.op != SWITCH &&
4023 tree->opval.op != FUNCTION &&
4024 tree->opval.op != INLINEASM &&
4025 tree->opval.op != CRITICAL)
4028 if (IS_ASSIGN_OP (tree->opval.op) ||
4029 IS_DEREF_OP (tree) ||
4030 (tree->opval.op == '&' && !tree->right) ||
4031 tree->opval.op == PTR_OP)
4034 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4035 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4038 left = operandFromAst (tree->left,lvl);
4040 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4041 left = geniCodeRValue (left, TRUE);
4045 left = operandFromAst (tree->left,lvl);
4047 if (tree->opval.op == INC_OP ||
4048 tree->opval.op == DEC_OP)
4051 right = operandFromAst (tree->right,lvl);
4056 right = operandFromAst (tree->right,lvl);
4060 /* now depending on the type of operand */
4061 /* this will be a biggy */
4062 switch (tree->opval.op)
4065 case '[': /* array operation */
4067 //sym_link *ltype = operandType (left);
4068 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4069 left = geniCodeRValue (left, FALSE);
4070 right = geniCodeRValue (right, TRUE);
4073 return geniCodeArray (left, right,lvl);
4075 case '.': /* structure dereference */
4076 if (IS_PTR (operandType (left)))
4077 left = geniCodeRValue (left, TRUE);
4079 left = geniCodeRValue (left, FALSE);
4081 return geniCodeStruct (left, right, tree->lvalue);
4083 case PTR_OP: /* structure pointer dereference */
4086 pType = operandType (left);
4087 left = geniCodeRValue (left, TRUE);
4089 setOClass (pType, getSpec (operandType (left)));
4092 return geniCodeStruct (left, right, tree->lvalue);
4094 case INC_OP: /* increment operator */
4096 return geniCodePostInc (left);
4098 return geniCodePreInc (right, tree->lvalue);
4100 case DEC_OP: /* decrement operator */
4102 return geniCodePostDec (left);
4104 return geniCodePreDec (right, tree->lvalue);
4106 case '&': /* bitwise and or address of operator */
4108 { /* this is a bitwise operator */
4109 left = geniCodeRValue (left, FALSE);
4110 right = geniCodeRValue (right, FALSE);
4111 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4114 return geniCodeAddressOf (left);
4116 case '|': /* bitwise or & xor */
4118 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4119 geniCodeRValue (right, FALSE),
4124 return geniCodeDivision (geniCodeRValue (left, FALSE),
4125 geniCodeRValue (right, FALSE),
4126 getResultTypeFromType (tree->ftype));
4129 return geniCodeModulus (geniCodeRValue (left, FALSE),
4130 geniCodeRValue (right, FALSE),
4131 getResultTypeFromType (tree->ftype));
4134 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4135 geniCodeRValue (right, FALSE),
4136 getResultTypeFromType (tree->ftype));
4138 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4142 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4143 geniCodeRValue (right, FALSE),
4144 getResultTypeFromType (tree->ftype));
4146 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4150 return geniCodeAdd (geniCodeRValue (left, FALSE),
4151 geniCodeRValue (right, FALSE),
4152 getResultTypeFromType (tree->ftype),
4155 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4158 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4159 geniCodeRValue (right, FALSE),
4160 getResultTypeFromType (tree->ftype));
4163 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4164 geniCodeRValue (right, FALSE));
4166 #if 0 // this indeed needs a second thought
4170 // let's keep this simple: get the rvalue we need
4171 op=geniCodeRValue (right, FALSE);
4172 // now cast it to whatever we want
4173 op=geniCodeCast (operandType(left), op, FALSE);
4174 // if this is going to be used as an lvalue, make it so
4180 #else // bug #604575, is it a bug ????
4181 return geniCodeCast (operandType (left),
4182 geniCodeRValue (right, FALSE), FALSE);
4189 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4194 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4195 setOperandType (op, UCHARTYPE);
4200 return geniCodeLogicAndOr (tree, lvl);
4207 /* different compilers (even different gccs) evaluate
4208 the two calls in a different order. to get the same
4209 result on all machines we've to specify a clear sequence.
4210 return geniCodeLogic (geniCodeRValue (left, FALSE),
4211 geniCodeRValue (right, FALSE),
4215 operand *leftOp, *rightOp;
4217 leftOp = geniCodeRValue (left , FALSE);
4218 rightOp = geniCodeRValue (right, FALSE);
4220 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4223 return geniCodeConditional (tree,lvl);
4226 return operandFromLit (getSize (tree->right->ftype));
4230 sym_link *rtype = operandType (right);
4231 sym_link *ltype = operandType (left);
4232 if (IS_PTR (rtype) && IS_ITEMP (right)
4233 && right->isaddr && compareType (rtype->next, ltype) == 1)
4234 right = geniCodeRValue (right, TRUE);
4236 right = geniCodeRValue (right, FALSE);
4238 geniCodeAssign (left, right, 0, 1);
4243 geniCodeAssign (left,
4244 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4246 geniCodeRValue (right, FALSE),
4247 getResultTypeFromType (tree->ftype)),
4252 geniCodeAssign (left,
4253 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4255 geniCodeRValue (right, FALSE),
4256 getResultTypeFromType (tree->ftype)),
4260 geniCodeAssign (left,
4261 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4263 geniCodeRValue (right, FALSE),
4264 getResultTypeFromType (tree->ftype)),
4268 sym_link *rtype = operandType (right);
4269 sym_link *ltype = operandType (left);
4270 if (IS_PTR (rtype) && IS_ITEMP (right)
4271 && right->isaddr && compareType (rtype->next, ltype) == 1)
4272 right = geniCodeRValue (right, TRUE);
4274 right = geniCodeRValue (right, FALSE);
4277 return geniCodeAssign (left,
4278 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4281 getResultTypeFromType (tree->ftype),
4287 sym_link *rtype = operandType (right);
4288 sym_link *ltype = operandType (left);
4289 if (IS_PTR (rtype) && IS_ITEMP (right)
4290 && right->isaddr && compareType (rtype->next, ltype) == 1)
4292 right = geniCodeRValue (right, TRUE);
4296 right = geniCodeRValue (right, FALSE);
4299 geniCodeAssign (left,
4300 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4303 getResultTypeFromType (tree->ftype)),
4308 geniCodeAssign (left,
4309 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4311 geniCodeRValue (right, FALSE),
4312 getResultTypeFromType (tree->ftype)),
4316 geniCodeAssign (left,
4317 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4319 geniCodeRValue (right, FALSE)), 0, 1);
4322 geniCodeAssign (left,
4323 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4325 geniCodeRValue (right, FALSE),
4327 operandType (left)), 0, 1);
4330 geniCodeAssign (left,
4331 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4333 geniCodeRValue (right, FALSE),
4335 operandType (left)), 0, 1);
4338 geniCodeAssign (left,
4339 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4341 geniCodeRValue (right, FALSE),
4343 operandType (left)), 0, 1);
4345 return geniCodeRValue (right, FALSE);
4348 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4351 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4352 return ast2iCode (tree->right,lvl+1);
4355 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4356 return ast2iCode (tree->right,lvl+1);
4359 geniCodeFunctionBody (tree,lvl);
4363 geniCodeReturn (right);
4367 geniCodeIfx (tree,lvl);
4371 geniCodeSwitch (tree,lvl);
4375 geniCodeInline (tree);
4379 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4383 geniCodeCritical (tree, lvl);
4389 /*-----------------------------------------------------------------*/
4390 /* reverseICChain - gets from the list and creates a linkedlist */
4391 /*-----------------------------------------------------------------*/
4398 while ((loop = getSet (&iCodeChain)))
4410 /*-----------------------------------------------------------------*/
4411 /* iCodeFromAst - given an ast will convert it to iCode */
4412 /*-----------------------------------------------------------------*/
4414 iCodeFromAst (ast * tree)
4416 returnLabel = newiTempLabel ("_return");
4417 entryLabel = newiTempLabel ("_entry");
4419 return reverseiCChain ();
4422 static const char *opTypeToStr(OPTYPE op)
4426 case SYMBOL: return "symbol";
4427 case VALUE: return "value";
4428 case TYPE: return "type";
4430 return "undefined type";
4434 operand *validateOpType(operand *op,
4441 if (op && op->type == type)
4446 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4447 " expected %s, got %s\n",
4448 macro, args, file, line,
4449 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4451 return op; // never reached, makes compiler happy.