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 {GETABIT, "gabit", picGenericOne, NULL},
84 {GETBYTE, "gbyte", picGenericOne, NULL},
85 {GETWORD, "gword", picGenericOne, NULL},
86 {UNARYMINUS, "-", picGenericOne, NULL},
87 {IPUSH, "push", picGenericOne, NULL},
88 {IPOP, "pop", picGenericOne, NULL},
89 {CALL, "call", picGenericOne, NULL},
90 {PCALL, "pcall", picGenericOne, NULL},
91 {FUNCTION, "proc", picGenericOne, NULL},
92 {ENDFUNCTION, "eproc", picGenericOne, NULL},
93 {RETURN, "ret", picGenericOne, NULL},
94 {'+', "+", picGeneric, NULL},
95 {'-', "-", picGeneric, NULL},
96 {'*', "*", picGeneric, NULL},
97 {'/', "/", picGeneric, NULL},
98 {'%', "%", picGeneric, NULL},
99 {'>', ">", picGeneric, NULL},
100 {'<', "<", picGeneric, NULL},
101 {LE_OP, "<=", picGeneric, NULL},
102 {GE_OP, ">=", picGeneric, NULL},
103 {EQ_OP, "==", picGeneric, NULL},
104 {NE_OP, "!=", picGeneric, NULL},
105 {AND_OP, "&&", picGeneric, NULL},
106 {OR_OP, "||", picGeneric, NULL},
107 {'^', "^", picGeneric, NULL},
108 {'|', "|", picGeneric, NULL},
109 {BITWISEAND, "&", picGeneric, NULL},
110 {LEFT_OP, "<<", picGeneric, NULL},
111 {RIGHT_OP, ">>", picGeneric, NULL},
112 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
113 {ADDRESS_OF, "&", picAddrOf, NULL},
114 {CAST, "<>", picCast, NULL},
115 {'=', ":=", picAssign, NULL},
116 {LABEL, "", picLabel, NULL},
117 {GOTO, "", picGoto, NULL},
118 {JUMPTABLE, "jtab", picJumpTable, NULL},
119 {IFX, "if", picIfx, NULL},
120 {INLINEASM, "", picInline, NULL},
121 {RECEIVE, "recv", picReceive, NULL},
122 {SEND, "send", picGenericOne, NULL},
123 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
124 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
125 {CRITICAL, "critical_start", picCritical, NULL},
126 {ENDCRITICAL, "critical_end", picEndCritical, NULL},
127 {SWAP, "swap", picGenericOne, NULL}
130 /*-----------------------------------------------------------------*/
131 /* checkConstantRange: check a constant against the type */
132 /*-----------------------------------------------------------------*/
135 /* pedantic=0: allmost anything is allowed as long as the absolute
136 value is within the bit range of the type, and -1 is treated as
137 0xf..f for unsigned types (e.g. in assign)
138 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
139 pedantic>1: "char c=200" is not allowed (evaluates to -56)
142 void checkConstantRange(sym_link *ltype, value *val, char *msg,
149 max = pow ((double)2.0, (double)bitsForType(ltype));
151 if (IS_LONG(val->type)) {
152 if (IS_UNSIGNED(val->type)) {
153 v=SPEC_CVAL(val->type).v_ulong;
155 v=SPEC_CVAL(val->type).v_long;
158 if (IS_UNSIGNED(val->type)) {
159 v=SPEC_CVAL(val->type).v_uint;
161 v=SPEC_CVAL(val->type).v_int;
167 // this could be a good idea
168 if (options.pedantic)
172 if (IS_FLOAT(ltype)) {
177 if (IS_FIXED(ltype)) {
182 if (!IS_UNSIGNED(val->type) && v<0) {
184 if (IS_UNSIGNED(ltype) && (pedantic>1)) {
190 // if very pedantic: "char c=200" is not allowed
191 if (pedantic>1 && !IS_UNSIGNED(ltype)) {
192 max = max/2 + negative;
199 #if 0 // temporary disabled, leaving the warning as a reminder
201 SNPRINTF (message, sizeof(message), "for %s %s in %s",
202 IS_UNSIGNED(ltype) ? "unsigned" : "signed",
203 nounName(ltype), msg);
204 werror (W_CONST_RANGE, message);
212 /*-----------------------------------------------------------------*/
213 /* operandName - returns the name of the operand */
214 /*-----------------------------------------------------------------*/
216 printOperand (operand * op, FILE * file)
233 opetype = getSpec (operandType (op));
234 if (IS_FLOAT (opetype))
235 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
236 if (IS_FIXED16X16 (opetype))
237 fprintf (file, "%g {", doubleFromFixed16x16(SPEC_CVAL (opetype).v_fixed16x16));
239 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
240 printTypeChain (operandType (op), file);
247 if(REGA && !getenv("PRINT_SHORT_OPERANDS")) {
248 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}" , */
249 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
251 OP_LIVEFROM (op), OP_LIVETO (op),
252 OP_SYMBOL (op)->stack,
253 op->isaddr, op->aggr2ptr, OP_SYMBOL (op)->isreqv,
254 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
255 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
259 printTypeChain (operandType (op), file);
260 if (SPIL_LOC (op) && IS_ITEMP (op))
261 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
266 /* if assigned to registers */
267 if (OP_SYMBOL (op)->nRegs)
269 if (OP_SYMBOL (op)->isspilt)
271 if (!OP_SYMBOL (op)->remat)
272 if (OP_SYMBOL (op)->usl.spillLoc)
273 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
274 OP_SYMBOL (op)->usl.spillLoc->rname :
275 OP_SYMBOL (op)->usl.spillLoc->name));
277 fprintf (file, "[err]");
279 fprintf (file, "[remat]");
285 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
286 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
290 //#else /* } else { */
292 /* (getenv("PRINT_SHORT_OPERANDS") != NULL) */
293 fprintf (file, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
295 if(getenv("PRINT_SHORT_OPERANDS")[0] < '1')
297 fprintf (file, "[lr%d:%d so:%d]",
298 OP_LIVEFROM (op), OP_LIVETO (op),
299 OP_SYMBOL (op)->stack);
302 if(getenv("PRINT_SHORT_OPERANDS")[0] < '2')
305 printTypeChain (operandType (op), file);
306 if (SPIL_LOC (op) && IS_ITEMP (op))
307 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
311 /* if assigned to registers */
312 if (OP_SYMBOL (op)->nRegs)
314 if (OP_SYMBOL (op)->isspilt)
316 if (!OP_SYMBOL (op)->remat)
317 if (OP_SYMBOL (op)->usl.spillLoc)
318 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
319 OP_SYMBOL (op)->usl.spillLoc->rname :
320 OP_SYMBOL (op)->usl.spillLoc->name));
322 fprintf (file, "[err]");
324 fprintf (file, "[remat]");
330 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
331 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
341 printTypeChain (op->operand.typeOperand, file);
347 fprintf (file, "\n");
352 /*-----------------------------------------------------------------*/
353 /* print functions */
354 /*-----------------------------------------------------------------*/
355 PRINTFUNC (picGetValueAtAddr)
358 printOperand (IC_RESULT (ic), of);
361 printOperand (IC_LEFT (ic), of);
367 PRINTFUNC (picSetValueAtAddr)
371 printOperand (IC_LEFT (ic), of);
372 fprintf (of, "] = ");
373 printOperand (IC_RIGHT (ic), of);
377 PRINTFUNC (picAddrOf)
380 printOperand (IC_RESULT (ic), of);
381 if (IS_ITEMP (IC_LEFT (ic)))
384 fprintf (of, " = &[");
385 printOperand (IC_LEFT (ic), of);
388 if (IS_ITEMP (IC_LEFT (ic)))
389 fprintf (of, " offsetAdd ");
392 printOperand (IC_RIGHT (ic), of);
394 if (IS_ITEMP (IC_LEFT (ic)))
400 PRINTFUNC (picJumpTable)
405 fprintf (of, "%s\t", s);
406 printOperand (IC_JTCOND (ic), of);
408 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
409 sym = setNextItem (IC_JTLABELS (ic)))
410 fprintf (of, "\t\t\t%s\n", sym->name);
413 PRINTFUNC (picGeneric)
416 printOperand (IC_RESULT (ic), of);
418 printOperand (IC_LEFT (ic), of);
419 fprintf (of, " %s ", s);
420 printOperand (IC_RIGHT (ic), of);
424 PRINTFUNC (picGenericOne)
429 printOperand (IC_RESULT (ic), of);
435 fprintf (of, "%s ", s);
436 printOperand (IC_LEFT (ic), of);
439 if (!IC_RESULT (ic) && !IC_LEFT (ic))
442 if (ic->op == SEND || ic->op == RECEIVE) {
443 fprintf(of,"{argreg = %d}",ic->argreg);
445 if (ic->op == IPUSH) {
446 fprintf(of,"{parmPush = %d}",ic->parmPush);
454 printOperand (IC_RESULT (ic), of);
456 printOperand (IC_LEFT (ic), of);
457 printOperand (IC_RIGHT (ic), of);
462 PRINTFUNC (picAssign)
466 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
469 printOperand (IC_RESULT (ic), of);
471 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
474 fprintf (of, " %s ", s);
475 printOperand (IC_RIGHT (ic), of);
482 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
488 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
495 printOperand (IC_COND (ic), of);
498 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
501 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
503 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
507 PRINTFUNC (picInline)
509 fprintf (of, "%s", IC_INLINE (ic));
512 PRINTFUNC (picReceive)
514 printOperand (IC_RESULT (ic), of);
515 fprintf (of, " = %s ", s);
516 printOperand (IC_LEFT (ic), of);
520 PRINTFUNC (picDummyRead)
523 fprintf (of, "%s ", s);
524 printOperand (IC_RIGHT (ic), of);
528 PRINTFUNC (picCritical)
532 printOperand (IC_RESULT (ic), of);
534 fprintf (of, "(stack)");
535 fprintf (of, " = %s ", s);
539 PRINTFUNC (picEndCritical)
542 fprintf (of, "%s = ", s);
544 printOperand (IC_RIGHT (ic), of);
546 fprintf (of, "(stack)");
550 /*-----------------------------------------------------------------*/
551 /* piCode - prints one iCode */
552 /*-----------------------------------------------------------------*/
554 piCode (void *item, FILE * of)
562 icTab = getTableEntry (ic->op);
563 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
564 ic->filename, ic->lineno,
565 ic->seq, ic->key, ic->depth, ic->supportRtn);
566 icTab->iCodePrint (of, ic, icTab->printName);
572 printiCChain(ic,stdout);
574 /*-----------------------------------------------------------------*/
575 /* printiCChain - prints intermediate code for humans */
576 /*-----------------------------------------------------------------*/
578 printiCChain (iCode * icChain, FILE * of)
585 for (loop = icChain; loop; loop = loop->next)
587 if ((icTab = getTableEntry (loop->op)))
589 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
590 loop->filename, loop->lineno,
591 loop->seq, loop->key, loop->depth, loop->supportRtn);
593 icTab->iCodePrint (of, loop, icTab->printName);
599 /*-----------------------------------------------------------------*/
600 /* newOperand - allocate, init & return a new iCode */
601 /*-----------------------------------------------------------------*/
607 op = Safe_alloc ( sizeof (operand));
613 /*-----------------------------------------------------------------*/
614 /* newiCode - create and return a new iCode entry initialised */
615 /*-----------------------------------------------------------------*/
617 newiCode (int op, operand * left, operand * right)
621 ic = Safe_alloc ( sizeof (iCode));
623 ic->seqPoint = seqPoint;
625 ic->filename = filename;
627 ic->level = scopeLevel;
629 ic->key = iCodeKey++;
631 IC_RIGHT (ic) = right;
636 /*-----------------------------------------------------------------*/
637 /* newiCode for conditional statements */
638 /*-----------------------------------------------------------------*/
640 newiCodeCondition (operand * condition,
646 if (IS_VOID(operandType(condition))) {
647 werror(E_VOID_VALUE_USED);
650 ic = newiCode (IFX, NULL, NULL);
651 IC_COND (ic) = condition;
652 IC_TRUE (ic) = trueLabel;
653 IC_FALSE (ic) = falseLabel;
657 /*-----------------------------------------------------------------*/
658 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
659 /*-----------------------------------------------------------------*/
661 newiCodeLabelGoto (int op, symbol * label)
665 ic = newiCode (op, NULL, NULL);
669 IC_RIGHT (ic) = NULL;
670 IC_RESULT (ic) = NULL;
674 /*-----------------------------------------------------------------*/
675 /* newiTemp - allocate & return a newItemp Variable */
676 /*-----------------------------------------------------------------*/
684 SNPRINTF (buffer, sizeof(buffer), "%s", s);
688 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
691 itmp = newSymbol (buffer, 1);
692 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
698 /*-----------------------------------------------------------------*/
699 /* newiTempLabel - creates a temp variable label */
700 /*-----------------------------------------------------------------*/
702 newiTempLabel (char *s)
706 /* check if this already exists */
707 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
712 itmplbl = newSymbol (s, 1);
716 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
717 itmplbl = newSymbol (buffer, 1);
722 itmplbl->key = labelKey++;
723 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
727 /*-----------------------------------------------------------------*/
728 /* newiTempPreheaderLabel - creates a new preheader label */
729 /*-----------------------------------------------------------------*/
731 newiTempPreheaderLabel ()
735 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
736 itmplbl = newSymbol (buffer, 1);
740 itmplbl->key = labelKey++;
741 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
746 /*-----------------------------------------------------------------*/
747 /* initiCode - initialises some iCode related stuff */
748 /*-----------------------------------------------------------------*/
755 /*-----------------------------------------------------------------*/
756 /* copyiCode - make a copy of the iCode given */
757 /*-----------------------------------------------------------------*/
759 copyiCode (iCode * ic)
761 iCode *nic = newiCode (ic->op, NULL, NULL);
763 nic->lineno = ic->lineno;
764 nic->filename = ic->filename;
765 nic->block = ic->block;
766 nic->level = ic->level;
767 nic->parmBytes = ic->parmBytes;
769 /* deal with the special cases first */
773 IC_COND (nic) = operandFromOperand (IC_COND (ic));
774 IC_TRUE (nic) = IC_TRUE (ic);
775 IC_FALSE (nic) = IC_FALSE (ic);
779 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
780 IC_JTLABELS (nic) = IC_JTLABELS (ic);
785 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
786 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
790 IC_INLINE (nic) = IC_INLINE (ic);
794 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
798 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
799 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
800 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
806 /*-----------------------------------------------------------------*/
807 /* getTableEntry - gets the table entry for the given operator */
808 /*-----------------------------------------------------------------*/
810 getTableEntry (int oper)
814 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
815 if (oper == codeTable[i].icode)
816 return &codeTable[i];
821 /*-----------------------------------------------------------------*/
822 /* newiTempOperand - new intermediate temp operand */
823 /*-----------------------------------------------------------------*/
825 newiTempOperand (sym_link * type, char throwType)
828 operand *op = newOperand ();
832 itmp = newiTemp (NULL);
834 etype = getSpec (type);
836 if (IS_LITERAL (etype))
839 /* copy the type information */
841 itmp->etype = getSpec (itmp->type = (throwType ? type :
842 copyLinkChain (type)));
843 if (IS_LITERAL (itmp->etype))
845 SPEC_SCLS (itmp->etype) = S_REGISTER;
846 SPEC_OCLS (itmp->etype) = reg;
849 op->operand.symOperand = itmp;
850 op->key = itmp->key = ++operandKey;
854 /*-----------------------------------------------------------------*/
855 /* operandType - returns the type chain for an operand */
856 /*-----------------------------------------------------------------*/
858 operandType (operand * op)
860 /* depending on type of operand */
865 return op->operand.valOperand->type;
868 return op->operand.symOperand->type;
871 return op->operand.typeOperand;
873 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
874 " operand type not known ");
875 assert (0); /* should never come here */
876 /* Just to keep the compiler happy */
877 return (sym_link *) 0;
881 /*-----------------------------------------------------------------*/
882 /* isParamterToCall - will return 1 if op is a parameter to args */
883 /*-----------------------------------------------------------------*/
885 isParameterToCall (value * args, operand * op)
889 wassert (IS_SYMOP(op));
894 isSymbolEqual (op->operand.symOperand, tval->sym))
901 /*-----------------------------------------------------------------*/
902 /* isOperandGlobal - return 1 if operand is a global variable */
903 /*-----------------------------------------------------------------*/
905 isOperandGlobal (operand * op)
914 (op->operand.symOperand->level == 0 ||
915 IS_STATIC (op->operand.symOperand->etype) ||
916 IS_EXTERN (op->operand.symOperand->etype))
923 /*-----------------------------------------------------------------*/
924 /* isOperandVolatile - return 1 if the operand is volatile */
925 /*-----------------------------------------------------------------*/
927 isOperandVolatile (operand * op, bool chkTemp)
932 if (IS_ITEMP (op) && !chkTemp)
935 opetype = getSpec (optype = operandType (op));
937 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
940 if (IS_VOLATILE (opetype))
945 /*-----------------------------------------------------------------*/
946 /* isOperandLiteral - returns 1 if an operand contains a literal */
947 /*-----------------------------------------------------------------*/
949 isOperandLiteral (operand * op)
956 opetype = getSpec (operandType (op));
958 if (IS_LITERAL (opetype))
964 /*-----------------------------------------------------------------*/
965 /* isOperandInFarSpace - will return true if operand is in farSpace */
966 /*-----------------------------------------------------------------*/
968 isOperandInFarSpace (operand * op)
978 if (!IS_TRUE_SYMOP (op))
981 etype = SPIL_LOC (op)->etype;
987 etype = getSpec (operandType (op));
989 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
992 /*------------------------------------------------------------------*/
993 /* isOperandInDirSpace - will return true if operand is in dirSpace */
994 /*------------------------------------------------------------------*/
996 isOperandInDirSpace (operand * op)
1006 if (!IS_TRUE_SYMOP (op))
1009 etype = SPIL_LOC (op)->etype;
1015 etype = getSpec (operandType (op));
1017 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1020 /*--------------------------------------------------------------------*/
1021 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
1022 /*--------------------------------------------------------------------*/
1024 isOperandInCodeSpace (operand * op)
1034 etype = getSpec (operandType (op));
1036 if (!IS_TRUE_SYMOP (op))
1039 etype = SPIL_LOC (op)->etype;
1045 etype = getSpec (operandType (op));
1047 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1050 /*-----------------------------------------------------------------*/
1051 /* isOperandOnStack - will return true if operand is on stack */
1052 /*-----------------------------------------------------------------*/
1054 isOperandOnStack (operand * op)
1064 etype = getSpec (operandType (op));
1065 if (IN_STACK (etype) ||
1066 OP_SYMBOL(op)->onStack ||
1067 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1073 /*-----------------------------------------------------------------*/
1074 /* isOclsExpensive - will return true if accesses to an output */
1075 /* storage class are expensive */
1076 /*-----------------------------------------------------------------*/
1078 isOclsExpensive (struct memmap *oclass)
1080 if (port->oclsExpense)
1081 return port->oclsExpense (oclass) > 0;
1083 /* In the absence of port specific guidance, assume only */
1084 /* farspace is expensive. */
1085 return IN_FARSPACE (oclass);
1088 /*-----------------------------------------------------------------*/
1089 /* isiCodeInFunctionCall - return TRUE if an iCode is between a */
1090 /* CALL/PCALL and the first IPUSH/SEND associated with the call */
1091 /*-----------------------------------------------------------------*/
1093 isiCodeInFunctionCall (iCode * ic)
1097 /* Find the next CALL/PCALL */
1100 if (lic->op == CALL || lic->op == PCALL)
1108 /* A function call was found. Scan backwards and see if an */
1109 /* IPUSH or SEND is encountered */
1112 if (lic != ic && (ic->op == CALL || ic->op == PCALL))
1114 if (ic->op == SEND || (ic->op == IPUSH && ic->parmPush))
1122 /*-----------------------------------------------------------------*/
1123 /* operandLitValue - literal value of an operand */
1124 /*-----------------------------------------------------------------*/
1126 operandLitValue (operand * op)
1128 assert (isOperandLiteral (op));
1130 return floatFromVal (op->operand.valOperand);
1133 /*-----------------------------------------------------------------*/
1134 /* getBuiltInParms - returns parameters to a builtin functions */
1135 /*-----------------------------------------------------------------*/
1136 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1141 /* builtin functions uses only SEND for parameters */
1142 while (ic->op != CALL) {
1143 assert(ic->op == SEND && ic->builtinSEND);
1144 ic->generated = 1; /* mark the icode as generated */
1145 parms[*pcount] = IC_LEFT(ic);
1151 /* make sure this is a builtin function call */
1152 assert(IS_SYMOP(IC_LEFT(ic)));
1153 ftype = operandType(IC_LEFT(ic));
1154 assert(IFFUNC_ISBUILTIN(ftype));
1158 /*-----------------------------------------------------------------*/
1159 /* operandOperation - performs operations on operands */
1160 /*-----------------------------------------------------------------*/
1162 operandOperation (operand * left, operand * right,
1163 int op, sym_link * type)
1165 sym_link *let , *ret=NULL;
1166 operand *retval = (operand *) 0;
1168 assert (isOperandLiteral (left));
1169 let = getSpec(operandType(left));
1171 assert (isOperandLiteral (right));
1172 ret = getSpec(operandType(right));
1178 retval = operandFromValue (valCastLiteral (type,
1179 operandLitValue (left) +
1180 operandLitValue (right)));
1183 retval = operandFromValue (valCastLiteral (type,
1184 operandLitValue (left) -
1185 operandLitValue (right)));
1189 retval = operandFromValue (valCastLiteral (type,
1190 operandLitValue (left) *
1191 operandLitValue (right)));
1192 This could be all we've to do, but with gcc we've to take care about
1193 overflows. Two examples:
1194 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1195 significant bits are lost (52 in fraction, 63 bits would be
1196 necessary to keep full precision).
1197 If the resulting double value is greater than ULONG_MAX (resp.
1198 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1201 /* if it is not a specifier then we can assume that */
1202 /* it will be an unsigned long */
1203 if (IS_INT (type) ||
1206 /* long is handled here, because it can overflow with double */
1207 if (IS_LONG (type) ||
1209 /* signed and unsigned mul are the same, as long as the precision
1210 of the result isn't bigger than the precision of the operands. */
1211 retval = operandFromValue (valCastLiteral (type,
1212 (TYPE_UDWORD) operandLitValue (left) *
1213 (TYPE_UDWORD) operandLitValue (right)));
1214 else if (IS_UNSIGNED (type)) /* unsigned int */
1216 /* unsigned int is handled here in order to detect overflow */
1217 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1218 (TYPE_UWORD) operandLitValue (right);
1220 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1221 if (ul != (TYPE_UWORD) ul)
1224 else /* signed int */
1226 /* signed int is handled here in order to detect overflow */
1227 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1228 (TYPE_WORD) operandLitValue (right);
1230 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1231 if (l != (TYPE_WORD) l)
1236 /* all others go here: */
1237 retval = operandFromValue (valCastLiteral (type,
1238 operandLitValue (left) *
1239 operandLitValue (right)));
1242 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1244 werror (E_DIVIDE_BY_ZERO);
1250 if (IS_UNSIGNED (type))
1252 SPEC_USIGN (let) = 1;
1253 SPEC_USIGN (ret) = 1;
1254 retval = operandFromValue (valCastLiteral (type,
1255 (TYPE_UDWORD) operandLitValue (left) /
1256 (TYPE_UDWORD) operandLitValue (right)));
1260 retval = operandFromValue (valCastLiteral (type,
1261 operandLitValue (left) /
1262 operandLitValue (right)));
1267 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1269 werror (E_DIVIDE_BY_ZERO);
1274 if (IS_UNSIGNED (type))
1275 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1276 (TYPE_UDWORD) operandLitValue (right));
1278 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1279 (TYPE_DWORD) operandLitValue (right));
1283 /* The number of left shifts is always unsigned. Signed doesn't make
1284 sense here. Shifting by a negative number is impossible. */
1285 retval = operandFromValue (valCastLiteral (type,
1286 ((TYPE_UDWORD) operandLitValue (left) <<
1287 (TYPE_UDWORD) operandLitValue (right))));
1290 /* The number of right shifts is always unsigned. Signed doesn't make
1291 sense here. Shifting by a negative number is impossible. */
1292 if (IS_UNSIGNED(let))
1293 /* unsigned: logic shift right */
1294 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1295 (TYPE_UDWORD) operandLitValue (right));
1297 /* signed: arithmetic shift right */
1298 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1299 (TYPE_UDWORD) operandLitValue (right));
1302 if (IS_FLOAT (let) ||
1305 retval = operandFromLit (operandLitValue (left) ==
1306 operandLitValue (right));
1309 if (IS_FIXED16X16 (let) ||
1310 IS_FIXED16X16 (ret))
1312 retval = operandFromLit (operandLitValue (left) ==
1313 operandLitValue (right));
1317 /* this op doesn't care about signedness */
1320 l = (TYPE_UDWORD) operandLitValue (left);
1321 r = (TYPE_UDWORD) operandLitValue (right);
1322 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1323 neccessary to strip them to 16 bit.
1324 Literals are reduced to their cheapest type, therefore left and
1325 right might have different types. It's neccessary to find a
1326 common type: int (used for char too) or long */
1327 if (!IS_LONG (let) &&
1333 retval = operandFromLit (l == r);
1337 retval = operandFromLit (operandLitValue (left) <
1338 operandLitValue (right));
1341 retval = operandFromLit (operandLitValue (left) <=
1342 operandLitValue (right));
1345 retval = operandFromLit (operandLitValue (left) !=
1346 operandLitValue (right));
1349 retval = operandFromLit (operandLitValue (left) >
1350 operandLitValue (right));
1353 retval = operandFromLit (operandLitValue (left) >=
1354 operandLitValue (right));
1357 retval = operandFromValue (valCastLiteral (type,
1358 (TYPE_UDWORD)operandLitValue(left) &
1359 (TYPE_UDWORD)operandLitValue(right)));
1362 retval = operandFromValue (valCastLiteral (type,
1363 (TYPE_UDWORD)operandLitValue(left) |
1364 (TYPE_UDWORD)operandLitValue(right)));
1367 retval = operandFromValue (valCastLiteral (type,
1368 (TYPE_UDWORD)operandLitValue(left) ^
1369 (TYPE_UDWORD)operandLitValue(right)));
1372 retval = operandFromLit (operandLitValue (left) &&
1373 operandLitValue (right));
1376 retval = operandFromLit (operandLitValue (left) ||
1377 operandLitValue (right));
1381 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1383 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1389 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1391 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1396 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1397 (TYPE_UDWORD)operandLitValue(right)) & 1);
1400 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1401 (TYPE_UDWORD)operandLitValue(right)) & 0xFF);
1404 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1405 (TYPE_UDWORD)operandLitValue(right)) & 0xFFFF);
1409 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1410 ((getSize (let) * 8) - 1)) & 1);
1414 retval = operandFromValue (valCastLiteral (type,
1415 -1 * operandLitValue (left)));
1419 retval = operandFromValue (valCastLiteral (type,
1421 operandLitValue (left))));
1425 retval = operandFromLit (!operandLitValue (left));
1429 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1430 " operandOperation invalid operator ");
1438 /*-----------------------------------------------------------------*/
1439 /* isOperandEqual - compares two operand & return 1 if they r = */
1440 /*-----------------------------------------------------------------*/
1442 isOperandEqual (operand * left, operand * right)
1444 /* if the pointers are equal then they are equal */
1448 /* if either of them null then false */
1449 if (!left || !right)
1452 if (left->type != right->type)
1455 if (IS_SYMOP (left) && IS_SYMOP (right))
1456 return left->key == right->key;
1458 /* if types are the same */
1462 return isSymbolEqual (left->operand.symOperand,
1463 right->operand.symOperand);
1465 return (compareType (left->operand.valOperand->type,
1466 right->operand.valOperand->type) &&
1467 (floatFromVal (left->operand.valOperand) ==
1468 floatFromVal (right->operand.valOperand)));
1470 if (compareType (left->operand.typeOperand,
1471 right->operand.typeOperand) == 1)
1478 /*-------------------------------------------------------------------*/
1479 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1480 /*-------------------------------------------------------------------*/
1482 isiCodeEqual (iCode * left, iCode * right)
1484 /* if the same pointer */
1488 /* if either of them null */
1489 if (!left || !right)
1492 /* if operand are the same */
1493 if (left->op == right->op)
1496 /* compare all the elements depending on type */
1497 if (left->op != IFX)
1499 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1501 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1507 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1509 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1511 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1520 /*-----------------------------------------------------------------*/
1521 /* newiTempFromOp - create a temp Operand with same attributes */
1522 /*-----------------------------------------------------------------*/
1524 newiTempFromOp (operand * op)
1534 nop = newiTempOperand (operandType (op), TRUE);
1535 nop->isaddr = op->isaddr;
1536 nop->isvolatile = op->isvolatile;
1537 nop->isGlobal = op->isGlobal;
1538 nop->isLiteral = op->isLiteral;
1539 nop->usesDefs = op->usesDefs;
1540 nop->isParm = op->isParm;
1544 /*-----------------------------------------------------------------*/
1545 /* operand from operand - creates an operand holder for the type */
1546 /*-----------------------------------------------------------------*/
1548 operandFromOperand (operand * op)
1554 nop = newOperand ();
1555 nop->type = op->type;
1556 nop->isaddr = op->isaddr;
1558 nop->isvolatile = op->isvolatile;
1559 nop->isGlobal = op->isGlobal;
1560 nop->isLiteral = op->isLiteral;
1561 nop->usesDefs = op->usesDefs;
1562 nop->isParm = op->isParm;
1567 nop->operand.symOperand = op->operand.symOperand;
1570 nop->operand.valOperand = op->operand.valOperand;
1573 nop->operand.typeOperand = op->operand.typeOperand;
1580 /*-----------------------------------------------------------------*/
1581 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1582 /*-----------------------------------------------------------------*/
1584 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1586 operand *nop = operandFromOperand (op);
1588 if (nop->type == SYMBOL)
1590 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1591 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1597 /*-----------------------------------------------------------------*/
1598 /* operandFromSymbol - creates an operand from a symbol */
1599 /*-----------------------------------------------------------------*/
1601 operandFromSymbol (symbol * sym)
1606 /* if the symbol's type is a literal */
1607 /* then it is an enumerator type */
1608 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1609 return operandFromValue (valFromType (sym->etype));
1612 sym->key = ++operandKey;
1614 /* if this an implicit variable, means struct/union */
1615 /* member so just return it */
1616 if (sym->implicit || IS_FUNC (sym->type))
1620 op->operand.symOperand = sym;
1622 op->isvolatile = isOperandVolatile (op, TRUE);
1623 op->isGlobal = isOperandGlobal (op);
1627 /* under the following conditions create a
1628 register equivalent for a local symbol */
1629 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1630 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1632 (!(options.model == MODEL_FLAT24)) ) &&
1633 options.stackAuto == 0)
1636 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1637 !IS_FUNC (sym->type) && /* not a function */
1638 !sym->_isparm && /* not a parameter */
1639 IS_AUTO (sym) && /* is a local auto variable */
1640 !sym->addrtaken && /* whose address has not been taken */
1641 !sym->reqv && /* does not already have a reg equivalence */
1642 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1643 !sym->islbl && /* not a label */
1644 ok /* farspace check */
1648 /* we will use it after all optimizations
1649 and before liveRange calculation */
1650 sym->reqv = newiTempOperand (sym->type, 0);
1651 sym->reqv->key = sym->key;
1652 OP_SYMBOL (sym->reqv)->prereqv = sym;
1653 OP_SYMBOL (sym->reqv)->key = sym->key;
1654 OP_SYMBOL (sym->reqv)->isreqv = 1;
1655 OP_SYMBOL (sym->reqv)->islocal = 1;
1656 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1657 SPIL_LOC (sym->reqv) = sym;
1660 if (!IS_AGGREGATE (sym->type))
1664 op->operand.symOperand = sym;
1667 op->isvolatile = isOperandVolatile (op, TRUE);
1668 op->isGlobal = isOperandGlobal (op);
1669 op->isPtr = IS_PTR (operandType (op));
1670 op->isParm = sym->_isparm;
1675 /* itemp = &[_symbol] */
1677 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1678 IC_LEFT (ic)->type = SYMBOL;
1679 IC_LEFT (ic)->operand.symOperand = sym;
1680 IC_LEFT (ic)->key = sym->key;
1681 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1682 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1683 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1686 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1687 if (IS_ARRAY (sym->type))
1689 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1690 IC_RESULT (ic)->isaddr = 0;
1693 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1697 return IC_RESULT (ic);
1700 /*-----------------------------------------------------------------*/
1701 /* operandFromValue - creates an operand from value */
1702 /*-----------------------------------------------------------------*/
1704 operandFromValue (value * val)
1708 /* if this is a symbol then do the symbol thing */
1710 return operandFromSymbol (val->sym);
1712 /* this is not a symbol */
1715 op->operand.valOperand = val;
1716 op->isLiteral = isOperandLiteral (op);
1720 /*-----------------------------------------------------------------*/
1721 /* operandFromLink - operand from typeChain */
1722 /*-----------------------------------------------------------------*/
1724 operandFromLink (sym_link * type)
1728 /* operand from sym_link */
1734 op->operand.typeOperand = copyLinkChain (type);
1738 /*-----------------------------------------------------------------*/
1739 /* operandFromLit - makes an operand from a literal value */
1740 /*-----------------------------------------------------------------*/
1742 operandFromLit (double i)
1744 return operandFromValue (valueFromLit (i));
1747 /*-----------------------------------------------------------------*/
1748 /* operandFromAst - creates an operand from an ast */
1749 /*-----------------------------------------------------------------*/
1751 operandFromAst (ast * tree,int lvl)
1757 /* depending on type do */
1761 return ast2iCode (tree,lvl+1);
1765 return operandFromValue (tree->opval.val);
1769 return operandFromLink (tree->opval.lnk);
1776 /* Just to keep the compiler happy */
1777 return (operand *) 0;
1780 /*-----------------------------------------------------------------*/
1781 /* setOperandType - sets the operand's type to the given type */
1782 /*-----------------------------------------------------------------*/
1784 setOperandType (operand * op, sym_link * type)
1786 /* depending on the type of operand */
1791 op->operand.valOperand->etype =
1792 getSpec (op->operand.valOperand->type =
1793 copyLinkChain (type));
1797 if (op->operand.symOperand->isitmp)
1798 op->operand.symOperand->etype =
1799 getSpec (op->operand.symOperand->type =
1800 copyLinkChain (type));
1802 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1803 "attempt to modify type of source");
1807 op->operand.typeOperand = copyLinkChain (type);
1813 /*-----------------------------------------------------------------*/
1814 /* Get size in byte of ptr need to access an array */
1815 /*-----------------------------------------------------------------*/
1817 getArraySizePtr (operand * op)
1819 sym_link *ltype = operandType(op);
1823 int size = getSize(ltype);
1824 return((IS_GENPTR(ltype) && GPTRSIZE > FPTRSIZE) ? (size-1) : size);
1829 sym_link *letype = getSpec(ltype);
1830 switch (PTR_TYPE (SPEC_OCLS (letype)))
1842 if (GPTRSIZE > FPTRSIZE)
1843 return (GPTRSIZE-1);
1854 /*-----------------------------------------------------------------*/
1855 /* perform "usual unary conversions" */
1856 /*-----------------------------------------------------------------*/
1859 usualUnaryConversions (operand * op)
1861 if (IS_INTEGRAL (operandType (op)))
1863 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1866 return geniCodeCast (INTTYPE, op, TRUE);
1873 /*-----------------------------------------------------------------*/
1874 /* perform "usual binary conversions" */
1875 /*-----------------------------------------------------------------*/
1878 usualBinaryConversions (operand ** op1, operand ** op2,
1879 RESULT_TYPE resultType, int op)
1882 sym_link *rtype = operandType (*op2);
1883 sym_link *ltype = operandType (*op1);
1885 ctype = computeType (ltype, rtype, resultType, op);
1892 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1894 /* one byte operations: keep signedness for code generator */
1902 *op1 = geniCodeCast (ctype, *op1, TRUE);
1903 *op2 = geniCodeCast (ctype, *op2, TRUE);
1908 /*-----------------------------------------------------------------*/
1909 /* geniCodeValueAtAddress - generate intermeditate code for value */
1911 /*-----------------------------------------------------------------*/
1913 geniCodeRValue (operand * op, bool force)
1916 sym_link *type = operandType (op);
1917 sym_link *etype = getSpec (type);
1919 /* if this is an array & already */
1920 /* an address then return this */
1921 if (IS_AGGREGATE (type) ||
1922 (IS_PTR (type) && !force && !op->isaddr))
1923 return operandFromOperand (op);
1925 /* if this is not an address then must be */
1926 /* rvalue already so return this one */
1930 /* if this is not a temp symbol then */
1931 if (!IS_ITEMP (op) &&
1933 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1935 op = operandFromOperand (op);
1940 if (IS_SPEC (type) &&
1941 IS_TRUE_SYMOP (op) &&
1942 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1943 (options.model == MODEL_FLAT24) ))
1945 op = operandFromOperand (op);
1950 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1951 if (IS_PTR (type) && op->isaddr && force)
1954 type = copyLinkChain (type);
1956 IC_RESULT (ic) = newiTempOperand (type, 1);
1957 IC_RESULT (ic)->isaddr = 0;
1959 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1963 return IC_RESULT (ic);
1966 /*-----------------------------------------------------------------*/
1967 /* geniCodeCast - changes the value from one type to another */
1968 /*-----------------------------------------------------------------*/
1970 geniCodeCast (sym_link * type, operand * op, bool implicit)
1974 sym_link *opetype = getSpec (optype = operandType (op));
1978 /* one of them has size zero then error */
1979 if (IS_VOID (optype))
1981 werror (E_CAST_ZERO);
1985 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1987 geniCodeArray2Ptr (op);
1991 /* if the operand is already the desired type then do nothing */
1992 if (compareType (type, optype) == 1)
1995 /* if this is a literal then just change the type & return */
1996 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1998 return operandFromValue (valCastLiteral (type,
1999 operandLitValue (op)));
2002 /* if casting to/from pointers, do some checking */
2003 if (IS_PTR(type)) { // to a pointer
2004 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
2005 if (IS_INTEGRAL(optype)) {
2006 // maybe this is NULL, than it's ok.
2007 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
2008 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
2009 // no way to set the storage
2010 if (IS_LITERAL(optype)) {
2011 werror(E_LITERAL_GENERIC);
2014 werror(E_NONPTR2_GENPTR);
2017 } else if (implicit) {
2018 werror(W_INTEGRAL2PTR_NOCAST);
2023 // shouldn't do that with float, array or structure unless to void
2024 if (!IS_VOID(getSpec(type)) &&
2025 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2026 werror(E_INCOMPAT_TYPES);
2030 } else { // from a pointer to a pointer
2031 if (IS_GENPTR(type) && IS_VOID(type->next))
2032 { // cast to void* is always allowed
2034 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
2035 { // cast from void* is always allowed
2037 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2038 // if not a pointer to a function
2039 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2040 if (implicit) { // if not to generic, they have to match
2041 if (!IS_GENPTR(type) &&
2042 !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
2043 ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
2047 werror(E_INCOMPAT_PTYPES);
2054 } else { // to a non pointer
2055 if (IS_PTR(optype)) { // from a pointer
2056 if (implicit) { // sneaky
2057 if (IS_INTEGRAL(type)) {
2058 werror(W_PTR2INTEGRAL_NOCAST);
2060 } else { // shouldn't do that with float, array or structure
2061 werror(E_INCOMPAT_TYPES);
2068 printFromToType (optype, type);
2071 /* if they are the same size create an assignment */
2073 /* This seems very dangerous to me, since there are several */
2074 /* optimizations (for example, gcse) that don't notice the */
2075 /* cast hidden in this assignement and may simplify an */
2076 /* iCode to use the original (uncasted) operand. */
2077 /* Unfortunately, other things break when this cast is */
2078 /* made explicit. Need to fix this someday. */
2079 /* -- EEP, 2004/01/21 */
2080 if (getSize (type) == getSize (optype) &&
2081 !IS_BITFIELD (type) &&
2083 !IS_FLOAT (optype) &&
2085 !IS_FIXED (optype) &&
2086 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2087 (!IS_SPEC (type) && !IS_SPEC (optype))))
2089 ic = newiCode ('=', NULL, op);
2090 IC_RESULT (ic) = newiTempOperand (type, 0);
2091 if (IS_TRUE_SYMOP (op) && !IS_VOLATILE (optype))
2092 SPIL_LOC (IC_RESULT (ic)) = OP_SYMBOL (op);
2093 IC_RESULT (ic)->isaddr = 0;
2097 ic = newiCode (CAST, operandFromLink (type),
2098 geniCodeRValue (op, FALSE));
2100 IC_RESULT (ic) = newiTempOperand (type, 0);
2103 /* preserve the storage class & output class */
2104 /* of the original variable */
2105 restype = getSpec (operandType (IC_RESULT (ic)));
2106 if (!IS_LITERAL(opetype) &&
2109 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2110 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2113 return IC_RESULT (ic);
2116 /*-----------------------------------------------------------------*/
2117 /* geniCodeLabel - will create a Label */
2118 /*-----------------------------------------------------------------*/
2120 geniCodeLabel (symbol * label)
2124 ic = newiCodeLabelGoto (LABEL, label);
2128 /*-----------------------------------------------------------------*/
2129 /* geniCodeGoto - will create a Goto */
2130 /*-----------------------------------------------------------------*/
2132 geniCodeGoto (symbol * label)
2136 ic = newiCodeLabelGoto (GOTO, label);
2140 /*-----------------------------------------------------------------*/
2141 /* geniCodeMultiply - gen intermediate code for multiplication */
2142 /*-----------------------------------------------------------------*/
2144 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2151 /* if they are both literal then we know the result */
2152 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2153 return operandFromValue (valMult (left->operand.valOperand,
2154 right->operand.valOperand));
2156 if (IS_LITERAL(retype)) {
2157 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2160 resType = usualBinaryConversions (&left, &right, resultType, '*');
2162 rtype = operandType (right);
2163 retype = getSpec (rtype);
2164 ltype = operandType (left);
2165 letype = getSpec (ltype);
2168 /* if the right is a literal & power of 2 */
2169 /* then make it a left shift */
2170 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2171 efficient in most cases than 2 bytes result = 2 bytes << literal
2172 if port has 1 byte muldiv */
2173 if (p2 && !IS_FLOAT (letype) && !IS_FIXED (letype)
2174 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2175 && (port->support.muldiv == 1))
2176 && strcmp (port->target, "pic16") != 0 /* don't shift for pic */
2177 && strcmp (port->target, "pic14") != 0)
2179 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2181 /* LEFT_OP need same size for left and result, */
2182 left = geniCodeCast (resType, left, TRUE);
2183 ltype = operandType (left);
2185 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2189 ic = newiCode ('*', left, right); /* normal multiplication */
2190 /* if the size left or right > 1 then support routine */
2191 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2195 IC_RESULT (ic) = newiTempOperand (resType, 1);
2198 return IC_RESULT (ic);
2201 /*-----------------------------------------------------------------*/
2202 /* geniCodeDivision - gen intermediate code for division */
2203 /*-----------------------------------------------------------------*/
2205 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2210 sym_link *rtype = operandType (right);
2211 sym_link *retype = getSpec (rtype);
2212 sym_link *ltype = operandType (left);
2213 sym_link *letype = getSpec (ltype);
2215 resType = usualBinaryConversions (&left, &right, resultType, '/');
2217 /* if the right is a literal & power of 2
2218 and left is unsigned then make it a
2220 if (IS_LITERAL (retype) &&
2221 !IS_FLOAT (letype) &&
2222 !IS_FIXED (letype) &&
2223 IS_UNSIGNED(letype) &&
2224 (p2 = powof2 ((TYPE_UDWORD)
2225 floatFromVal (right->operand.valOperand)))) {
2226 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2230 ic = newiCode ('/', left, right); /* normal division */
2231 /* if the size left or right > 1 then support routine */
2232 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2235 IC_RESULT (ic) = newiTempOperand (resType, 0);
2238 return IC_RESULT (ic);
2240 /*-----------------------------------------------------------------*/
2241 /* geniCodeModulus - gen intermediate code for modulus */
2242 /*-----------------------------------------------------------------*/
2244 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2250 /* if they are both literal then we know the result */
2251 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2252 return operandFromValue (valMod (left->operand.valOperand,
2253 right->operand.valOperand));
2255 resType = usualBinaryConversions (&left, &right, resultType, '%');
2257 /* now they are the same size */
2258 ic = newiCode ('%', left, right);
2260 /* if the size left or right > 1 then support routine */
2261 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2263 IC_RESULT (ic) = newiTempOperand (resType, 0);
2266 return IC_RESULT (ic);
2269 /*-----------------------------------------------------------------*/
2270 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2271 /*-----------------------------------------------------------------*/
2273 geniCodePtrPtrSubtract (operand * left, operand * right)
2279 /* if they are both literals then */
2280 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2282 result = operandFromValue (valMinus (left->operand.valOperand,
2283 right->operand.valOperand));
2287 ic = newiCode ('-', left, right);
2289 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2293 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2297 // should we really do this? is this ANSI?
2298 return geniCodeDivision (result,
2299 operandFromLit (getSize (ltype->next)),
2303 /*-----------------------------------------------------------------*/
2304 /* geniCodeSubtract - generates code for subtraction */
2305 /*-----------------------------------------------------------------*/
2307 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2314 /* if they both pointers then */
2315 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2316 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2317 return geniCodePtrPtrSubtract (left, right);
2319 /* if they are both literal then we know the result */
2320 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2321 && left->isLiteral && right->isLiteral)
2322 return operandFromValue (valMinus (left->operand.valOperand,
2323 right->operand.valOperand));
2325 /* if left is an array or pointer */
2326 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2328 isarray = left->isaddr;
2329 right = geniCodeMultiply (right,
2330 operandFromLit (getSize (ltype->next)),
2331 (getArraySizePtr(left) >= INTSIZE) ?
2334 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2337 { /* make them the same size */
2338 resType = usualBinaryConversions (&left, &right, resultType, '-');
2341 ic = newiCode ('-', left, right);
2343 IC_RESULT (ic) = newiTempOperand (resType, 1);
2344 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2346 /* if left or right is a float */
2347 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2348 || IS_FIXED (ltype) || IS_FIXED (rtype))
2352 return IC_RESULT (ic);
2355 /*-----------------------------------------------------------------*/
2356 /* geniCodeAdd - generates iCode for addition */
2357 /*-----------------------------------------------------------------*/
2359 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2368 /* if the right side is LITERAL zero */
2369 /* return the left side */
2370 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2373 /* if left is literal zero return right */
2374 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2377 /* if left is a pointer then size */
2378 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2380 isarray = left->isaddr;
2381 // there is no need to multiply with 1
2382 if (getSize (ltype->next) != 1)
2384 size = operandFromLit (getSize (ltype->next));
2385 SPEC_USIGN (getSpec (operandType (size))) = 1;
2386 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2387 right = geniCodeMultiply (right,
2389 (getArraySizePtr(left) >= INTSIZE) ?
2392 /* Even if right is a 'unsigned char',
2393 the result will be a 'signed int' due to the promotion rules.
2394 It doesn't make sense when accessing arrays, so let's fix it here: */
2396 SPEC_USIGN (getSpec (operandType (right))) = 1;
2398 resType = copyLinkChain (ltype);
2401 { // make them the same size
2402 resType = usualBinaryConversions (&left, &right, resultType, '+');
2405 /* if they are both literals then we know */
2406 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2407 && left->isLiteral && right->isLiteral)
2408 return operandFromValue (valPlus (valFromType (ltype),
2409 valFromType (rtype)));
2411 ic = newiCode ('+', left, right);
2413 IC_RESULT (ic) = newiTempOperand (resType, 1);
2414 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2416 /* if left or right is a float then support
2418 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2419 || IS_FIXED (ltype) || IS_FIXED (rtype))
2424 return IC_RESULT (ic);
2428 /*-----------------------------------------------------------------*/
2429 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2430 /*-----------------------------------------------------------------*/
2432 aggrToPtr (sym_link * type, bool force)
2437 if (IS_PTR (type) && !force)
2440 etype = getSpec (type);
2441 ptype = newLink (DECLARATOR);
2445 /* set the pointer depending on the storage class */
2446 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2450 /*------------------------------------------------------------------*/
2451 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2452 /*------------------------------------------------------------------*/
2454 aggrToPtrDclType (sym_link * type, bool force)
2456 if (IS_PTR (type) && !force)
2457 return DCL_TYPE (type);
2459 /* return the pointer depending on the storage class */
2460 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2463 /*-----------------------------------------------------------------*/
2464 /* geniCodeArray2Ptr - array to pointer */
2465 /*-----------------------------------------------------------------*/
2467 geniCodeArray2Ptr (operand * op)
2469 sym_link *optype = operandType (op);
2470 sym_link *opetype = getSpec (optype);
2472 /* set the pointer depending on the storage class */
2473 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2480 /*-----------------------------------------------------------------*/
2481 /* geniCodeArray - array access */
2482 /*-----------------------------------------------------------------*/
2484 geniCodeArray (operand * left, operand * right, int lvl)
2488 sym_link *ltype = operandType (left);
2493 if (IS_PTR (ltype->next) && left->isaddr)
2495 left = geniCodeRValue (left, FALSE);
2498 return geniCodeDerefPtr (geniCodeAdd (left,
2500 (getArraySizePtr(left) >= INTSIZE) ?
2506 size = operandFromLit (getSize (ltype->next));
2507 SPEC_USIGN (getSpec (operandType (size))) = 1;
2508 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2509 right = geniCodeMultiply (right,
2511 (getArraySizePtr(left) >= INTSIZE) ?
2514 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2515 It doesn't make sense when accessing arrays, so let's fix it here: */
2517 SPEC_USIGN (getSpec (operandType (right))) = 1;
2518 /* we can check for limits here */
2519 /* already done in SDCCast.c
2520 if (isOperandLiteral (right) &&
2523 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2525 werror (W_IDX_OUT_OF_BOUNDS,
2526 (int) operandLitValue (right) / getSize (ltype->next),
2531 ic = newiCode ('+', left, right);
2533 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2534 !IS_AGGREGATE (ltype->next) &&
2535 !IS_PTR (ltype->next))
2536 ? ltype : ltype->next), 0);
2538 if (!IS_AGGREGATE (ltype->next))
2540 IC_RESULT (ic)->isaddr = 1;
2541 IC_RESULT (ic)->aggr2ptr = 1;
2545 return IC_RESULT (ic);
2548 /*-----------------------------------------------------------------*/
2549 /* geniCodeStruct - generates intermediate code for structures */
2550 /*-----------------------------------------------------------------*/
2552 geniCodeStruct (operand * left, operand * right, bool islval)
2555 sym_link *type = operandType (left);
2556 sym_link *etype = getSpec (type);
2558 symbol *element = getStructElement (SPEC_STRUCT (etype),
2559 right->operand.symOperand);
2561 wassert(IS_SYMOP(right));
2563 /* add the offset */
2564 ic = newiCode ('+', left, operandFromLit (element->offset));
2566 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2568 /* preserve the storage & output class of the struct */
2569 /* as well as the volatile attribute */
2570 retype = getSpec (operandType (IC_RESULT (ic)));
2571 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2572 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2573 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2574 SPEC_CONST (retype) |= SPEC_CONST (etype);
2576 if (IS_PTR (element->type))
2577 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2579 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2582 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2585 /*-----------------------------------------------------------------*/
2586 /* geniCodePostInc - generate int code for Post increment */
2587 /*-----------------------------------------------------------------*/
2589 geniCodePostInc (operand * op)
2593 sym_link *optype = operandType (op);
2595 operand *rv = (IS_ITEMP (op) ?
2596 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2598 sym_link *rvtype = operandType (rv);
2601 /* if this is not an address we have trouble */
2604 werror (E_LVALUE_REQUIRED, "++");
2608 rOp = newiTempOperand (rvtype, 0);
2609 OP_SYMBOL(rOp)->noSpilLoc = 1;
2612 OP_SYMBOL(rv)->noSpilLoc = 1;
2614 geniCodeAssign (rOp, rv, 0, 0);
2616 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2618 werror(W_SIZEOF_VOID);
2619 if (IS_FLOAT (rvtype))
2620 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2622 if (IS_FIXED16X16 (rvtype))
2623 ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
2625 ic = newiCode ('+', rv, operandFromLit (size));
2627 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2630 geniCodeAssign (op, result, 0, 0);
2636 /*-----------------------------------------------------------------*/
2637 /* geniCodePreInc - generate code for preIncrement */
2638 /*-----------------------------------------------------------------*/
2640 geniCodePreInc (operand * op, bool lvalue)
2643 sym_link *optype = operandType (op);
2644 operand *rop = (IS_ITEMP (op) ?
2645 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2647 sym_link *roptype = operandType (rop);
2653 werror (E_LVALUE_REQUIRED, "++");
2657 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2659 werror(W_SIZEOF_VOID);
2660 if (IS_FLOAT (roptype))
2661 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2663 if (IS_FIXED16X16 (roptype))
2664 ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
2666 ic = newiCode ('+', rop, operandFromLit (size));
2667 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2670 (void) geniCodeAssign (op, result, 0, 0);
2671 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2677 /*-----------------------------------------------------------------*/
2678 /* geniCodePostDec - generates code for Post decrement */
2679 /*-----------------------------------------------------------------*/
2681 geniCodePostDec (operand * op)
2685 sym_link *optype = operandType (op);
2687 operand *rv = (IS_ITEMP (op) ?
2688 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2690 sym_link *rvtype = operandType (rv);
2693 /* if this is not an address we have trouble */
2696 werror (E_LVALUE_REQUIRED, "--");
2700 rOp = newiTempOperand (rvtype, 0);
2701 OP_SYMBOL(rOp)->noSpilLoc = 1;
2704 OP_SYMBOL(rv)->noSpilLoc = 1;
2706 geniCodeAssign (rOp, rv, 0, 0);
2708 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2710 werror(W_SIZEOF_VOID);
2711 if (IS_FLOAT (rvtype))
2712 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2714 if (IS_FIXED16X16 (rvtype))
2715 ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
2717 ic = newiCode ('-', rv, operandFromLit (size));
2719 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2722 geniCodeAssign (op, result, 0, 0);
2728 /*-----------------------------------------------------------------*/
2729 /* geniCodePreDec - generate code for pre decrement */
2730 /*-----------------------------------------------------------------*/
2732 geniCodePreDec (operand * op, bool lvalue)
2735 sym_link *optype = operandType (op);
2736 operand *rop = (IS_ITEMP (op) ?
2737 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2739 sym_link *roptype = operandType (rop);
2745 werror (E_LVALUE_REQUIRED, "--");
2749 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2751 werror(W_SIZEOF_VOID);
2752 if (IS_FLOAT (roptype))
2753 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2755 if (IS_FIXED16X16 (roptype))
2756 ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
2758 ic = newiCode ('-', rop, operandFromLit (size));
2759 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2762 (void) geniCodeAssign (op, result, 0, 0);
2763 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2770 /*-----------------------------------------------------------------*/
2771 /* geniCodeBitwise - gen int code for bitWise operators */
2772 /*-----------------------------------------------------------------*/
2774 geniCodeBitwise (operand * left, operand * right,
2775 int oper, sym_link * resType)
2779 left = geniCodeCast (resType, left, TRUE);
2780 right = geniCodeCast (resType, right, TRUE);
2782 ic = newiCode (oper, left, right);
2783 IC_RESULT (ic) = newiTempOperand (resType, 0);
2786 return IC_RESULT (ic);
2789 /*-----------------------------------------------------------------*/
2790 /* geniCodeAddressOf - gens icode for '&' address of operator */
2791 /*-----------------------------------------------------------------*/
2793 geniCodeAddressOf (operand * op)
2797 sym_link *optype = operandType (op);
2798 sym_link *opetype = getSpec (optype);
2800 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2802 op = operandFromOperand (op);
2807 /* lvalue check already done in decorateType */
2808 /* this must be a lvalue */
2809 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2810 /* werror (E_LVALUE_REQUIRED,"&"); */
2814 p = newLink (DECLARATOR);
2816 /* set the pointer depending on the storage class */
2817 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2819 p->next = copyLinkChain (optype);
2821 /* if already a temp */
2824 setOperandType (op, p);
2829 /* other wise make this of the type coming in */
2830 ic = newiCode (ADDRESS_OF, op, NULL);
2831 IC_RESULT (ic) = newiTempOperand (p, 1);
2832 IC_RESULT (ic)->isaddr = 0;
2834 return IC_RESULT (ic);
2836 /*-----------------------------------------------------------------*/
2837 /* setOClass - sets the output class depending on the pointer type */
2838 /*-----------------------------------------------------------------*/
2840 setOClass (sym_link * ptr, sym_link * spec)
2842 switch (DCL_TYPE (ptr))
2845 SPEC_OCLS (spec) = data;
2849 SPEC_OCLS (spec) = generic;
2853 SPEC_OCLS (spec) = xdata;
2857 SPEC_OCLS (spec) = code;
2861 SPEC_OCLS (spec) = idata;
2865 SPEC_OCLS (spec) = xstack;
2869 SPEC_OCLS (spec) = eeprom;
2878 /*-----------------------------------------------------------------*/
2879 /* geniCodeDerefPtr - dereference pointer with '*' */
2880 /*-----------------------------------------------------------------*/
2882 geniCodeDerefPtr (operand * op,int lvl)
2884 sym_link *rtype, *retype;
2885 sym_link *optype = operandType (op);
2887 // if this is an array then array access
2888 if (IS_ARRAY (optype)) {
2889 // don't worry, this will be optimized out later
2890 return geniCodeArray (op, operandFromLit (0), lvl);
2893 // just in case someone screws up
2894 wassert (IS_PTR (optype));
2896 if (IS_TRUE_SYMOP (op))
2899 op = geniCodeRValue (op, TRUE);
2902 /* now get rid of the pointer part */
2903 if (isLvaluereq(lvl) && IS_ITEMP (op))
2905 retype = getSpec (rtype = copyLinkChain (optype));
2909 retype = getSpec (rtype = copyLinkChain (optype->next));
2910 /* outputclass needs 2b updated */
2911 setOClass (optype, retype);
2914 op->isGptr = IS_GENPTR (optype);
2916 op->isaddr = (IS_PTR (rtype) ||
2917 IS_STRUCT (rtype) ||
2923 if (!isLvaluereq(lvl))
2924 op = geniCodeRValue (op, TRUE);
2926 setOperandType (op, rtype);
2931 /*-----------------------------------------------------------------*/
2932 /* geniCodeUnaryMinus - does a unary minus of the operand */
2933 /*-----------------------------------------------------------------*/
2935 geniCodeUnaryMinus (operand * op)
2938 sym_link *optype = operandType (op);
2940 if (IS_LITERAL (optype))
2941 return operandFromLit (-floatFromVal (op->operand.valOperand));
2943 ic = newiCode (UNARYMINUS, op, NULL);
2944 IC_RESULT (ic) = newiTempOperand (optype, 0);
2946 return IC_RESULT (ic);
2949 /*-----------------------------------------------------------------*/
2950 /* geniCodeLeftShift - gen i code for left shift */
2951 /*-----------------------------------------------------------------*/
2953 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2958 ic = newiCode (LEFT_OP, left, right);
2960 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2961 IC_RESULT (ic) = newiTempOperand (resType, 0);
2963 return IC_RESULT (ic);
2966 /*-----------------------------------------------------------------*/
2967 /* geniCodeRightShift - gen i code for right shift */
2968 /*-----------------------------------------------------------------*/
2970 geniCodeRightShift (operand * left, operand * right)
2974 ic = newiCode (RIGHT_OP, left, right);
2975 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2977 return IC_RESULT (ic);
2980 /*-----------------------------------------------------------------*/
2981 /* geniCodeLogic- logic code */
2982 /*-----------------------------------------------------------------*/
2984 geniCodeLogic (operand * left, operand * right, int op)
2988 sym_link *rtype = operandType (right);
2989 sym_link *ltype = operandType (left);
2991 /* left is integral type and right is literal then
2992 check if the literal value is within bounds */
2993 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2995 checkConstantRange(ltype,
2996 OP_VALUE(right), "compare operation", 1);
2999 /* if one operand is a pointer and the other is a literal generic void pointer,
3000 change the type of the literal generic void pointer to match the other pointer */
3001 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
3002 && IS_PTR (rtype) && !IS_GENPTR(rtype))
3004 /* find left's definition */
3005 ic = (iCode *) setFirstItem (iCodeChain);
3008 if (((ic->op == CAST) || (ic->op == '='))
3009 && isOperandEqual(left, IC_RESULT (ic)))
3012 ic = setNextItem (iCodeChain);
3014 /* if casting literal to generic pointer, then cast to rtype instead */
3015 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3017 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
3018 ltype = operandType(left);
3021 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
3022 && IS_PTR (ltype) && !IS_GENPTR(ltype))
3024 /* find right's definition */
3025 ic = (iCode *) setFirstItem (iCodeChain);
3028 if (((ic->op == CAST) || (ic->op == '='))
3029 && isOperandEqual(right, IC_RESULT (ic)))
3032 ic = setNextItem (iCodeChain);
3034 /* if casting literal to generic pointer, then cast to rtype instead */
3035 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3037 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
3038 rtype = operandType(right);
3042 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
3044 ic = newiCode (op, left, right);
3045 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
3047 /* if comparing float
3048 and not a '==' || '!=' || '&&' || '||' (these
3050 if (IS_FLOAT(ctype) &&
3057 /* if comparing a fixed type use support functions */
3058 if (IS_FIXED(ctype))
3062 return IC_RESULT (ic);
3065 /*-----------------------------------------------------------------*/
3066 /* geniCodeLogicAndOr - && || operations */
3067 /*-----------------------------------------------------------------*/
3069 geniCodeLogicAndOr (ast *tree, int lvl)
3073 symbol *falseLabel = newiTempLabel (NULL);
3074 symbol *trueLabel = newiTempLabel (NULL);
3075 symbol *exitLabel = newiTempLabel (NULL);
3076 operand *op, *result, *condition;
3078 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3079 They can be reenabled by executing the following block. If you find
3080 a decent optimization you could start right here:
3085 operand *leftOp, *rightOp;
3087 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3088 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3090 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3094 /* generate two IFX for the '&&' or '||' op */
3096 /* evaluate left operand */
3097 condition = ast2iCode (tree->left, lvl + 1);
3098 op = geniCodeRValue (condition, FALSE);
3100 /* test left operand */
3101 if (tree->opval.op == AND_OP)
3102 ic = newiCodeCondition (op, NULL, falseLabel);
3104 ic = newiCodeCondition (op, trueLabel, NULL);
3107 /* evaluate right operand */
3108 condition = ast2iCode (tree->right, lvl + 1);
3109 op = geniCodeRValue (condition, FALSE);
3111 /* test right operand */
3112 ic = newiCodeCondition (op, trueLabel, NULL);
3115 /* store 0 or 1 in result */
3116 type = (SPEC_NOUN(tree->ftype) == V_BIT) ? newBoolLink() : newCharLink();
3117 result = newiTempOperand (type, 1);
3119 geniCodeLabel (falseLabel);
3120 geniCodeAssign (result, operandFromLit (0), 0, 0);
3121 /* generate an unconditional goto */
3122 geniCodeGoto (exitLabel);
3124 geniCodeLabel (trueLabel);
3125 geniCodeAssign (result, operandFromLit (1), 0, 0);
3127 geniCodeLabel (exitLabel);
3132 /*-----------------------------------------------------------------*/
3133 /* geniCodeUnary - for a generic unary operation */
3134 /*-----------------------------------------------------------------*/
3136 geniCodeUnary (operand * op, int oper)
3138 iCode *ic = newiCode (oper, op, NULL);
3140 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3142 return IC_RESULT (ic);
3145 /*-----------------------------------------------------------------*/
3146 /* geniCodeBinary - for a generic binary operation */
3147 /*-----------------------------------------------------------------*/
3149 geniCodeBinary (operand * left, operand * right, int oper)
3151 iCode *ic = newiCode (oper, left, right);
3153 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3155 return IC_RESULT (ic);
3158 /*-----------------------------------------------------------------*/
3159 /* geniCodeConditional - geniCode for '?' ':' operation */
3160 /*-----------------------------------------------------------------*/
3162 geniCodeConditional (ast * tree,int lvl)
3165 symbol *falseLabel = newiTempLabel (NULL);
3166 symbol *exitLabel = newiTempLabel (NULL);
3167 operand *cond = ast2iCode (tree->left,lvl+1);
3168 operand *true, *false, *result;
3170 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3174 true = ast2iCode (tree->right->left,lvl+1);
3176 /* move the value to a new Operand */
3177 result = newiTempOperand (tree->right->ftype, 0);
3178 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3180 /* generate an unconditional goto */
3181 geniCodeGoto (exitLabel);
3183 /* now for the right side */
3184 geniCodeLabel (falseLabel);
3186 false = ast2iCode (tree->right->right,lvl+1);
3187 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3189 /* create the exit label */
3190 geniCodeLabel (exitLabel);
3195 /*-----------------------------------------------------------------*/
3196 /* geniCodeAssign - generate code for assignment */
3197 /*-----------------------------------------------------------------*/
3199 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3202 sym_link *ltype = operandType (left);
3203 sym_link *rtype = operandType (right);
3205 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3207 werror (E_LVALUE_REQUIRED, "assignment");
3211 /* left is integral type and right is literal then
3212 check if the literal value is within bounds */
3213 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3215 checkConstantRange(ltype,
3216 OP_VALUE(right), "= operation", 0);
3219 /* if the left & right type don't exactly match */
3220 /* if pointer set then make sure the check is
3221 done with the type & not the pointer */
3222 /* then cast rights type to left */
3224 /* first check the type for pointer assignement */
3225 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3226 compareType (ltype, rtype) <= 0)
3228 if (compareType (ltype->next, rtype) < 0)
3229 right = geniCodeCast (ltype->next, right, TRUE);
3231 else if (compareType (ltype, rtype) < 0)
3232 right = geniCodeCast (ltype, right, TRUE);
3234 /* If left is a true symbol & ! volatile
3235 create an assignment to temporary for
3236 the right & then assign this temporary
3237 to the symbol. This is SSA (static single
3238 assignment). Isn't it simple and folks have
3239 published mountains of paper on it */
3240 if (IS_TRUE_SYMOP (left) &&
3241 !isOperandVolatile (left, FALSE) &&
3242 isOperandGlobal (left))
3246 if (IS_TRUE_SYMOP (right))
3247 sym = OP_SYMBOL (right);
3248 ic = newiCode ('=', NULL, right);
3249 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3250 SPIL_LOC (right) = sym;
3254 ic = newiCode ('=', NULL, right);
3255 IC_RESULT (ic) = left;
3258 /* if left isgptr flag is set then support
3259 routine will be required */
3263 ic->nosupdate = nosupdate;
3267 /*-----------------------------------------------------------------*/
3268 /* geniCodeDummyRead - generate code for dummy read */
3269 /*-----------------------------------------------------------------*/
3271 geniCodeDummyRead (operand * op)
3274 sym_link *type = operandType (op);
3276 if (!IS_VOLATILE(type))
3279 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3285 /*-----------------------------------------------------------------*/
3286 /* geniCodeSEParms - generate code for side effecting fcalls */
3287 /*-----------------------------------------------------------------*/
3289 geniCodeSEParms (ast * parms,int lvl)
3294 if (parms->type == EX_OP && parms->opval.op == PARAM)
3296 geniCodeSEParms (parms->left,lvl);
3297 geniCodeSEParms (parms->right,lvl);
3301 /* hack don't like this but too lazy to think of
3303 if (IS_ADDRESS_OF_OP (parms))
3304 parms->left->lvalue = 1;
3306 if (IS_CAST_OP (parms) &&
3307 IS_PTR (parms->ftype) &&
3308 IS_ADDRESS_OF_OP (parms->right))
3309 parms->right->left->lvalue = 1;
3311 parms->opval.oprnd =
3312 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3314 parms->type = EX_OPERAND;
3315 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3316 SPEC_ARGREG(parms->ftype);
3319 /*-----------------------------------------------------------------*/
3320 /* geniCodeParms - generates parameters */
3321 /*-----------------------------------------------------------------*/
3323 geniCodeParms (ast * parms, value *argVals, int *stack,
3324 sym_link * ftype, int lvl)
3332 if (argVals==NULL) {
3334 argVals = FUNC_ARGS (ftype);
3337 /* if this is a param node then do the left & right */
3338 if (parms->type == EX_OP && parms->opval.op == PARAM)
3340 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3341 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3345 /* get the parameter value */
3346 if (parms->type == EX_OPERAND)
3347 pval = parms->opval.oprnd;
3350 /* maybe this else should go away ?? */
3351 /* hack don't like this but too lazy to think of
3353 if (IS_ADDRESS_OF_OP (parms))
3354 parms->left->lvalue = 1;
3356 if (IS_CAST_OP (parms) &&
3357 IS_PTR (parms->ftype) &&
3358 IS_ADDRESS_OF_OP (parms->right))
3359 parms->right->left->lvalue = 1;
3361 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3364 /* if register parm then make it a send */
3365 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3366 IFFUNC_ISBUILTIN(ftype))
3368 ic = newiCode (SEND, pval, NULL);
3369 ic->argreg = SPEC_ARGREG(parms->etype);
3370 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3375 /* now decide whether to push or assign */
3376 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3380 operand *top = operandFromSymbol (argVals->sym);
3381 /* clear useDef and other bitVectors */
3382 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3383 geniCodeAssign (top, pval, 1, 0);
3387 sym_link *p = operandType (pval);
3389 ic = newiCode (IPUSH, pval, NULL);
3391 /* update the stack adjustment */
3392 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3397 argVals=argVals->next;
3401 /*-----------------------------------------------------------------*/
3402 /* geniCodeCall - generates temp code for calling */
3403 /*-----------------------------------------------------------------*/
3405 geniCodeCall (operand * left, ast * parms,int lvl)
3409 sym_link *type, *etype;
3413 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3414 !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3415 werror (E_FUNCTION_EXPECTED);
3416 return operandFromValue(valueFromLit(0));
3419 /* take care of parameters with side-effecting
3420 function calls in them, this is required to take care
3421 of overlaying function parameters */
3422 geniCodeSEParms (parms,lvl);
3424 ftype = operandType (left);
3425 if (IS_FUNCPTR (ftype))
3426 ftype = ftype->next;
3428 /* first the parameters */
3429 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3431 /* now call : if symbol then pcall */
3432 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3433 ic = newiCode (PCALL, left, NULL);
3435 ic = newiCode (CALL, left, NULL);
3438 type = copyLinkChain (ftype->next);
3439 etype = getSpec (type);
3440 SPEC_EXTR (etype) = 0;
3441 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3445 /* stack adjustment after call */
3446 ic->parmBytes = stack;
3451 /*-----------------------------------------------------------------*/
3452 /* geniCodeReceive - generate intermediate code for "receive" */
3453 /*-----------------------------------------------------------------*/
3455 geniCodeReceive (value * args, operand * func)
3457 unsigned char paramByteCounter = 0;
3459 /* for all arguments that are passed in registers */
3462 if (IS_REGPARM (args->etype))
3464 operand *opr = operandFromValue (args);
3466 symbol *sym = OP_SYMBOL (opr);
3469 /* we will use it after all optimizations
3470 and before liveRange calculation */
3471 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3474 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3475 options.stackAuto == 0 &&
3476 (!(options.model == MODEL_FLAT24)) )
3481 opl = newiTempOperand (args->type, 0);
3483 sym->reqv->key = sym->key;
3484 OP_SYMBOL (sym->reqv)->key = sym->key;
3485 OP_SYMBOL (sym->reqv)->isreqv = 1;
3486 OP_SYMBOL (sym->reqv)->islocal = 0;
3487 SPIL_LOC (sym->reqv) = sym;
3491 ic = newiCode (RECEIVE, func, NULL);
3492 ic->argreg = SPEC_ARGREG(args->etype);
3493 if (ic->argreg == 1) {
3494 currFunc->recvSize = getSize (sym->type);
3496 IC_RESULT (ic) = opr;
3498 /* misuse of parmBytes (normally used for functions)
3499 * to save estimated stack position of this argument.
3500 * Normally this should be zero for RECEIVE iCodes.
3501 * No idea if this causes side effects on other ports. - dw
3503 ic->parmBytes = paramByteCounter;
3505 /* what stack position do we have? */
3506 paramByteCounter += getSize (sym->type);
3515 /*-----------------------------------------------------------------*/
3516 /* geniCodeFunctionBody - create the function body */
3517 /*-----------------------------------------------------------------*/
3519 geniCodeFunctionBody (ast * tree,int lvl)
3526 /* reset the auto generation */
3532 func = ast2iCode (tree->left,lvl+1);
3533 fetype = getSpec (operandType (func));
3535 savelineno = lineno;
3536 lineno = OP_SYMBOL (func)->lineDef;
3537 /* create an entry label */
3538 geniCodeLabel (entryLabel);
3539 lineno = savelineno;
3541 /* create a proc icode */
3542 ic = newiCode (FUNCTION, func, NULL);
3543 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3548 /* for all parameters that are passed
3549 on registers add a "receive" */
3550 geniCodeReceive (tree->values.args, func);
3552 /* generate code for the body */
3553 ast2iCode (tree->right,lvl+1);
3555 /* create a label for return */
3556 geniCodeLabel (returnLabel);
3558 /* now generate the end proc */
3559 ic = newiCode (ENDFUNCTION, func, NULL);
3565 /*-----------------------------------------------------------------*/
3566 /* geniCodeReturn - gen icode for 'return' statement */
3567 /*-----------------------------------------------------------------*/
3569 geniCodeReturn (operand * op)
3573 /* if the operand is present force an rvalue */
3575 op = geniCodeRValue (op, FALSE);
3577 ic = newiCode (RETURN, op, NULL);
3581 /*-----------------------------------------------------------------*/
3582 /* geniCodeIfx - generates code for extended if statement */
3583 /*-----------------------------------------------------------------*/
3585 geniCodeIfx (ast * tree,int lvl)
3588 operand *condition = ast2iCode (tree->left,lvl+1);
3591 /* if condition is null then exit */
3595 condition = geniCodeRValue (condition, FALSE);
3597 cetype = getSpec (operandType (condition));
3598 /* if the condition is a literal */
3599 if (IS_LITERAL (cetype))
3601 if (floatFromVal (condition->operand.valOperand))
3603 if (tree->trueLabel)
3604 geniCodeGoto (tree->trueLabel);
3610 if (tree->falseLabel)
3611 geniCodeGoto (tree->falseLabel);
3618 if (tree->trueLabel)
3620 ic = newiCodeCondition (condition,
3625 if (tree->falseLabel)
3626 geniCodeGoto (tree->falseLabel);
3630 ic = newiCodeCondition (condition,
3637 ast2iCode (tree->right,lvl+1);
3640 /*-----------------------------------------------------------------*/
3641 /* geniCodeJumpTable - tries to create a jump table for switch */
3642 /*-----------------------------------------------------------------*/
3644 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3646 int min, max, cnt = 1;
3653 int needRangeCheck = !optimize.noJTabBoundary
3654 || tree->values.switchVals.swDefault;
3655 sym_link *cetype = getSpec (operandType (cond));
3656 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3657 int sizeofMatchJump, sizeofJumpTable;
3660 if (!tree || !caseVals)
3663 /* the criteria for creating a jump table is */
3664 /* all integer numbers between the maximum & minimum must */
3665 /* be present , the maximum value should not exceed 255 */
3666 /* If not all integer numbers are present the algorithm */
3667 /* inserts jumps to the default label for the missing numbers */
3668 /* and decides later whether it is worth it */
3669 min = (int) floatFromVal (vch = caseVals);
3676 max = (int) floatFromVal (vch);
3678 /* Exit if the range is too large to handle with a jump table. */
3679 if (1 + max - min > port->jumptableCost.maxCount)
3682 switch (getSize (operandType (cond)))
3684 case 1: sizeIndex = 0; break;
3685 case 2: sizeIndex = 1; break;
3686 case 4: sizeIndex = 2; break;
3690 /* Compute the size cost of the range check and subtraction. */
3692 sizeofZeroMinCost = 0;
3696 if (!(min==0 && IS_UNSIGNED (cetype)))
3697 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3698 if (!IS_UNSIGNED (cetype))
3699 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3700 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3703 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3705 /* If the size cost of handling a non-zero minimum exceeds the */
3706 /* cost of extending the range down to zero, then it might be */
3707 /* better to extend the range to zero. */
3708 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3709 >= (min * port->jumptableCost.sizeofElement))
3711 /* Only extend the jump table if it would still be manageable. */
3712 if (1 + max <= port->jumptableCost.maxCount)
3715 if (IS_UNSIGNED (cetype))
3718 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3722 /* Compute the total size cost of a jump table. */
3723 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3724 + port->jumptableCost.sizeofDispatch
3725 + sizeofMinCost + sizeofMaxCost;
3727 /* Compute the total size cost of a match & jump sequence */
3728 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3730 /* If the size cost of the jump table is uneconomical then exit */
3731 if (sizeofMatchJump < sizeofJumpTable)
3734 /* The jump table is preferable. */
3736 /* First, a label for the default or missing cases. */
3737 if (tree->values.switchVals.swDefault)
3739 SNPRINTF (buffer, sizeof(buffer),
3741 tree->values.switchVals.swNum);
3745 SNPRINTF (buffer, sizeof(buffer),
3747 tree->values.switchVals.swNum);
3749 falseLabel = newiTempLabel (buffer);
3751 /* Build the list of labels for the jump table. */
3753 t = (int) floatFromVal (vch);
3754 for (i=min; i<=max; i++)
3758 /* Explicit case: make a new label for it. */
3759 SNPRINTF (buffer, sizeof(buffer),
3761 tree->values.switchVals.swNum,
3763 addSet (&labels, newiTempLabel (buffer));
3766 t = (int) floatFromVal (vch);
3770 /* Implicit case: use the default label. */
3771 addSet (&labels, falseLabel);
3775 /* first we rule out the boundary conditions */
3776 /* if only optimization says so */
3779 sym_link *cetype = getSpec (operandType (cond));
3780 /* no need to check the lower bound if
3781 the condition is unsigned & minimum value is zero */
3782 if (!(min == 0 && IS_UNSIGNED (cetype)))
3784 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3785 ic = newiCodeCondition (boundary, falseLabel, NULL);
3789 /* now for upper bounds */
3790 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3791 ic = newiCodeCondition (boundary, falseLabel, NULL);
3795 /* if the min is not zero then we no make it zero */
3798 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3799 if (!IS_LITERAL(getSpec(operandType(cond))))
3800 setOperandType (cond, UCHARTYPE);
3803 /* now create the jumptable */
3804 ic = newiCode (JUMPTABLE, NULL, NULL);
3805 IC_JTCOND (ic) = cond;
3806 IC_JTLABELS (ic) = labels;
3811 /*-----------------------------------------------------------------*/
3812 /* geniCodeSwitch - changes a switch to a if statement */
3813 /*-----------------------------------------------------------------*/
3815 geniCodeSwitch (ast * tree,int lvl)
3818 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3819 value *caseVals = tree->values.switchVals.swVals;
3820 symbol *trueLabel, *falseLabel;
3822 /* If the condition is a literal, then just jump to the */
3823 /* appropriate case label. */
3824 if (IS_LITERAL(getSpec(operandType(cond))))
3826 int switchVal, caseVal;
3828 switchVal = (int) floatFromVal (cond->operand.valOperand);
3831 caseVal = (int) floatFromVal (caseVals);
3832 if (caseVal == switchVal)
3834 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3835 tree->values.switchVals.swNum, caseVal);
3836 trueLabel = newiTempLabel (buffer);
3837 geniCodeGoto (trueLabel);
3840 caseVals = caseVals->next;
3842 goto defaultOrBreak;
3845 /* If cond is volatile, it might change while we are trying to */
3846 /* find the matching case. To avoid this possibility, make a */
3847 /* non-volatile copy to use instead. */
3848 if (IS_OP_VOLATILE (cond))
3853 newcond = newiTempOperand (operandType (cond), TRUE);
3854 newcond->isvolatile = 0;
3855 ic = newiCode ('=', NULL, cond);
3856 IC_RESULT (ic) = newcond;
3861 /* if we can make this a jump table */
3862 if (geniCodeJumpTable (cond, caseVals, tree))
3863 goto jumpTable; /* no need for the comparison */
3865 /* for the cases defined do */
3869 operand *compare = geniCodeLogic (cond,
3870 operandFromValue (caseVals),
3873 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3874 tree->values.switchVals.swNum,
3875 (int) floatFromVal (caseVals));
3876 trueLabel = newiTempLabel (buffer);
3878 ic = newiCodeCondition (compare, trueLabel, NULL);
3880 caseVals = caseVals->next;
3885 /* if default is present then goto break else break */
3886 if (tree->values.switchVals.swDefault)
3888 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3892 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3895 falseLabel = newiTempLabel (buffer);
3896 geniCodeGoto (falseLabel);
3899 ast2iCode (tree->right,lvl+1);
3902 /*-----------------------------------------------------------------*/
3903 /* geniCodeInline - intermediate code for inline assembler */
3904 /*-----------------------------------------------------------------*/
3906 geniCodeInline (ast * tree)
3910 ic = newiCode (INLINEASM, NULL, NULL);
3911 IC_INLINE (ic) = tree->values.inlineasm;
3915 /*-----------------------------------------------------------------*/
3916 /* geniCodeArrayInit - intermediate code for array initializer */
3917 /*-----------------------------------------------------------------*/
3919 geniCodeArrayInit (ast * tree, operand *array)
3923 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3924 ic = newiCode (ARRAYINIT, array, NULL);
3925 IC_ARRAYILIST (ic) = tree->values.constlist;
3927 operand *left=newOperand(), *right=newOperand();
3928 left->type=right->type=SYMBOL;
3929 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3930 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3931 ic = newiCode (ARRAYINIT, left, right);
3936 /*-----------------------------------------------------------------*/
3937 /* geniCodeCritical - intermediate code for a critical statement */
3938 /*-----------------------------------------------------------------*/
3940 geniCodeCritical (ast *tree, int lvl)
3946 if (!options.stackAuto)
3948 type = newLink(SPECIFIER);
3949 SPEC_VOLATILE(type) = 1;
3950 SPEC_NOUN(type) = V_BIT;
3951 SPEC_SCLS(type) = S_BIT;
3952 SPEC_BLEN(type) = 1;
3953 SPEC_BSTR(type) = 0;
3954 op = newiTempOperand(type, 1);
3957 /* If op is NULL, the original interrupt state will saved on */
3958 /* the stack. Otherwise, it will be saved in op. */
3960 /* Generate a save of the current interrupt state & disable */
3961 ic = newiCode (CRITICAL, NULL, NULL);
3962 IC_RESULT (ic) = op;
3965 /* Generate the critical code sequence */
3966 if (tree->left && tree->left->type == EX_VALUE)
3967 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3969 ast2iCode (tree->left,lvl+1);
3971 /* Generate a restore of the original interrupt state */
3972 ic = newiCode (ENDCRITICAL, NULL, op);
3976 /*-----------------------------------------------------------------*/
3977 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3978 /* particular case. Ie : assigning or dereferencing array or ptr */
3979 /*-----------------------------------------------------------------*/
3980 set * lvaluereqSet = NULL;
3981 typedef struct lvalItem
3988 /*-----------------------------------------------------------------*/
3989 /* addLvaluereq - add a flag for lvalreq for current ast level */
3990 /*-----------------------------------------------------------------*/
3991 void addLvaluereq(int lvl)
3993 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3996 addSetHead(&lvaluereqSet,lpItem);
3999 /*-----------------------------------------------------------------*/
4000 /* delLvaluereq - del a flag for lvalreq for current ast level */
4001 /*-----------------------------------------------------------------*/
4005 lpItem = getSet(&lvaluereqSet);
4006 if(lpItem) Safe_free(lpItem);
4008 /*-----------------------------------------------------------------*/
4009 /* clearLvaluereq - clear lvalreq flag */
4010 /*-----------------------------------------------------------------*/
4011 void clearLvaluereq()
4014 lpItem = peekSet(lvaluereqSet);
4015 if(lpItem) lpItem->req = 0;
4017 /*-----------------------------------------------------------------*/
4018 /* getLvaluereq - get the last lvalreq level */
4019 /*-----------------------------------------------------------------*/
4020 int getLvaluereqLvl()
4023 lpItem = peekSet(lvaluereqSet);
4024 if(lpItem) return lpItem->lvl;
4027 /*-----------------------------------------------------------------*/
4028 /* isLvaluereq - is lvalreq valid for this level ? */
4029 /*-----------------------------------------------------------------*/
4030 int isLvaluereq(int lvl)
4033 lpItem = peekSet(lvaluereqSet);
4034 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4038 /*-----------------------------------------------------------------*/
4039 /* ast2iCode - creates an icodeList from an ast */
4040 /*-----------------------------------------------------------------*/
4042 ast2iCode (ast * tree,int lvl)
4044 operand *left = NULL;
4045 operand *right = NULL;
4049 /* set the global variables for filename & line number */
4051 filename = tree->filename;
4053 lineno = tree->lineno;
4055 block = tree->block;
4057 scopeLevel = tree->level;
4059 seqPoint = tree->seqPoint;
4061 if (tree->type == EX_VALUE)
4062 return operandFromValue (tree->opval.val);
4064 if (tree->type == EX_LINK)
4065 return operandFromLink (tree->opval.lnk);
4067 /* if we find a nullop */
4068 if (tree->type == EX_OP &&
4069 (tree->opval.op == NULLOP ||
4070 tree->opval.op == BLOCK))
4072 if (tree->left && tree->left->type == EX_VALUE)
4073 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4075 ast2iCode (tree->left,lvl+1);
4076 if (tree->right && tree->right->type == EX_VALUE)
4077 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4079 ast2iCode (tree->right,lvl+1);
4083 /* special cases for not evaluating */
4084 if (tree->opval.op != ':' &&
4085 tree->opval.op != '?' &&
4086 tree->opval.op != CALL &&
4087 tree->opval.op != IFX &&
4088 tree->opval.op != AND_OP &&
4089 tree->opval.op != OR_OP &&
4090 tree->opval.op != LABEL &&
4091 tree->opval.op != GOTO &&
4092 tree->opval.op != SWITCH &&
4093 tree->opval.op != FUNCTION &&
4094 tree->opval.op != INLINEASM &&
4095 tree->opval.op != CRITICAL)
4098 if (IS_ASSIGN_OP (tree->opval.op) ||
4099 IS_DEREF_OP (tree) ||
4100 (tree->opval.op == '&' && !tree->right) ||
4101 tree->opval.op == PTR_OP)
4104 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4105 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4108 left = operandFromAst (tree->left,lvl);
4110 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4111 left = geniCodeRValue (left, TRUE);
4115 left = operandFromAst (tree->left,lvl);
4117 if (tree->opval.op == INC_OP ||
4118 tree->opval.op == DEC_OP)
4121 right = operandFromAst (tree->right,lvl);
4126 right = operandFromAst (tree->right,lvl);
4130 /* now depending on the type of operand */
4131 /* this will be a biggy */
4132 switch (tree->opval.op)
4135 case '[': /* array operation */
4137 //sym_link *ltype = operandType (left);
4138 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4139 left = geniCodeRValue (left, FALSE);
4140 right = geniCodeRValue (right, TRUE);
4143 return geniCodeArray (left, right,lvl);
4145 case '.': /* structure dereference */
4146 if (IS_PTR (operandType (left)))
4147 left = geniCodeRValue (left, TRUE);
4149 left = geniCodeRValue (left, FALSE);
4151 return geniCodeStruct (left, right, tree->lvalue);
4153 case PTR_OP: /* structure pointer dereference */
4156 pType = operandType (left);
4157 left = geniCodeRValue (left, TRUE);
4159 setOClass (pType, getSpec (operandType (left)));
4162 return geniCodeStruct (left, right, tree->lvalue);
4164 case INC_OP: /* increment operator */
4166 return geniCodePostInc (left);
4168 return geniCodePreInc (right, tree->lvalue);
4170 case DEC_OP: /* decrement operator */
4172 return geniCodePostDec (left);
4174 return geniCodePreDec (right, tree->lvalue);
4176 case '&': /* bitwise and or address of operator */
4178 { /* this is a bitwise operator */
4179 left = geniCodeRValue (left, FALSE);
4180 right = geniCodeRValue (right, FALSE);
4181 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4184 return geniCodeAddressOf (left);
4186 case '|': /* bitwise or & xor */
4188 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4189 geniCodeRValue (right, FALSE),
4194 return geniCodeDivision (geniCodeRValue (left, FALSE),
4195 geniCodeRValue (right, FALSE),
4196 getResultTypeFromType (tree->ftype));
4199 return geniCodeModulus (geniCodeRValue (left, FALSE),
4200 geniCodeRValue (right, FALSE),
4201 getResultTypeFromType (tree->ftype));
4204 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4205 geniCodeRValue (right, FALSE),
4206 getResultTypeFromType (tree->ftype));
4208 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4212 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4213 geniCodeRValue (right, FALSE),
4214 getResultTypeFromType (tree->ftype));
4216 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4220 return geniCodeAdd (geniCodeRValue (left, FALSE),
4221 geniCodeRValue (right, FALSE),
4222 getResultTypeFromType (tree->ftype),
4225 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4228 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4229 geniCodeRValue (right, FALSE),
4230 getResultTypeFromType (tree->ftype));
4233 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4234 geniCodeRValue (right, FALSE));
4236 #if 0 // this indeed needs a second thought
4240 // let's keep this simple: get the rvalue we need
4241 op=geniCodeRValue (right, FALSE);
4242 // now cast it to whatever we want
4243 op=geniCodeCast (operandType(left), op, FALSE);
4244 // if this is going to be used as an lvalue, make it so
4250 #else // bug #604575, is it a bug ????
4251 return geniCodeCast (operandType (left),
4252 geniCodeRValue (right, FALSE), FALSE);
4257 sym_link *ltype = operandType (left);
4258 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4259 if ((SPEC_NOUN(ltype) == V_CHAR) && IS_UNSIGNED(ltype))
4261 setOperandType (op, INTTYPE);
4268 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4273 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4274 setOperandType (op, UCHARTYPE);
4281 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4282 geniCodeRValue (right, FALSE),
4284 setOperandType (op, (tree->opval.op == GETWORD) ? UINTTYPE : UCHARTYPE);
4289 return geniCodeLogicAndOr (tree, lvl);
4296 /* different compilers (even different gccs) evaluate
4297 the two calls in a different order. to get the same
4298 result on all machines we've to specify a clear sequence.
4299 return geniCodeLogic (geniCodeRValue (left, FALSE),
4300 geniCodeRValue (right, FALSE),
4304 operand *leftOp, *rightOp;
4306 leftOp = geniCodeRValue (left , FALSE);
4307 rightOp = geniCodeRValue (right, FALSE);
4309 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4312 return geniCodeConditional (tree,lvl);
4315 return operandFromLit (getSize (tree->right->ftype));
4319 sym_link *rtype = operandType (right);
4320 sym_link *ltype = operandType (left);
4321 if (IS_PTR (rtype) && IS_ITEMP (right)
4322 && right->isaddr && compareType (rtype->next, ltype) == 1)
4323 right = geniCodeRValue (right, TRUE);
4325 right = geniCodeRValue (right, FALSE);
4327 geniCodeAssign (left, right, 0, 1);
4332 geniCodeAssign (left,
4333 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4335 geniCodeRValue (right, FALSE),
4336 getResultTypeFromType (tree->ftype)),
4341 geniCodeAssign (left,
4342 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4344 geniCodeRValue (right, FALSE),
4345 getResultTypeFromType (tree->ftype)),
4349 geniCodeAssign (left,
4350 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4352 geniCodeRValue (right, FALSE),
4353 getResultTypeFromType (tree->ftype)),
4357 sym_link *rtype = operandType (right);
4358 sym_link *ltype = operandType (left);
4359 if (IS_PTR (rtype) && IS_ITEMP (right)
4360 && right->isaddr && compareType (rtype->next, ltype) == 1)
4361 right = geniCodeRValue (right, TRUE);
4363 right = geniCodeRValue (right, FALSE);
4366 return geniCodeAssign (left,
4367 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4370 getResultTypeFromType (tree->ftype),
4376 sym_link *rtype = operandType (right);
4377 sym_link *ltype = operandType (left);
4378 if (IS_PTR (rtype) && IS_ITEMP (right)
4379 && right->isaddr && compareType (rtype->next, ltype) == 1)
4381 right = geniCodeRValue (right, TRUE);
4385 right = geniCodeRValue (right, FALSE);
4388 geniCodeAssign (left,
4389 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4392 getResultTypeFromType (tree->ftype)),
4397 geniCodeAssign (left,
4398 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4400 geniCodeRValue (right, FALSE),
4401 getResultTypeFromType (tree->ftype)),
4405 geniCodeAssign (left,
4406 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4408 geniCodeRValue (right, FALSE)), 0, 1);
4411 geniCodeAssign (left,
4412 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4414 geniCodeRValue (right, FALSE),
4416 operandType (left)), 0, 1);
4419 geniCodeAssign (left,
4420 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4422 geniCodeRValue (right, FALSE),
4424 operandType (left)), 0, 1);
4427 geniCodeAssign (left,
4428 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4430 geniCodeRValue (right, FALSE),
4432 operandType (left)), 0, 1);
4434 return geniCodeRValue (right, FALSE);
4437 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4440 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4441 return ast2iCode (tree->right,lvl+1);
4444 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4445 return ast2iCode (tree->right,lvl+1);
4448 geniCodeFunctionBody (tree,lvl);
4452 geniCodeReturn (right);
4456 geniCodeIfx (tree,lvl);
4460 geniCodeSwitch (tree,lvl);
4464 geniCodeInline (tree);
4468 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4472 geniCodeCritical (tree, lvl);
4478 /*-----------------------------------------------------------------*/
4479 /* reverseICChain - gets from the list and creates a linkedlist */
4480 /*-----------------------------------------------------------------*/
4487 while ((loop = getSet (&iCodeChain)))
4499 /*-----------------------------------------------------------------*/
4500 /* iCodeFromAst - given an ast will convert it to iCode */
4501 /*-----------------------------------------------------------------*/
4503 iCodeFromAst (ast * tree)
4505 returnLabel = newiTempLabel ("_return");
4506 entryLabel = newiTempLabel ("_entry");
4508 return reverseiCChain ();
4511 static const char *opTypeToStr(OPTYPE op)
4515 case SYMBOL: return "symbol";
4516 case VALUE: return "value";
4517 case TYPE: return "type";
4519 return "undefined type";
4523 operand *validateOpType(operand *op,
4530 if (op && op->type == type)
4535 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4536 " expected %s, got %s\n",
4537 macro, args, file, line,
4538 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4540 return op; // never reached, makes compiler happy.