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 else 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 /* isOperandInPagedSpace - return true if operand is in pagedSpace */
994 /*-----------------------------------------------------------------*/
996 isOperandInPagedSpace (operand * op)
1006 if (!IS_TRUE_SYMOP (op))
1009 etype = SPIL_LOC (op)->etype;
1015 etype = getSpec (operandType (op));
1017 return (IN_PAGEDSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1020 /*------------------------------------------------------------------*/
1021 /* isOperandInDirSpace - will return true if operand is in dirSpace */
1022 /*------------------------------------------------------------------*/
1024 isOperandInDirSpace (operand * op)
1034 if (!IS_TRUE_SYMOP (op))
1037 etype = SPIL_LOC (op)->etype;
1043 etype = getSpec (operandType (op));
1045 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1048 /*--------------------------------------------------------------------*/
1049 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
1050 /*--------------------------------------------------------------------*/
1052 isOperandInCodeSpace (operand * op)
1062 etype = getSpec (operandType (op));
1064 if (!IS_TRUE_SYMOP (op))
1067 etype = SPIL_LOC (op)->etype;
1073 etype = getSpec (operandType (op));
1075 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1078 /*-----------------------------------------------------------------*/
1079 /* isOperandOnStack - will return true if operand is on stack */
1080 /*-----------------------------------------------------------------*/
1082 isOperandOnStack (operand * op)
1092 etype = getSpec (operandType (op));
1093 if (IN_STACK (etype) ||
1094 OP_SYMBOL(op)->onStack ||
1095 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1101 /*-----------------------------------------------------------------*/
1102 /* isOclsExpensive - will return true if accesses to an output */
1103 /* storage class are expensive */
1104 /*-----------------------------------------------------------------*/
1106 isOclsExpensive (struct memmap *oclass)
1108 if (port->oclsExpense)
1109 return port->oclsExpense (oclass) > 0;
1111 /* In the absence of port specific guidance, assume only */
1112 /* farspace is expensive. */
1113 return IN_FARSPACE (oclass);
1116 /*-----------------------------------------------------------------*/
1117 /* isiCodeInFunctionCall - return TRUE if an iCode is between a */
1118 /* CALL/PCALL and the first IPUSH/SEND associated with the call */
1119 /*-----------------------------------------------------------------*/
1121 isiCodeInFunctionCall (iCode * ic)
1125 /* Find the next CALL/PCALL */
1128 if (lic->op == CALL || lic->op == PCALL)
1136 /* A function call was found. Scan backwards and see if an */
1137 /* IPUSH or SEND is encountered */
1140 if (lic != ic && (ic->op == CALL || ic->op == PCALL))
1142 if (ic->op == SEND || (ic->op == IPUSH && ic->parmPush))
1150 /*-----------------------------------------------------------------*/
1151 /* operandLitValue - literal value of an operand */
1152 /*-----------------------------------------------------------------*/
1154 operandLitValue (operand * op)
1156 assert (isOperandLiteral (op));
1158 return floatFromVal (op->operand.valOperand);
1161 /*-----------------------------------------------------------------*/
1162 /* getBuiltInParms - returns parameters to a builtin functions */
1163 /*-----------------------------------------------------------------*/
1164 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1169 /* builtin functions uses only SEND for parameters */
1170 while (ic->op != CALL) {
1171 assert(ic->op == SEND && ic->builtinSEND);
1172 ic->generated = 1; /* mark the icode as generated */
1173 parms[*pcount] = IC_LEFT(ic);
1179 /* make sure this is a builtin function call */
1180 assert(IS_SYMOP(IC_LEFT(ic)));
1181 ftype = operandType(IC_LEFT(ic));
1182 assert(IFFUNC_ISBUILTIN(ftype));
1186 /*-----------------------------------------------------------------*/
1187 /* operandOperation - performs operations on operands */
1188 /*-----------------------------------------------------------------*/
1190 operandOperation (operand * left, operand * right,
1191 int op, sym_link * type)
1193 sym_link *let , *ret=NULL;
1194 operand *retval = (operand *) 0;
1196 assert (isOperandLiteral (left));
1197 let = getSpec(operandType(left));
1199 assert (isOperandLiteral (right));
1200 ret = getSpec(operandType(right));
1206 retval = operandFromValue (valCastLiteral (type,
1207 operandLitValue (left) +
1208 operandLitValue (right)));
1211 retval = operandFromValue (valCastLiteral (type,
1212 operandLitValue (left) -
1213 operandLitValue (right)));
1217 retval = operandFromValue (valCastLiteral (type,
1218 operandLitValue (left) *
1219 operandLitValue (right)));
1220 This could be all we've to do, but with gcc we've to take care about
1221 overflows. Two examples:
1222 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1223 significant bits are lost (52 in fraction, 63 bits would be
1224 necessary to keep full precision).
1225 If the resulting double value is greater than ULONG_MAX (resp.
1226 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1229 /* if it is not a specifier then we can assume that */
1230 /* it will be an unsigned long */
1231 if (IS_INT (type) ||
1234 /* long is handled here, because it can overflow with double */
1235 if (IS_LONG (type) ||
1237 /* signed and unsigned mul are the same, as long as the precision
1238 of the result isn't bigger than the precision of the operands. */
1239 retval = operandFromValue (valCastLiteral (type,
1240 (TYPE_UDWORD) operandLitValue (left) *
1241 (TYPE_UDWORD) operandLitValue (right)));
1242 else if (IS_UNSIGNED (type)) /* unsigned int */
1244 /* unsigned int is handled here in order to detect overflow */
1245 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1246 (TYPE_UWORD) operandLitValue (right);
1248 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1249 if (ul != (TYPE_UWORD) ul)
1252 else /* signed int */
1254 /* signed int is handled here in order to detect overflow */
1255 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1256 (TYPE_WORD) operandLitValue (right);
1258 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1259 if (l != (TYPE_WORD) l)
1264 /* all others go here: */
1265 retval = operandFromValue (valCastLiteral (type,
1266 operandLitValue (left) *
1267 operandLitValue (right)));
1270 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1272 werror (E_DIVIDE_BY_ZERO);
1278 if (IS_UNSIGNED (type))
1280 SPEC_USIGN (let) = 1;
1281 SPEC_USIGN (ret) = 1;
1282 retval = operandFromValue (valCastLiteral (type,
1283 (TYPE_UDWORD) operandLitValue (left) /
1284 (TYPE_UDWORD) operandLitValue (right)));
1288 retval = operandFromValue (valCastLiteral (type,
1289 operandLitValue (left) /
1290 operandLitValue (right)));
1295 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1297 werror (E_DIVIDE_BY_ZERO);
1302 if (IS_UNSIGNED (type))
1303 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1304 (TYPE_UDWORD) operandLitValue (right));
1306 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1307 (TYPE_DWORD) operandLitValue (right));
1311 /* The number of left shifts is always unsigned. Signed doesn't make
1312 sense here. Shifting by a negative number is impossible. */
1313 retval = operandFromValue (valCastLiteral (type,
1314 ((TYPE_UDWORD) operandLitValue (left) <<
1315 (TYPE_UDWORD) operandLitValue (right))));
1318 /* The number of right shifts is always unsigned. Signed doesn't make
1319 sense here. Shifting by a negative number is impossible. */
1320 if (IS_UNSIGNED(let))
1321 /* unsigned: logic shift right */
1322 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1323 (TYPE_UDWORD) operandLitValue (right));
1325 /* signed: arithmetic shift right */
1326 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1327 (TYPE_UDWORD) operandLitValue (right));
1330 if (IS_FLOAT (let) || IS_FLOAT (ret))
1332 retval = operandFromLit (operandLitValue (left) ==
1333 operandLitValue (right));
1335 else if (IS_FIXED16X16 (let) || IS_FIXED16X16 (ret))
1337 retval = operandFromLit (operandLitValue (left) ==
1338 operandLitValue (right));
1342 /* this op doesn't care about signedness */
1345 l = (TYPE_UDWORD) operandLitValue (left);
1346 r = (TYPE_UDWORD) operandLitValue (right);
1347 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1348 neccessary to strip them to 16 bit.
1349 Literals are reduced to their cheapest type, therefore left and
1350 right might have different types. It's neccessary to find a
1351 common type: int (used for char too) or long */
1352 if (!IS_LONG (let) &&
1358 retval = operandFromLit (l == r);
1362 retval = operandFromLit (operandLitValue (left) <
1363 operandLitValue (right));
1366 retval = operandFromLit (operandLitValue (left) <=
1367 operandLitValue (right));
1370 retval = operandFromLit (operandLitValue (left) !=
1371 operandLitValue (right));
1374 retval = operandFromLit (operandLitValue (left) >
1375 operandLitValue (right));
1378 retval = operandFromLit (operandLitValue (left) >=
1379 operandLitValue (right));
1382 retval = operandFromValue (valCastLiteral (type,
1383 (TYPE_UDWORD)operandLitValue(left) &
1384 (TYPE_UDWORD)operandLitValue(right)));
1387 retval = operandFromValue (valCastLiteral (type,
1388 (TYPE_UDWORD)operandLitValue(left) |
1389 (TYPE_UDWORD)operandLitValue(right)));
1392 retval = operandFromValue (valCastLiteral (type,
1393 (TYPE_UDWORD)operandLitValue(left) ^
1394 (TYPE_UDWORD)operandLitValue(right)));
1397 retval = operandFromLit (operandLitValue (left) &&
1398 operandLitValue (right));
1401 retval = operandFromLit (operandLitValue (left) ||
1402 operandLitValue (right));
1406 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1408 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1414 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1416 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1421 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1422 (TYPE_UDWORD)operandLitValue(right)) & 1);
1425 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1426 (TYPE_UDWORD)operandLitValue(right)) & 0xFF);
1429 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1430 (TYPE_UDWORD)operandLitValue(right)) & 0xFFFF);
1434 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1435 ((getSize (let) * 8) - 1)) & 1);
1439 retval = operandFromValue (valCastLiteral (type,
1440 -1 * operandLitValue (left)));
1444 retval = operandFromValue (valCastLiteral (type,
1446 operandLitValue (left))));
1450 retval = operandFromLit (!operandLitValue (left));
1454 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1455 " operandOperation invalid operator ");
1463 /*-----------------------------------------------------------------*/
1464 /* isOperandEqual - compares two operand & return 1 if they r = */
1465 /*-----------------------------------------------------------------*/
1467 isOperandEqual (operand * left, operand * right)
1469 /* if the pointers are equal then they are equal */
1473 /* if either of them null then false */
1474 if (!left || !right)
1477 if (left->type != right->type)
1480 if (IS_SYMOP (left) && IS_SYMOP (right))
1481 return left->key == right->key;
1483 /* if types are the same */
1487 return isSymbolEqual (left->operand.symOperand,
1488 right->operand.symOperand);
1490 return (compareType (left->operand.valOperand->type,
1491 right->operand.valOperand->type) &&
1492 (floatFromVal (left->operand.valOperand) ==
1493 floatFromVal (right->operand.valOperand)));
1495 if (compareType (left->operand.typeOperand,
1496 right->operand.typeOperand) == 1)
1503 /*-------------------------------------------------------------------*/
1504 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1505 /*-------------------------------------------------------------------*/
1507 isiCodeEqual (iCode * left, iCode * right)
1509 /* if the same pointer */
1513 /* if either of them null */
1514 if (!left || !right)
1517 /* if operand are the same */
1518 if (left->op == right->op)
1521 /* compare all the elements depending on type */
1522 if (left->op != IFX)
1524 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1526 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1532 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1534 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1536 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1545 /*-----------------------------------------------------------------*/
1546 /* newiTempFromOp - create a temp Operand with same attributes */
1547 /*-----------------------------------------------------------------*/
1549 newiTempFromOp (operand * op)
1559 nop = newiTempOperand (operandType (op), TRUE);
1560 nop->isaddr = op->isaddr;
1561 nop->isvolatile = op->isvolatile;
1562 nop->isGlobal = op->isGlobal;
1563 nop->isLiteral = op->isLiteral;
1564 nop->usesDefs = op->usesDefs;
1565 nop->isParm = op->isParm;
1569 /*-----------------------------------------------------------------*/
1570 /* operand from operand - creates an operand holder for the type */
1571 /*-----------------------------------------------------------------*/
1573 operandFromOperand (operand * op)
1579 nop = newOperand ();
1580 nop->type = op->type;
1581 nop->isaddr = op->isaddr;
1583 nop->isvolatile = op->isvolatile;
1584 nop->isGlobal = op->isGlobal;
1585 nop->isLiteral = op->isLiteral;
1586 nop->usesDefs = op->usesDefs;
1587 nop->isParm = op->isParm;
1592 nop->operand.symOperand = op->operand.symOperand;
1595 nop->operand.valOperand = op->operand.valOperand;
1598 nop->operand.typeOperand = op->operand.typeOperand;
1605 /*-----------------------------------------------------------------*/
1606 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1607 /*-----------------------------------------------------------------*/
1609 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1611 operand *nop = operandFromOperand (op);
1613 if (nop->type == SYMBOL)
1615 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1616 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1622 /*-----------------------------------------------------------------*/
1623 /* operandFromSymbol - creates an operand from a symbol */
1624 /*-----------------------------------------------------------------*/
1626 operandFromSymbol (symbol * sym)
1631 /* if the symbol's type is a literal */
1632 /* then it is an enumerator type */
1633 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1634 return operandFromValue (valFromType (sym->etype));
1637 sym->key = ++operandKey;
1639 /* if this an implicit variable, means struct/union */
1640 /* member so just return it */
1641 if (sym->implicit || IS_FUNC (sym->type))
1645 op->operand.symOperand = sym;
1647 op->isvolatile = isOperandVolatile (op, TRUE);
1648 op->isGlobal = isOperandGlobal (op);
1652 /* under the following conditions create a
1653 register equivalent for a local symbol */
1654 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1655 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1657 (!(options.model == MODEL_FLAT24)) ) &&
1658 options.stackAuto == 0)
1661 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1662 !IS_FUNC (sym->type) && /* not a function */
1663 !sym->_isparm && /* not a parameter */
1664 IS_AUTO (sym) && /* is a local auto variable */
1665 !sym->addrtaken && /* whose address has not been taken */
1666 !sym->reqv && /* does not already have a reg equivalence */
1667 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1668 !sym->islbl && /* not a label */
1669 ok /* farspace check */
1673 /* we will use it after all optimizations
1674 and before liveRange calculation */
1675 sym->reqv = newiTempOperand (sym->type, 0);
1676 sym->reqv->key = sym->key;
1677 OP_SYMBOL (sym->reqv)->prereqv = sym;
1678 OP_SYMBOL (sym->reqv)->key = sym->key;
1679 OP_SYMBOL (sym->reqv)->isreqv = 1;
1680 OP_SYMBOL (sym->reqv)->islocal = 1;
1681 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1682 SPIL_LOC (sym->reqv) = sym;
1685 if (!IS_AGGREGATE (sym->type))
1689 op->operand.symOperand = sym;
1692 op->isvolatile = isOperandVolatile (op, TRUE);
1693 op->isGlobal = isOperandGlobal (op);
1694 op->isPtr = IS_PTR (operandType (op));
1695 op->isParm = sym->_isparm;
1700 /* itemp = &[_symbol] */
1702 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1703 IC_LEFT (ic)->type = SYMBOL;
1704 IC_LEFT (ic)->operand.symOperand = sym;
1705 IC_LEFT (ic)->key = sym->key;
1706 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1707 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1708 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1711 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1712 if (IS_ARRAY (sym->type))
1714 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1715 IC_RESULT (ic)->isaddr = 0;
1718 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1722 return IC_RESULT (ic);
1725 /*-----------------------------------------------------------------*/
1726 /* operandFromValue - creates an operand from value */
1727 /*-----------------------------------------------------------------*/
1729 operandFromValue (value * val)
1733 /* if this is a symbol then do the symbol thing */
1735 return operandFromSymbol (val->sym);
1737 /* this is not a symbol */
1740 op->operand.valOperand = val;
1741 op->isLiteral = isOperandLiteral (op);
1745 /*-----------------------------------------------------------------*/
1746 /* operandFromLink - operand from typeChain */
1747 /*-----------------------------------------------------------------*/
1749 operandFromLink (sym_link * type)
1753 /* operand from sym_link */
1759 op->operand.typeOperand = copyLinkChain (type);
1763 /*-----------------------------------------------------------------*/
1764 /* operandFromLit - makes an operand from a literal value */
1765 /*-----------------------------------------------------------------*/
1767 operandFromLit (double i)
1769 return operandFromValue (valueFromLit (i));
1772 /*-----------------------------------------------------------------*/
1773 /* operandFromAst - creates an operand from an ast */
1774 /*-----------------------------------------------------------------*/
1776 operandFromAst (ast * tree,int lvl)
1782 /* depending on type do */
1786 return ast2iCode (tree,lvl+1);
1790 return operandFromValue (tree->opval.val);
1794 return operandFromLink (tree->opval.lnk);
1801 /* Just to keep the compiler happy */
1802 return (operand *) 0;
1805 /*-----------------------------------------------------------------*/
1806 /* setOperandType - sets the operand's type to the given type */
1807 /*-----------------------------------------------------------------*/
1809 setOperandType (operand * op, sym_link * type)
1811 /* depending on the type of operand */
1816 op->operand.valOperand->etype =
1817 getSpec (op->operand.valOperand->type =
1818 copyLinkChain (type));
1822 if (op->operand.symOperand->isitmp)
1823 op->operand.symOperand->etype =
1824 getSpec (op->operand.symOperand->type =
1825 copyLinkChain (type));
1827 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1828 "attempt to modify type of source");
1832 op->operand.typeOperand = copyLinkChain (type);
1838 /*-----------------------------------------------------------------*/
1839 /* Get size in byte of ptr need to access an array */
1840 /*-----------------------------------------------------------------*/
1842 getArraySizePtr (operand * op)
1844 sym_link *ltype = operandType(op);
1848 int size = getSize(ltype);
1849 return((IS_GENPTR(ltype) && GPTRSIZE > FPTRSIZE) ? (size-1) : size);
1854 sym_link *letype = getSpec(ltype);
1855 switch (PTR_TYPE (SPEC_OCLS (letype)))
1867 if (GPTRSIZE > FPTRSIZE)
1868 return (GPTRSIZE-1);
1879 /*-----------------------------------------------------------------*/
1880 /* perform "usual unary conversions" */
1881 /*-----------------------------------------------------------------*/
1884 usualUnaryConversions (operand * op)
1886 if (IS_INTEGRAL (operandType (op)))
1888 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1891 return geniCodeCast (INTTYPE, op, TRUE);
1898 /*-----------------------------------------------------------------*/
1899 /* perform "usual binary conversions" */
1900 /*-----------------------------------------------------------------*/
1903 usualBinaryConversions (operand ** op1, operand ** op2,
1904 RESULT_TYPE resultType, int op)
1907 sym_link *rtype = operandType (*op2);
1908 sym_link *ltype = operandType (*op1);
1910 ctype = computeType (ltype, rtype, resultType, op);
1917 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1919 /* one byte operations: keep signedness for code generator */
1927 *op1 = geniCodeCast (ctype, *op1, TRUE);
1928 *op2 = geniCodeCast (ctype, *op2, TRUE);
1933 /*-----------------------------------------------------------------*/
1934 /* geniCodeValueAtAddress - generate intermeditate code for value */
1936 /*-----------------------------------------------------------------*/
1938 geniCodeRValue (operand * op, bool force)
1941 sym_link *type = operandType (op);
1942 sym_link *etype = getSpec (type);
1944 /* if this is an array & already */
1945 /* an address then return this */
1946 if (IS_AGGREGATE (type) ||
1947 (IS_PTR (type) && !force && !op->isaddr))
1948 return operandFromOperand (op);
1950 /* if this is not an address then must be */
1951 /* rvalue already so return this one */
1955 /* if this is not a temp symbol then */
1956 if (!IS_ITEMP (op) &&
1958 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1960 op = operandFromOperand (op);
1965 if (IS_SPEC (type) &&
1966 IS_TRUE_SYMOP (op) &&
1967 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1968 (options.model == MODEL_FLAT24) ))
1970 op = operandFromOperand (op);
1975 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1976 if (IS_PTR (type) && op->isaddr && force)
1979 type = copyLinkChain (type);
1981 IC_RESULT (ic) = newiTempOperand (type, 1);
1982 IC_RESULT (ic)->isaddr = 0;
1984 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1988 return IC_RESULT (ic);
1991 /*-----------------------------------------------------------------*/
1992 /* geniCodeCast - changes the value from one type to another */
1993 /*-----------------------------------------------------------------*/
1995 geniCodeCast (sym_link * type, operand * op, bool implicit)
1999 sym_link *opetype = getSpec (optype = operandType (op));
2003 /* one of them has size zero then error */
2004 if (IS_VOID (optype))
2006 werror (E_CAST_ZERO);
2010 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
2012 geniCodeArray2Ptr (op);
2016 /* if the operand is already the desired type then do nothing */
2017 if (compareType (type, optype) == 1)
2020 /* if this is a literal then just change the type & return */
2021 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
2023 return operandFromValue (valCastLiteral (type,
2024 operandLitValue (op)));
2027 /* if casting to/from pointers, do some checking */
2028 if (IS_PTR(type)) { // to a pointer
2029 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
2030 if (IS_INTEGRAL(optype)) {
2031 // maybe this is NULL, than it's ok.
2032 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
2033 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
2034 // no way to set the storage
2035 if (IS_LITERAL(optype)) {
2036 werror(E_LITERAL_GENERIC);
2039 werror(E_NONPTR2_GENPTR);
2042 } else if (implicit) {
2043 werror(W_INTEGRAL2PTR_NOCAST);
2048 // shouldn't do that with float, array or structure unless to void
2049 if (!IS_VOID(getSpec(type)) &&
2050 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2051 werror(E_INCOMPAT_TYPES);
2055 } else { // from a pointer to a pointer
2056 if (IS_GENPTR(type) && IS_VOID(type->next))
2057 { // cast to void* is always allowed
2059 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
2060 { // cast from void* is always allowed
2062 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2063 // if not a pointer to a function
2064 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2065 if (implicit) { // if not to generic, they have to match
2066 if (!IS_GENPTR(type) &&
2067 !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
2068 ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
2072 werror(E_INCOMPAT_PTYPES);
2079 } else { // to a non pointer
2080 if (IS_PTR(optype)) { // from a pointer
2081 if (implicit) { // sneaky
2082 if (IS_INTEGRAL(type)) {
2083 werror(W_PTR2INTEGRAL_NOCAST);
2085 } else { // shouldn't do that with float, array or structure
2086 werror(E_INCOMPAT_TYPES);
2093 printFromToType (optype, type);
2096 /* if they are the same size create an assignment */
2098 /* This seems very dangerous to me, since there are several */
2099 /* optimizations (for example, gcse) that don't notice the */
2100 /* cast hidden in this assignement and may simplify an */
2101 /* iCode to use the original (uncasted) operand. */
2102 /* Unfortunately, other things break when this cast is */
2103 /* made explicit. Need to fix this someday. */
2104 /* -- EEP, 2004/01/21 */
2105 if (getSize (type) == getSize (optype) &&
2106 !IS_BITFIELD (type) &&
2108 !IS_FLOAT (optype) &&
2110 !IS_FIXED (optype) &&
2111 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2112 (!IS_SPEC (type) && !IS_SPEC (optype))))
2114 ic = newiCode ('=', NULL, op);
2115 IC_RESULT (ic) = newiTempOperand (type, 0);
2116 if (IS_TRUE_SYMOP (op) && !IS_VOLATILE (optype))
2117 SPIL_LOC (IC_RESULT (ic)) = OP_SYMBOL (op);
2118 IC_RESULT (ic)->isaddr = 0;
2122 ic = newiCode (CAST, operandFromLink (type),
2123 geniCodeRValue (op, FALSE));
2125 IC_RESULT (ic) = newiTempOperand (type, 0);
2128 /* preserve the storage class & output class */
2129 /* of the original variable */
2130 restype = getSpec (operandType (IC_RESULT (ic)));
2131 if (!IS_LITERAL(opetype) &&
2134 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2135 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2138 return IC_RESULT (ic);
2141 /*-----------------------------------------------------------------*/
2142 /* geniCodeLabel - will create a Label */
2143 /*-----------------------------------------------------------------*/
2145 geniCodeLabel (symbol * label)
2149 ic = newiCodeLabelGoto (LABEL, label);
2153 /*-----------------------------------------------------------------*/
2154 /* geniCodeGoto - will create a Goto */
2155 /*-----------------------------------------------------------------*/
2157 geniCodeGoto (symbol * label)
2161 ic = newiCodeLabelGoto (GOTO, label);
2165 /*-----------------------------------------------------------------*/
2166 /* geniCodeMultiply - gen intermediate code for multiplication */
2167 /*-----------------------------------------------------------------*/
2169 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2176 /* if they are both literal then we know the result */
2177 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2178 return operandFromValue (valMult (left->operand.valOperand,
2179 right->operand.valOperand));
2181 if (IS_LITERAL(retype)) {
2182 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2185 resType = usualBinaryConversions (&left, &right, resultType, '*');
2187 rtype = operandType (right);
2188 retype = getSpec (rtype);
2189 ltype = operandType (left);
2190 letype = getSpec (ltype);
2193 /* if the right is a literal & power of 2 */
2194 /* then make it a left shift */
2195 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2196 efficient in most cases than 2 bytes result = 2 bytes << literal
2197 if port has 1 byte muldiv */
2198 if ((p2 > 0) && !IS_FLOAT (letype) && !IS_FIXED (letype)
2199 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2200 && (port->support.muldiv == 1))
2201 && strcmp (port->target, "pic16") != 0 /* don't shift for pic */
2202 && strcmp (port->target, "pic14") != 0)
2204 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2206 /* LEFT_OP need same size for left and result, */
2207 left = geniCodeCast (resType, left, TRUE);
2208 ltype = operandType (left);
2210 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2214 ic = newiCode ('*', left, right); /* normal multiplication */
2215 /* if the size left or right > 1 then support routine */
2216 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2220 IC_RESULT (ic) = newiTempOperand (resType, 1);
2223 return IC_RESULT (ic);
2226 /*-----------------------------------------------------------------*/
2227 /* geniCodeDivision - gen intermediate code for division */
2228 /*-----------------------------------------------------------------*/
2230 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2235 sym_link *rtype = operandType (right);
2236 sym_link *retype = getSpec (rtype);
2237 sym_link *ltype = operandType (left);
2238 sym_link *letype = getSpec (ltype);
2240 resType = usualBinaryConversions (&left, &right, resultType, '/');
2242 /* if the right is a literal & power of 2
2243 and left is unsigned then make it a
2245 if (IS_LITERAL (retype) &&
2246 !IS_FLOAT (letype) &&
2247 !IS_FIXED (letype) &&
2248 IS_UNSIGNED(letype) &&
2249 ((p2 = powof2 ((TYPE_UDWORD)
2250 floatFromVal (right->operand.valOperand))) > 0)) {
2251 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2255 ic = newiCode ('/', left, right); /* normal division */
2256 /* if the size left or right > 1 then support routine */
2257 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2260 IC_RESULT (ic) = newiTempOperand (resType, 0);
2263 return IC_RESULT (ic);
2265 /*-----------------------------------------------------------------*/
2266 /* geniCodeModulus - gen intermediate code for modulus */
2267 /*-----------------------------------------------------------------*/
2269 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2275 /* if they are both literal then we know the result */
2276 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2277 return operandFromValue (valMod (left->operand.valOperand,
2278 right->operand.valOperand));
2280 resType = usualBinaryConversions (&left, &right, resultType, '%');
2282 /* now they are the same size */
2283 ic = newiCode ('%', left, right);
2285 /* if the size left or right > 1 then support routine */
2286 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2288 IC_RESULT (ic) = newiTempOperand (resType, 0);
2291 return IC_RESULT (ic);
2294 /*-----------------------------------------------------------------*/
2295 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2296 /*-----------------------------------------------------------------*/
2298 geniCodePtrPtrSubtract (operand * left, operand * right)
2304 /* if they are both literals then */
2305 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2307 result = operandFromValue (valMinus (left->operand.valOperand,
2308 right->operand.valOperand));
2312 ic = newiCode ('-', left, right);
2314 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2318 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2322 // should we really do this? is this ANSI?
2323 return geniCodeDivision (result,
2324 operandFromLit (getSize (ltype->next)),
2328 /*-----------------------------------------------------------------*/
2329 /* geniCodeSubtract - generates code for subtraction */
2330 /*-----------------------------------------------------------------*/
2332 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2339 /* if they both pointers then */
2340 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2341 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2342 return geniCodePtrPtrSubtract (left, right);
2344 /* if they are both literal then we know the result */
2345 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2346 && left->isLiteral && right->isLiteral)
2347 return operandFromValue (valMinus (left->operand.valOperand,
2348 right->operand.valOperand));
2350 /* if left is an array or pointer */
2351 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2353 isarray = left->isaddr;
2354 right = geniCodeMultiply (right,
2355 operandFromLit (getSize (ltype->next)),
2356 (getArraySizePtr(left) >= INTSIZE) ?
2359 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2362 { /* make them the same size */
2363 resType = usualBinaryConversions (&left, &right, resultType, '-');
2366 ic = newiCode ('-', left, right);
2368 IC_RESULT (ic) = newiTempOperand (resType, 1);
2369 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2371 /* if left or right is a float */
2372 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2373 || IS_FIXED (ltype) || IS_FIXED (rtype))
2377 return IC_RESULT (ic);
2380 /*-----------------------------------------------------------------*/
2381 /* geniCodeAdd - generates iCode for addition */
2382 /*-----------------------------------------------------------------*/
2384 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2393 /* if the right side is LITERAL zero */
2394 /* return the left side */
2395 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2398 /* if left is literal zero return right */
2399 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2402 /* if left is a pointer then size */
2403 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2405 isarray = left->isaddr;
2406 // there is no need to multiply with 1
2407 if (getSize (ltype->next) != 1)
2409 size = operandFromLit (getSize (ltype->next));
2410 SPEC_USIGN (getSpec (operandType (size))) = 1;
2411 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2412 right = geniCodeMultiply (right,
2414 (getArraySizePtr(left) >= INTSIZE) ?
2417 /* Even if right is a 'unsigned char',
2418 the result will be a 'signed int' due to the promotion rules.
2419 It doesn't make sense when accessing arrays, so let's fix it here: */
2421 SPEC_USIGN (getSpec (operandType (right))) = 1;
2423 resType = copyLinkChain (ltype);
2426 { // make them the same size
2427 resType = usualBinaryConversions (&left, &right, resultType, '+');
2430 /* if they are both literals then we know */
2431 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2432 && left->isLiteral && right->isLiteral)
2433 return operandFromValue (valPlus (valFromType (ltype),
2434 valFromType (rtype)));
2436 ic = newiCode ('+', left, right);
2438 IC_RESULT (ic) = newiTempOperand (resType, 1);
2439 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2441 /* if left or right is a float then support
2443 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2444 || IS_FIXED (ltype) || IS_FIXED (rtype))
2449 return IC_RESULT (ic);
2453 /*-----------------------------------------------------------------*/
2454 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2455 /*-----------------------------------------------------------------*/
2457 aggrToPtr (sym_link * type, bool force)
2462 if (IS_PTR (type) && !force)
2465 etype = getSpec (type);
2466 ptype = newLink (DECLARATOR);
2470 /* set the pointer depending on the storage class */
2471 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2475 /*------------------------------------------------------------------*/
2476 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2477 /*------------------------------------------------------------------*/
2479 aggrToPtrDclType (sym_link * type, bool force)
2481 if (IS_PTR (type) && !force)
2482 return DCL_TYPE (type);
2484 /* return the pointer depending on the storage class */
2485 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2488 /*-----------------------------------------------------------------*/
2489 /* geniCodeArray2Ptr - array to pointer */
2490 /*-----------------------------------------------------------------*/
2492 geniCodeArray2Ptr (operand * op)
2494 sym_link *optype = operandType (op);
2495 sym_link *opetype = getSpec (optype);
2497 /* set the pointer depending on the storage class */
2498 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2505 /*-----------------------------------------------------------------*/
2506 /* geniCodeArray - array access */
2507 /*-----------------------------------------------------------------*/
2509 geniCodeArray (operand * left, operand * right, int lvl)
2513 sym_link *ltype = operandType (left);
2518 if (IS_PTR (ltype->next) && left->isaddr)
2520 left = geniCodeRValue (left, FALSE);
2523 return geniCodeDerefPtr (geniCodeAdd (left,
2525 (getArraySizePtr(left) >= INTSIZE) ?
2531 size = operandFromLit (getSize (ltype->next));
2532 SPEC_USIGN (getSpec (operandType (size))) = 1;
2533 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2534 right = geniCodeMultiply (right,
2536 (getArraySizePtr(left) >= INTSIZE) ?
2539 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2540 It doesn't make sense when accessing arrays, so let's fix it here: */
2542 SPEC_USIGN (getSpec (operandType (right))) = 1;
2543 /* we can check for limits here */
2544 /* already done in SDCCast.c
2545 if (isOperandLiteral (right) &&
2548 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2550 werror (W_IDX_OUT_OF_BOUNDS,
2551 (int) operandLitValue (right) / getSize (ltype->next),
2556 ic = newiCode ('+', left, right);
2558 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2559 !IS_AGGREGATE (ltype->next) &&
2560 !IS_PTR (ltype->next))
2561 ? ltype : ltype->next), 0);
2563 if (!IS_AGGREGATE (ltype->next))
2565 IC_RESULT (ic)->isaddr = 1;
2566 IC_RESULT (ic)->aggr2ptr = 1;
2570 return IC_RESULT (ic);
2573 /*-----------------------------------------------------------------*/
2574 /* geniCodeStruct - generates intermediate code for structures */
2575 /*-----------------------------------------------------------------*/
2577 geniCodeStruct (operand * left, operand * right, bool islval)
2580 sym_link *type = operandType (left);
2581 sym_link *etype = getSpec (type);
2583 symbol *element = getStructElement (SPEC_STRUCT (etype),
2584 right->operand.symOperand);
2586 wassert(IS_SYMOP(right));
2588 /* add the offset */
2589 ic = newiCode ('+', left, operandFromLit (element->offset));
2591 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2593 /* preserve the storage & output class of the struct */
2594 /* as well as the volatile attribute */
2595 retype = getSpec (operandType (IC_RESULT (ic)));
2596 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2597 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2598 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2599 SPEC_CONST (retype) |= SPEC_CONST (etype);
2601 if (IS_PTR (element->type))
2602 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2604 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2607 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2610 /*-----------------------------------------------------------------*/
2611 /* geniCodePostInc - generate int code for Post increment */
2612 /*-----------------------------------------------------------------*/
2614 geniCodePostInc (operand * op)
2618 sym_link *optype = operandType (op);
2620 operand *rv = (IS_ITEMP (op) ?
2621 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2623 sym_link *rvtype = operandType (rv);
2626 /* if this is not an address we have trouble */
2629 werror (E_LVALUE_REQUIRED, "++");
2633 rOp = newiTempOperand (rvtype, 0);
2634 OP_SYMBOL(rOp)->noSpilLoc = 1;
2637 OP_SYMBOL(rv)->noSpilLoc = 1;
2639 geniCodeAssign (rOp, rv, 0, 0);
2641 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2643 werror(W_SIZEOF_VOID);
2644 if (IS_FLOAT (rvtype))
2645 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2646 else if (IS_FIXED16X16 (rvtype))
2647 ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
2649 ic = newiCode ('+', rv, operandFromLit (size));
2651 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2654 geniCodeAssign (op, result, 0, 0);
2660 /*-----------------------------------------------------------------*/
2661 /* geniCodePreInc - generate code for preIncrement */
2662 /*-----------------------------------------------------------------*/
2664 geniCodePreInc (operand * op, bool lvalue)
2667 sym_link *optype = operandType (op);
2668 operand *rop = (IS_ITEMP (op) ?
2669 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2671 sym_link *roptype = operandType (rop);
2677 werror (E_LVALUE_REQUIRED, "++");
2681 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2683 werror(W_SIZEOF_VOID);
2684 if (IS_FLOAT (roptype))
2685 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2686 else if (IS_FIXED16X16 (roptype))
2687 ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
2689 ic = newiCode ('+', rop, operandFromLit (size));
2690 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2693 (void) geniCodeAssign (op, result, 0, 0);
2694 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2700 /*-----------------------------------------------------------------*/
2701 /* geniCodePostDec - generates code for Post decrement */
2702 /*-----------------------------------------------------------------*/
2704 geniCodePostDec (operand * op)
2708 sym_link *optype = operandType (op);
2710 operand *rv = (IS_ITEMP (op) ?
2711 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2713 sym_link *rvtype = operandType (rv);
2716 /* if this is not an address we have trouble */
2719 werror (E_LVALUE_REQUIRED, "--");
2723 rOp = newiTempOperand (rvtype, 0);
2724 OP_SYMBOL(rOp)->noSpilLoc = 1;
2727 OP_SYMBOL(rv)->noSpilLoc = 1;
2729 geniCodeAssign (rOp, rv, 0, 0);
2731 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2733 werror(W_SIZEOF_VOID);
2734 if (IS_FLOAT (rvtype))
2735 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2736 else if (IS_FIXED16X16 (rvtype))
2737 ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
2739 ic = newiCode ('-', rv, operandFromLit (size));
2741 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2744 geniCodeAssign (op, result, 0, 0);
2750 /*-----------------------------------------------------------------*/
2751 /* geniCodePreDec - generate code for pre decrement */
2752 /*-----------------------------------------------------------------*/
2754 geniCodePreDec (operand * op, bool lvalue)
2757 sym_link *optype = operandType (op);
2758 operand *rop = (IS_ITEMP (op) ?
2759 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2761 sym_link *roptype = operandType (rop);
2767 werror (E_LVALUE_REQUIRED, "--");
2771 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2773 werror(W_SIZEOF_VOID);
2774 if (IS_FLOAT (roptype))
2775 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2776 else if (IS_FIXED16X16 (roptype))
2777 ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
2779 ic = newiCode ('-', rop, operandFromLit (size));
2780 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2783 (void) geniCodeAssign (op, result, 0, 0);
2784 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2791 /*-----------------------------------------------------------------*/
2792 /* geniCodeBitwise - gen int code for bitWise operators */
2793 /*-----------------------------------------------------------------*/
2795 geniCodeBitwise (operand * left, operand * right,
2796 int oper, sym_link * resType)
2800 left = geniCodeCast (resType, left, TRUE);
2801 right = geniCodeCast (resType, right, TRUE);
2803 ic = newiCode (oper, left, right);
2804 IC_RESULT (ic) = newiTempOperand (resType, 0);
2807 return IC_RESULT (ic);
2810 /*-----------------------------------------------------------------*/
2811 /* geniCodeAddressOf - gens icode for '&' address of operator */
2812 /*-----------------------------------------------------------------*/
2814 geniCodeAddressOf (operand * op)
2818 sym_link *optype = operandType (op);
2819 sym_link *opetype = getSpec (optype);
2821 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2823 op = operandFromOperand (op);
2828 /* lvalue check already done in decorateType */
2829 /* this must be a lvalue */
2830 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2831 /* werror (E_LVALUE_REQUIRED,"&"); */
2835 p = newLink (DECLARATOR);
2837 /* set the pointer depending on the storage class */
2838 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2840 p->next = copyLinkChain (optype);
2842 /* if already a temp */
2845 setOperandType (op, p);
2850 /* other wise make this of the type coming in */
2851 ic = newiCode (ADDRESS_OF, op, NULL);
2852 IC_RESULT (ic) = newiTempOperand (p, 1);
2853 IC_RESULT (ic)->isaddr = 0;
2855 return IC_RESULT (ic);
2858 /*-----------------------------------------------------------------*/
2859 /* setOClass - sets the output class depending on the pointer type */
2860 /*-----------------------------------------------------------------*/
2862 setOClass (sym_link * ptr, sym_link * spec)
2864 switch (DCL_TYPE (ptr))
2867 SPEC_OCLS (spec) = data;
2871 SPEC_OCLS (spec) = generic;
2875 SPEC_OCLS (spec) = xdata;
2879 SPEC_OCLS (spec) = code;
2883 SPEC_OCLS (spec) = idata;
2887 SPEC_OCLS (spec) = xstack;
2891 SPEC_OCLS (spec) = eeprom;
2900 /*-----------------------------------------------------------------*/
2901 /* geniCodeDerefPtr - dereference pointer with '*' */
2902 /*-----------------------------------------------------------------*/
2904 geniCodeDerefPtr (operand * op,int lvl)
2906 sym_link *rtype, *retype;
2907 sym_link *optype = operandType (op);
2909 // if this is an array then array access
2910 if (IS_ARRAY (optype)) {
2911 // don't worry, this will be optimized out later
2912 return geniCodeArray (op, operandFromLit (0), lvl);
2915 // just in case someone screws up
2916 wassert (IS_PTR (optype));
2918 if (IS_TRUE_SYMOP (op))
2921 op = geniCodeRValue (op, TRUE);
2924 /* now get rid of the pointer part */
2925 if (isLvaluereq(lvl) && IS_ITEMP (op))
2927 retype = getSpec (rtype = copyLinkChain (optype));
2931 retype = getSpec (rtype = copyLinkChain (optype->next));
2932 /* outputclass needs 2b updated */
2933 setOClass (optype, retype);
2936 op->isGptr = IS_GENPTR (optype);
2938 op->isaddr = (IS_PTR (rtype) ||
2939 IS_STRUCT (rtype) ||
2945 if (!isLvaluereq(lvl))
2946 op = geniCodeRValue (op, TRUE);
2948 setOperandType (op, rtype);
2953 /*-----------------------------------------------------------------*/
2954 /* geniCodeUnaryMinus - does a unary minus of the operand */
2955 /*-----------------------------------------------------------------*/
2957 geniCodeUnaryMinus (operand * op)
2960 sym_link *optype = operandType (op);
2962 if (IS_LITERAL (optype))
2963 return operandFromLit (-floatFromVal (op->operand.valOperand));
2965 ic = newiCode (UNARYMINUS, op, NULL);
2966 IC_RESULT (ic) = newiTempOperand (optype, 0);
2968 return IC_RESULT (ic);
2971 /*-----------------------------------------------------------------*/
2972 /* geniCodeLeftShift - gen i code for left shift */
2973 /*-----------------------------------------------------------------*/
2975 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2980 ic = newiCode (LEFT_OP, left, right);
2982 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2983 IC_RESULT (ic) = newiTempOperand (resType, 0);
2985 return IC_RESULT (ic);
2988 /*-----------------------------------------------------------------*/
2989 /* geniCodeRightShift - gen i code for right shift */
2990 /*-----------------------------------------------------------------*/
2992 geniCodeRightShift (operand * left, operand * right)
2996 ic = newiCode (RIGHT_OP, left, right);
2997 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2999 return IC_RESULT (ic);
3002 /*-----------------------------------------------------------------*/
3003 /* geniCodeLogic- logic code */
3004 /*-----------------------------------------------------------------*/
3006 geniCodeLogic (operand * left, operand * right, int op)
3010 sym_link *rtype = operandType (right);
3011 sym_link *ltype = operandType (left);
3013 /* left is integral type and right is literal then
3014 check if the literal value is within bounds */
3015 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
3017 checkConstantRange(ltype,
3018 OP_VALUE(right), "compare operation", 1);
3021 /* if one operand is a pointer and the other is a literal generic void pointer,
3022 change the type of the literal generic void pointer to match the other pointer */
3023 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
3024 && IS_PTR (rtype) && !IS_GENPTR(rtype))
3026 /* find left's definition */
3027 ic = (iCode *) setFirstItem (iCodeChain);
3030 if (((ic->op == CAST) || (ic->op == '='))
3031 && isOperandEqual(left, IC_RESULT (ic)))
3034 ic = setNextItem (iCodeChain);
3036 /* if casting literal to generic pointer, then cast to rtype instead */
3037 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3039 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
3040 ltype = operandType(left);
3043 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
3044 && IS_PTR (ltype) && !IS_GENPTR(ltype))
3046 /* find right's definition */
3047 ic = (iCode *) setFirstItem (iCodeChain);
3050 if (((ic->op == CAST) || (ic->op == '='))
3051 && isOperandEqual(right, IC_RESULT (ic)))
3054 ic = setNextItem (iCodeChain);
3056 /* if casting literal to generic pointer, then cast to rtype instead */
3057 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3059 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
3060 rtype = operandType(right);
3064 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
3066 ic = newiCode (op, left, right);
3067 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
3069 /* if comparing float
3070 and not a '==' || '!=' || '&&' || '||' (these
3072 if (IS_FLOAT(ctype) &&
3079 /* if comparing a fixed type use support functions */
3080 if (IS_FIXED(ctype))
3084 return IC_RESULT (ic);
3087 /*-----------------------------------------------------------------*/
3088 /* geniCodeLogicAndOr - && || operations */
3089 /*-----------------------------------------------------------------*/
3091 geniCodeLogicAndOr (ast *tree, int lvl)
3095 symbol *falseLabel = newiTempLabel (NULL);
3096 symbol *trueLabel = newiTempLabel (NULL);
3097 symbol *exitLabel = newiTempLabel (NULL);
3098 operand *op, *result, *condition;
3100 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3101 They can be reenabled by executing the following block. If you find
3102 a decent optimization you could start right here:
3107 operand *leftOp, *rightOp;
3109 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3110 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3112 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3116 /* generate two IFX for the '&&' or '||' op */
3118 /* evaluate left operand */
3119 condition = ast2iCode (tree->left, lvl + 1);
3120 op = geniCodeRValue (condition, FALSE);
3122 /* test left operand */
3123 if (tree->opval.op == AND_OP)
3124 ic = newiCodeCondition (op, NULL, falseLabel);
3126 ic = newiCodeCondition (op, trueLabel, NULL);
3129 /* evaluate right operand */
3130 condition = ast2iCode (tree->right, lvl + 1);
3131 op = geniCodeRValue (condition, FALSE);
3133 /* test right operand */
3134 ic = newiCodeCondition (op, trueLabel, NULL);
3137 /* store 0 or 1 in result */
3138 type = (SPEC_NOUN(tree->ftype) == V_BIT) ? newBoolLink() : newCharLink();
3139 result = newiTempOperand (type, 1);
3141 geniCodeLabel (falseLabel);
3142 geniCodeAssign (result, operandFromLit (0), 0, 0);
3143 /* generate an unconditional goto */
3144 geniCodeGoto (exitLabel);
3146 geniCodeLabel (trueLabel);
3147 geniCodeAssign (result, operandFromLit (1), 0, 0);
3149 geniCodeLabel (exitLabel);
3154 /*-----------------------------------------------------------------*/
3155 /* geniCodeUnary - for a generic unary operation */
3156 /*-----------------------------------------------------------------*/
3158 geniCodeUnary (operand * op, int oper)
3160 iCode *ic = newiCode (oper, op, NULL);
3162 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3164 return IC_RESULT (ic);
3167 /*-----------------------------------------------------------------*/
3168 /* geniCodeBinary - for a generic binary operation */
3169 /*-----------------------------------------------------------------*/
3171 geniCodeBinary (operand * left, operand * right, int oper)
3173 iCode *ic = newiCode (oper, left, right);
3175 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3177 return IC_RESULT (ic);
3180 /*-----------------------------------------------------------------*/
3181 /* geniCodeConditional - geniCode for '?' ':' operation */
3182 /*-----------------------------------------------------------------*/
3184 geniCodeConditional (ast * tree,int lvl)
3187 symbol *falseLabel = newiTempLabel (NULL);
3188 symbol *exitLabel = newiTempLabel (NULL);
3189 operand *cond = ast2iCode (tree->left,lvl+1);
3190 operand *true, *false, *result;
3192 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3196 true = ast2iCode (tree->right->left,lvl+1);
3198 /* move the value to a new Operand */
3199 result = newiTempOperand (tree->right->ftype, 0);
3200 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3202 /* generate an unconditional goto */
3203 geniCodeGoto (exitLabel);
3205 /* now for the right side */
3206 geniCodeLabel (falseLabel);
3208 false = ast2iCode (tree->right->right,lvl+1);
3209 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3211 /* create the exit label */
3212 geniCodeLabel (exitLabel);
3217 /*-----------------------------------------------------------------*/
3218 /* geniCodeAssign - generate code for assignment */
3219 /*-----------------------------------------------------------------*/
3221 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3224 sym_link *ltype = operandType (left);
3225 sym_link *rtype = operandType (right);
3227 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3229 werror (E_LVALUE_REQUIRED, "assignment");
3233 /* left is integral type and right is literal then
3234 check if the literal value is within bounds */
3235 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3237 checkConstantRange(ltype,
3238 OP_VALUE(right), "= operation", 0);
3241 /* if the left & right type don't exactly match */
3242 /* if pointer set then make sure the check is
3243 done with the type & not the pointer */
3244 /* then cast rights type to left */
3246 /* first check the type for pointer assignement */
3247 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3248 compareType (ltype, rtype) <= 0)
3250 if (compareType (ltype->next, rtype) < 0)
3251 right = geniCodeCast (ltype->next, right, TRUE);
3253 else if (compareType (ltype, rtype) < 0)
3254 right = geniCodeCast (ltype, right, TRUE);
3256 /* If left is a true symbol & ! volatile
3257 create an assignment to temporary for
3258 the right & then assign this temporary
3259 to the symbol. This is SSA (static single
3260 assignment). Isn't it simple and folks have
3261 published mountains of paper on it */
3262 if (IS_TRUE_SYMOP (left) &&
3263 !isOperandVolatile (left, FALSE) &&
3264 isOperandGlobal (left))
3268 if (IS_TRUE_SYMOP (right))
3269 sym = OP_SYMBOL (right);
3270 ic = newiCode ('=', NULL, right);
3271 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3272 SPIL_LOC (right) = sym;
3276 ic = newiCode ('=', NULL, right);
3277 IC_RESULT (ic) = left;
3280 /* if left isgptr flag is set then support
3281 routine will be required */
3285 ic->nosupdate = nosupdate;
3289 /*-----------------------------------------------------------------*/
3290 /* geniCodeDummyRead - generate code for dummy read */
3291 /*-----------------------------------------------------------------*/
3293 geniCodeDummyRead (operand * op)
3296 sym_link *type = operandType (op);
3298 if (!IS_VOLATILE(type))
3301 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3307 /*-----------------------------------------------------------------*/
3308 /* geniCodeSEParms - generate code for side effecting fcalls */
3309 /*-----------------------------------------------------------------*/
3311 geniCodeSEParms (ast * parms,int lvl)
3316 if (parms->type == EX_OP && parms->opval.op == PARAM)
3318 geniCodeSEParms (parms->left,lvl);
3319 geniCodeSEParms (parms->right,lvl);
3323 /* hack don't like this but too lazy to think of
3325 if (IS_ADDRESS_OF_OP (parms))
3326 parms->left->lvalue = 1;
3328 if (IS_CAST_OP (parms) &&
3329 IS_PTR (parms->ftype) &&
3330 IS_ADDRESS_OF_OP (parms->right))
3331 parms->right->left->lvalue = 1;
3333 parms->opval.oprnd =
3334 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3336 parms->type = EX_OPERAND;
3337 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3338 SPEC_ARGREG(parms->ftype);
3341 /*-----------------------------------------------------------------*/
3342 /* geniCodeParms - generates parameters */
3343 /*-----------------------------------------------------------------*/
3345 geniCodeParms (ast * parms, value *argVals, int *stack,
3346 sym_link * ftype, int lvl)
3354 if (argVals==NULL) {
3356 argVals = FUNC_ARGS (ftype);
3359 /* if this is a param node then do the left & right */
3360 if (parms->type == EX_OP && parms->opval.op == PARAM)
3362 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3363 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3367 /* get the parameter value */
3368 if (parms->type == EX_OPERAND)
3369 pval = parms->opval.oprnd;
3372 /* maybe this else should go away ?? */
3373 /* hack don't like this but too lazy to think of
3375 if (IS_ADDRESS_OF_OP (parms))
3376 parms->left->lvalue = 1;
3378 if (IS_CAST_OP (parms) &&
3379 IS_PTR (parms->ftype) &&
3380 IS_ADDRESS_OF_OP (parms->right))
3381 parms->right->left->lvalue = 1;
3383 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3386 /* if register parm then make it a send */
3387 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3388 IFFUNC_ISBUILTIN(ftype))
3390 ic = newiCode (SEND, pval, NULL);
3391 ic->argreg = SPEC_ARGREG(parms->etype);
3392 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3397 /* now decide whether to push or assign */
3398 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3402 operand *top = operandFromSymbol (argVals->sym);
3403 /* clear useDef and other bitVectors */
3404 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3405 geniCodeAssign (top, pval, 1, 0);
3409 sym_link *p = operandType (pval);
3411 ic = newiCode (IPUSH, pval, NULL);
3413 /* update the stack adjustment */
3414 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3419 argVals=argVals->next;
3423 /*-----------------------------------------------------------------*/
3424 /* geniCodeCall - generates temp code for calling */
3425 /*-----------------------------------------------------------------*/
3427 geniCodeCall (operand * left, ast * parms,int lvl)
3431 sym_link *type, *etype;
3435 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3436 !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3437 werror (E_FUNCTION_EXPECTED);
3438 return operandFromValue(valueFromLit(0));
3441 /* take care of parameters with side-effecting
3442 function calls in them, this is required to take care
3443 of overlaying function parameters */
3444 geniCodeSEParms (parms,lvl);
3446 ftype = operandType (left);
3447 if (IS_FUNCPTR (ftype))
3448 ftype = ftype->next;
3450 /* first the parameters */
3451 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3453 /* now call : if symbol then pcall */
3454 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3455 ic = newiCode (PCALL, left, NULL);
3457 ic = newiCode (CALL, left, NULL);
3460 type = copyLinkChain (ftype->next);
3461 etype = getSpec (type);
3462 SPEC_EXTR (etype) = 0;
3463 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3467 /* stack adjustment after call */
3468 ic->parmBytes = stack;
3473 /*-----------------------------------------------------------------*/
3474 /* geniCodeReceive - generate intermediate code for "receive" */
3475 /*-----------------------------------------------------------------*/
3477 geniCodeReceive (value * args, operand * func)
3479 unsigned char paramByteCounter = 0;
3481 /* for all arguments that are passed in registers */
3484 if (IS_REGPARM (args->etype))
3486 operand *opr = operandFromValue (args);
3488 symbol *sym = OP_SYMBOL (opr);
3491 /* we will use it after all optimizations
3492 and before liveRange calculation */
3493 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3496 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3497 options.stackAuto == 0 &&
3498 (!(options.model == MODEL_FLAT24)) )
3503 opl = newiTempOperand (args->type, 0);
3505 sym->reqv->key = sym->key;
3506 OP_SYMBOL (sym->reqv)->key = sym->key;
3507 OP_SYMBOL (sym->reqv)->isreqv = 1;
3508 OP_SYMBOL (sym->reqv)->islocal = 0;
3509 SPIL_LOC (sym->reqv) = sym;
3513 ic = newiCode (RECEIVE, func, NULL);
3514 ic->argreg = SPEC_ARGREG(args->etype);
3515 if (ic->argreg == 1) {
3516 currFunc->recvSize = getSize (sym->type);
3518 IC_RESULT (ic) = opr;
3520 /* misuse of parmBytes (normally used for functions)
3521 * to save estimated stack position of this argument.
3522 * Normally this should be zero for RECEIVE iCodes.
3523 * No idea if this causes side effects on other ports. - dw
3525 ic->parmBytes = paramByteCounter;
3527 /* what stack position do we have? */
3528 paramByteCounter += getSize (sym->type);
3537 /*-----------------------------------------------------------------*/
3538 /* geniCodeFunctionBody - create the function body */
3539 /*-----------------------------------------------------------------*/
3541 geniCodeFunctionBody (ast * tree,int lvl)
3548 /* reset the auto generation */
3554 func = ast2iCode (tree->left,lvl+1);
3555 fetype = getSpec (operandType (func));
3557 savelineno = lineno;
3558 lineno = OP_SYMBOL (func)->lineDef;
3559 /* create an entry label */
3560 geniCodeLabel (entryLabel);
3561 lineno = savelineno;
3563 /* create a proc icode */
3564 ic = newiCode (FUNCTION, func, NULL);
3565 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3570 /* for all parameters that are passed
3571 on registers add a "receive" */
3572 geniCodeReceive (tree->values.args, func);
3574 /* generate code for the body */
3575 ast2iCode (tree->right,lvl+1);
3577 /* create a label for return */
3578 geniCodeLabel (returnLabel);
3580 /* now generate the end proc */
3581 ic = newiCode (ENDFUNCTION, func, NULL);
3587 /*-----------------------------------------------------------------*/
3588 /* geniCodeReturn - gen icode for 'return' statement */
3589 /*-----------------------------------------------------------------*/
3591 geniCodeReturn (operand * op)
3595 /* if the operand is present force an rvalue */
3597 op = geniCodeRValue (op, FALSE);
3599 ic = newiCode (RETURN, op, NULL);
3603 /*-----------------------------------------------------------------*/
3604 /* geniCodeIfx - generates code for extended if statement */
3605 /*-----------------------------------------------------------------*/
3607 geniCodeIfx (ast * tree,int lvl)
3610 operand *condition = ast2iCode (tree->left,lvl+1);
3613 /* if condition is null then exit */
3617 condition = geniCodeRValue (condition, FALSE);
3619 cetype = getSpec (operandType (condition));
3620 /* if the condition is a literal */
3621 if (IS_LITERAL (cetype))
3623 if (floatFromVal (condition->operand.valOperand))
3625 if (tree->trueLabel)
3626 geniCodeGoto (tree->trueLabel);
3632 if (tree->falseLabel)
3633 geniCodeGoto (tree->falseLabel);
3640 if (tree->trueLabel)
3642 ic = newiCodeCondition (condition,
3647 if (tree->falseLabel)
3648 geniCodeGoto (tree->falseLabel);
3652 ic = newiCodeCondition (condition,
3659 ast2iCode (tree->right,lvl+1);
3662 /*-----------------------------------------------------------------*/
3663 /* geniCodeJumpTable - tries to create a jump table for switch */
3664 /*-----------------------------------------------------------------*/
3666 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3668 int min, max, cnt = 1;
3675 int needRangeCheck = !optimize.noJTabBoundary
3676 || tree->values.switchVals.swDefault;
3677 sym_link *cetype = getSpec (operandType (cond));
3678 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3679 int sizeofMatchJump, sizeofJumpTable;
3682 if (!tree || !caseVals)
3685 /* the criteria for creating a jump table is */
3686 /* all integer numbers between the maximum & minimum must */
3687 /* be present , the maximum value should not exceed 255 */
3688 /* If not all integer numbers are present the algorithm */
3689 /* inserts jumps to the default label for the missing numbers */
3690 /* and decides later whether it is worth it */
3691 min = (int) floatFromVal (vch = caseVals);
3698 max = (int) floatFromVal (vch);
3700 /* Exit if the range is too large to handle with a jump table. */
3701 if (1 + max - min > port->jumptableCost.maxCount)
3704 switch (getSize (operandType (cond)))
3706 case 1: sizeIndex = 0; break;
3707 case 2: sizeIndex = 1; break;
3708 case 4: sizeIndex = 2; break;
3712 /* Compute the size cost of the range check and subtraction. */
3714 sizeofZeroMinCost = 0;
3718 if (!(min==0 && IS_UNSIGNED (cetype)))
3719 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3720 if (!IS_UNSIGNED (cetype))
3721 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3722 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3725 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3727 /* If the size cost of handling a non-zero minimum exceeds the */
3728 /* cost of extending the range down to zero, then it might be */
3729 /* better to extend the range to zero. */
3730 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3731 >= (min * port->jumptableCost.sizeofElement))
3733 /* Only extend the jump table if it would still be manageable. */
3734 if (1 + max <= port->jumptableCost.maxCount)
3737 if (IS_UNSIGNED (cetype))
3740 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3744 /* Compute the total size cost of a jump table. */
3745 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3746 + port->jumptableCost.sizeofDispatch
3747 + sizeofMinCost + sizeofMaxCost;
3749 /* Compute the total size cost of a match & jump sequence */
3750 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3752 /* If the size cost of the jump table is uneconomical then exit */
3753 if (sizeofMatchJump < sizeofJumpTable)
3756 /* The jump table is preferable. */
3758 /* First, a label for the default or missing cases. */
3759 if (tree->values.switchVals.swDefault)
3761 SNPRINTF (buffer, sizeof(buffer),
3763 tree->values.switchVals.swNum);
3767 SNPRINTF (buffer, sizeof(buffer),
3769 tree->values.switchVals.swNum);
3771 falseLabel = newiTempLabel (buffer);
3773 /* Build the list of labels for the jump table. */
3775 t = (int) floatFromVal (vch);
3776 for (i=min; i<=max; i++)
3780 /* Explicit case: make a new label for it. */
3781 SNPRINTF (buffer, sizeof(buffer),
3783 tree->values.switchVals.swNum,
3785 addSet (&labels, newiTempLabel (buffer));
3788 t = (int) floatFromVal (vch);
3792 /* Implicit case: use the default label. */
3793 addSet (&labels, falseLabel);
3797 /* first we rule out the boundary conditions */
3798 /* if only optimization says so */
3801 sym_link *cetype = getSpec (operandType (cond));
3802 /* no need to check the lower bound if
3803 the condition is unsigned & minimum value is zero */
3804 if (!(min == 0 && IS_UNSIGNED (cetype)))
3806 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3807 ic = newiCodeCondition (boundary, falseLabel, NULL);
3811 /* now for upper bounds */
3812 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3813 ic = newiCodeCondition (boundary, falseLabel, NULL);
3817 /* if the min is not zero then we no make it zero */
3820 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3821 if (!IS_LITERAL(getSpec(operandType(cond))))
3822 setOperandType (cond, UCHARTYPE);
3825 /* now create the jumptable */
3826 ic = newiCode (JUMPTABLE, NULL, NULL);
3827 IC_JTCOND (ic) = cond;
3828 IC_JTLABELS (ic) = labels;
3833 /*-----------------------------------------------------------------*/
3834 /* geniCodeSwitch - changes a switch to a if statement */
3835 /*-----------------------------------------------------------------*/
3837 geniCodeSwitch (ast * tree,int lvl)
3840 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3841 value *caseVals = tree->values.switchVals.swVals;
3842 symbol *trueLabel, *falseLabel;
3844 /* If the condition is a literal, then just jump to the */
3845 /* appropriate case label. */
3846 if (IS_LITERAL(getSpec(operandType(cond))))
3848 int switchVal, caseVal;
3850 switchVal = (int) floatFromVal (cond->operand.valOperand);
3853 caseVal = (int) floatFromVal (caseVals);
3854 if (caseVal == switchVal)
3856 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3857 tree->values.switchVals.swNum, caseVal);
3858 trueLabel = newiTempLabel (buffer);
3859 geniCodeGoto (trueLabel);
3862 caseVals = caseVals->next;
3864 goto defaultOrBreak;
3867 /* If cond is volatile, it might change while we are trying to */
3868 /* find the matching case. To avoid this possibility, make a */
3869 /* non-volatile copy to use instead. */
3870 if (IS_OP_VOLATILE (cond))
3875 newcond = newiTempOperand (operandType (cond), TRUE);
3876 newcond->isvolatile = 0;
3877 ic = newiCode ('=', NULL, cond);
3878 IC_RESULT (ic) = newcond;
3883 /* if we can make this a jump table */
3884 if (geniCodeJumpTable (cond, caseVals, tree))
3885 goto jumpTable; /* no need for the comparison */
3887 /* for the cases defined do */
3891 operand *compare = geniCodeLogic (cond,
3892 operandFromValue (caseVals),
3895 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3896 tree->values.switchVals.swNum,
3897 (int) floatFromVal (caseVals));
3898 trueLabel = newiTempLabel (buffer);
3900 ic = newiCodeCondition (compare, trueLabel, NULL);
3902 caseVals = caseVals->next;
3907 /* if default is present then goto break else break */
3908 if (tree->values.switchVals.swDefault)
3910 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3914 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3917 falseLabel = newiTempLabel (buffer);
3918 geniCodeGoto (falseLabel);
3921 ast2iCode (tree->right,lvl+1);
3924 /*-----------------------------------------------------------------*/
3925 /* geniCodeInline - intermediate code for inline assembler */
3926 /*-----------------------------------------------------------------*/
3928 geniCodeInline (ast * tree)
3932 ic = newiCode (INLINEASM, NULL, NULL);
3933 IC_INLINE (ic) = tree->values.inlineasm;
3937 /*-----------------------------------------------------------------*/
3938 /* geniCodeArrayInit - intermediate code for array initializer */
3939 /*-----------------------------------------------------------------*/
3941 geniCodeArrayInit (ast * tree, operand *array)
3945 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3946 ic = newiCode (ARRAYINIT, array, NULL);
3947 IC_ARRAYILIST (ic) = tree->values.constlist;
3949 operand *left=newOperand(), *right=newOperand();
3950 left->type=right->type=SYMBOL;
3951 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3952 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3953 ic = newiCode (ARRAYINIT, left, right);
3958 /*-----------------------------------------------------------------*/
3959 /* geniCodeCritical - intermediate code for a critical statement */
3960 /*-----------------------------------------------------------------*/
3962 geniCodeCritical (ast *tree, int lvl)
3968 if (!options.stackAuto)
3970 type = newLink(SPECIFIER);
3971 SPEC_VOLATILE(type) = 1;
3972 SPEC_NOUN(type) = V_BIT;
3973 SPEC_SCLS(type) = S_BIT;
3974 SPEC_BLEN(type) = 1;
3975 SPEC_BSTR(type) = 0;
3976 op = newiTempOperand(type, 1);
3979 /* If op is NULL, the original interrupt state will saved on */
3980 /* the stack. Otherwise, it will be saved in op. */
3982 /* Generate a save of the current interrupt state & disable */
3983 ic = newiCode (CRITICAL, NULL, NULL);
3984 IC_RESULT (ic) = op;
3987 /* Generate the critical code sequence */
3988 if (tree->left && tree->left->type == EX_VALUE)
3989 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3991 ast2iCode (tree->left,lvl+1);
3993 /* Generate a restore of the original interrupt state */
3994 ic = newiCode (ENDCRITICAL, NULL, op);
3998 /*-----------------------------------------------------------------*/
3999 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
4000 /* particular case. Ie : assigning or dereferencing array or ptr */
4001 /*-----------------------------------------------------------------*/
4002 set * lvaluereqSet = NULL;
4003 typedef struct lvalItem
4010 /*-----------------------------------------------------------------*/
4011 /* addLvaluereq - add a flag for lvalreq for current ast level */
4012 /*-----------------------------------------------------------------*/
4013 void addLvaluereq(int lvl)
4015 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
4018 addSetHead(&lvaluereqSet,lpItem);
4021 /*-----------------------------------------------------------------*/
4022 /* delLvaluereq - del a flag for lvalreq for current ast level */
4023 /*-----------------------------------------------------------------*/
4027 lpItem = getSet(&lvaluereqSet);
4028 if(lpItem) Safe_free(lpItem);
4030 /*-----------------------------------------------------------------*/
4031 /* clearLvaluereq - clear lvalreq flag */
4032 /*-----------------------------------------------------------------*/
4033 void clearLvaluereq()
4036 lpItem = peekSet(lvaluereqSet);
4037 if(lpItem) lpItem->req = 0;
4039 /*-----------------------------------------------------------------*/
4040 /* getLvaluereq - get the last lvalreq level */
4041 /*-----------------------------------------------------------------*/
4042 int getLvaluereqLvl()
4045 lpItem = peekSet(lvaluereqSet);
4046 if(lpItem) return lpItem->lvl;
4049 /*-----------------------------------------------------------------*/
4050 /* isLvaluereq - is lvalreq valid for this level ? */
4051 /*-----------------------------------------------------------------*/
4052 int isLvaluereq(int lvl)
4055 lpItem = peekSet(lvaluereqSet);
4056 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4060 /*-----------------------------------------------------------------*/
4061 /* ast2iCode - creates an icodeList from an ast */
4062 /*-----------------------------------------------------------------*/
4064 ast2iCode (ast * tree,int lvl)
4066 operand *left = NULL;
4067 operand *right = NULL;
4071 /* set the global variables for filename & line number */
4073 filename = tree->filename;
4075 lineno = tree->lineno;
4077 block = tree->block;
4079 scopeLevel = tree->level;
4081 seqPoint = tree->seqPoint;
4083 if (tree->type == EX_VALUE)
4084 return operandFromValue (tree->opval.val);
4086 if (tree->type == EX_LINK)
4087 return operandFromLink (tree->opval.lnk);
4089 /* if we find a nullop */
4090 if (tree->type == EX_OP &&
4091 (tree->opval.op == NULLOP ||
4092 tree->opval.op == BLOCK))
4094 if (tree->left && tree->left->type == EX_VALUE)
4095 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4097 ast2iCode (tree->left,lvl+1);
4098 if (tree->right && tree->right->type == EX_VALUE)
4099 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4101 ast2iCode (tree->right,lvl+1);
4105 /* special cases for not evaluating */
4106 if (tree->opval.op != ':' &&
4107 tree->opval.op != '?' &&
4108 tree->opval.op != CALL &&
4109 tree->opval.op != IFX &&
4110 tree->opval.op != AND_OP &&
4111 tree->opval.op != OR_OP &&
4112 tree->opval.op != LABEL &&
4113 tree->opval.op != GOTO &&
4114 tree->opval.op != SWITCH &&
4115 tree->opval.op != FUNCTION &&
4116 tree->opval.op != INLINEASM &&
4117 tree->opval.op != CRITICAL)
4120 if (IS_ASSIGN_OP (tree->opval.op) ||
4121 IS_DEREF_OP (tree) ||
4122 (tree->opval.op == '&' && !tree->right) ||
4123 tree->opval.op == PTR_OP)
4126 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4127 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4130 left = operandFromAst (tree->left,lvl);
4132 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4133 left = geniCodeRValue (left, TRUE);
4137 left = operandFromAst (tree->left,lvl);
4139 if (tree->opval.op == INC_OP ||
4140 tree->opval.op == DEC_OP)
4143 right = operandFromAst (tree->right,lvl);
4148 right = operandFromAst (tree->right,lvl);
4152 /* now depending on the type of operand */
4153 /* this will be a biggy */
4154 switch (tree->opval.op)
4157 case '[': /* array operation */
4159 //sym_link *ltype = operandType (left);
4160 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4161 left = geniCodeRValue (left, FALSE);
4162 right = geniCodeRValue (right, TRUE);
4165 return geniCodeArray (left, right,lvl);
4167 case '.': /* structure dereference */
4168 if (IS_PTR (operandType (left)))
4169 left = geniCodeRValue (left, TRUE);
4171 left = geniCodeRValue (left, FALSE);
4173 return geniCodeStruct (left, right, tree->lvalue);
4175 case PTR_OP: /* structure pointer dereference */
4178 pType = operandType (left);
4179 left = geniCodeRValue (left, TRUE);
4181 setOClass (pType, getSpec (operandType (left)));
4184 return geniCodeStruct (left, right, tree->lvalue);
4186 case INC_OP: /* increment operator */
4188 return geniCodePostInc (left);
4190 return geniCodePreInc (right, tree->lvalue);
4192 case DEC_OP: /* decrement operator */
4194 return geniCodePostDec (left);
4196 return geniCodePreDec (right, tree->lvalue);
4198 case '&': /* bitwise and or address of operator */
4200 { /* this is a bitwise operator */
4201 left = geniCodeRValue (left, FALSE);
4202 right = geniCodeRValue (right, FALSE);
4203 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4206 return geniCodeAddressOf (left);
4208 case '|': /* bitwise or & xor */
4210 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4211 geniCodeRValue (right, FALSE),
4216 return geniCodeDivision (geniCodeRValue (left, FALSE),
4217 geniCodeRValue (right, FALSE),
4218 getResultTypeFromType (tree->ftype));
4221 return geniCodeModulus (geniCodeRValue (left, FALSE),
4222 geniCodeRValue (right, FALSE),
4223 getResultTypeFromType (tree->ftype));
4226 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4227 geniCodeRValue (right, FALSE),
4228 getResultTypeFromType (tree->ftype));
4230 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4234 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4235 geniCodeRValue (right, FALSE),
4236 getResultTypeFromType (tree->ftype));
4238 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4242 return geniCodeAdd (geniCodeRValue (left, FALSE),
4243 geniCodeRValue (right, FALSE),
4244 getResultTypeFromType (tree->ftype),
4247 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4250 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4251 geniCodeRValue (right, FALSE),
4252 getResultTypeFromType (tree->ftype));
4255 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4256 geniCodeRValue (right, FALSE));
4258 #if 0 // this indeed needs a second thought
4262 // let's keep this simple: get the rvalue we need
4263 op=geniCodeRValue (right, FALSE);
4264 // now cast it to whatever we want
4265 op=geniCodeCast (operandType(left), op, FALSE);
4266 // if this is going to be used as an lvalue, make it so
4272 #else // bug #604575, is it a bug ????
4273 return geniCodeCast (operandType (left),
4274 geniCodeRValue (right, FALSE), FALSE);
4281 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4286 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4287 setOperandType (op, UCHARTYPE);
4294 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4295 geniCodeRValue (right, FALSE),
4297 setOperandType (op, (tree->opval.op == GETWORD) ? UINTTYPE : UCHARTYPE);
4302 return geniCodeLogicAndOr (tree, lvl);
4309 /* different compilers (even different gccs) evaluate
4310 the two calls in a different order. to get the same
4311 result on all machines we've to specify a clear sequence.
4312 return geniCodeLogic (geniCodeRValue (left, FALSE),
4313 geniCodeRValue (right, FALSE),
4317 operand *leftOp, *rightOp;
4319 leftOp = geniCodeRValue (left , FALSE);
4320 rightOp = geniCodeRValue (right, FALSE);
4322 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4325 return geniCodeConditional (tree,lvl);
4328 return operandFromLit (getSize (tree->right->ftype));
4332 sym_link *rtype = operandType (right);
4333 sym_link *ltype = operandType (left);
4334 if (IS_PTR (rtype) && IS_ITEMP (right)
4335 && right->isaddr && compareType (rtype->next, ltype) == 1)
4336 right = geniCodeRValue (right, TRUE);
4338 right = geniCodeRValue (right, FALSE);
4340 geniCodeAssign (left, right, 0, 1);
4345 geniCodeAssign (left,
4346 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4348 geniCodeRValue (right, FALSE),
4349 getResultTypeFromType (tree->ftype)),
4354 geniCodeAssign (left,
4355 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4357 geniCodeRValue (right, FALSE),
4358 getResultTypeFromType (tree->ftype)),
4362 geniCodeAssign (left,
4363 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4365 geniCodeRValue (right, FALSE),
4366 getResultTypeFromType (tree->ftype)),
4370 sym_link *rtype = operandType (right);
4371 sym_link *ltype = operandType (left);
4372 if (IS_PTR (rtype) && IS_ITEMP (right)
4373 && right->isaddr && compareType (rtype->next, ltype) == 1)
4374 right = geniCodeRValue (right, TRUE);
4376 right = geniCodeRValue (right, FALSE);
4379 return geniCodeAssign (left,
4380 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4383 getResultTypeFromType (tree->ftype),
4389 sym_link *rtype = operandType (right);
4390 sym_link *ltype = operandType (left);
4391 if (IS_PTR (rtype) && IS_ITEMP (right)
4392 && right->isaddr && compareType (rtype->next, ltype) == 1)
4394 right = geniCodeRValue (right, TRUE);
4398 right = geniCodeRValue (right, FALSE);
4401 geniCodeAssign (left,
4402 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4405 getResultTypeFromType (tree->ftype)),
4410 geniCodeAssign (left,
4411 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4413 geniCodeRValue (right, FALSE),
4414 getResultTypeFromType (tree->ftype)),
4418 geniCodeAssign (left,
4419 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4421 geniCodeRValue (right, FALSE)), 0, 1);
4424 geniCodeAssign (left,
4425 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4427 geniCodeRValue (right, FALSE),
4429 operandType (left)), 0, 1);
4432 geniCodeAssign (left,
4433 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4435 geniCodeRValue (right, FALSE),
4437 operandType (left)), 0, 1);
4440 geniCodeAssign (left,
4441 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4443 geniCodeRValue (right, FALSE),
4445 operandType (left)), 0, 1);
4447 return geniCodeRValue (right, FALSE);
4450 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4453 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4454 return ast2iCode (tree->right,lvl+1);
4457 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4458 return ast2iCode (tree->right,lvl+1);
4461 geniCodeFunctionBody (tree,lvl);
4465 geniCodeReturn (right);
4469 geniCodeIfx (tree,lvl);
4473 geniCodeSwitch (tree,lvl);
4477 geniCodeInline (tree);
4481 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4485 geniCodeCritical (tree, lvl);
4491 /*-----------------------------------------------------------------*/
4492 /* reverseICChain - gets from the list and creates a linkedlist */
4493 /*-----------------------------------------------------------------*/
4500 while ((loop = getSet (&iCodeChain)))
4512 /*-----------------------------------------------------------------*/
4513 /* iCodeFromAst - given an ast will convert it to iCode */
4514 /*-----------------------------------------------------------------*/
4516 iCodeFromAst (ast * tree)
4518 returnLabel = newiTempLabel ("_return");
4519 entryLabel = newiTempLabel ("_entry");
4521 return reverseiCChain ();
4524 static const char *opTypeToStr(OPTYPE op)
4528 case SYMBOL: return "symbol";
4529 case VALUE: return "value";
4530 case TYPE: return "type";
4532 return "undefined type";
4536 operand *validateOpType(operand *op,
4543 if (op && op->type == type)
4548 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4549 " expected %s, got %s\n",
4550 macro, args, file, line,
4551 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4553 return op; // never reached, makes compiler happy.