1 /*-------------------------------------------------------------------------
3 SDCCicode.c - intermediate code generation etc.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
29 /*-----------------------------------------------------------------*/
30 /* global variables */
32 set *iCodeChain = NULL;
43 symbol *returnLabel; /* function return label */
44 symbol *entryLabel; /* function entry label */
46 /*-----------------------------------------------------------------*/
47 /* forward definition of some functions */
48 operand *geniCodeAssign (operand *, operand *, int, int);
49 static operand *geniCodeArray (operand *, operand *,int);
50 static operand *geniCodeArray2Ptr (operand *);
51 operand *geniCodeRValue (operand *, bool);
52 operand *geniCodeDerefPtr (operand *,int);
53 int isLvaluereq(int lvl);
54 void setOClass (sym_link * ptr, sym_link * spec);
55 static operand *geniCodeCast (sym_link *, operand *, bool);
57 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
58 /* forward definition of ic print functions */
59 PRINTFUNC (picGetValueAtAddr);
60 PRINTFUNC (picSetValueAtAddr);
61 PRINTFUNC (picAddrOf);
62 PRINTFUNC (picGeneric);
63 PRINTFUNC (picGenericOne);
65 PRINTFUNC (picAssign);
69 PRINTFUNC (picJumpTable);
70 PRINTFUNC (picInline);
71 PRINTFUNC (picReceive);
72 PRINTFUNC (picDummyRead);
73 PRINTFUNC (picCritical);
74 PRINTFUNC (picEndCritical);
76 iCodeTable codeTable[] =
78 {'!', "not", picGenericOne, NULL},
79 {'~', "~", picGenericOne, NULL},
80 {RRC, "rrc", picGenericOne, NULL},
81 {RLC, "rlc", picGenericOne, NULL},
82 {GETHBIT, "ghbit", picGenericOne, NULL},
83 {GETABIT, "gabit", picGenericOne, NULL},
84 {GETBYTE, "gbyte", picGenericOne, NULL},
85 {GETWORD, "gword", picGenericOne, NULL},
86 {UNARYMINUS, "-", picGenericOne, NULL},
87 {IPUSH, "push", picGenericOne, NULL},
88 {IPOP, "pop", picGenericOne, NULL},
89 {CALL, "call", picGenericOne, NULL},
90 {PCALL, "pcall", picGenericOne, NULL},
91 {FUNCTION, "proc", picGenericOne, NULL},
92 {ENDFUNCTION, "eproc", picGenericOne, NULL},
93 {RETURN, "ret", picGenericOne, NULL},
94 {'+', "+", picGeneric, NULL},
95 {'-', "-", picGeneric, NULL},
96 {'*', "*", picGeneric, NULL},
97 {'/', "/", picGeneric, NULL},
98 {'%', "%", picGeneric, NULL},
99 {'>', ">", picGeneric, NULL},
100 {'<', "<", picGeneric, NULL},
101 {LE_OP, "<=", picGeneric, NULL},
102 {GE_OP, ">=", picGeneric, NULL},
103 {EQ_OP, "==", picGeneric, NULL},
104 {NE_OP, "!=", picGeneric, NULL},
105 {AND_OP, "&&", picGeneric, NULL},
106 {OR_OP, "||", picGeneric, NULL},
107 {'^', "^", picGeneric, NULL},
108 {'|', "|", picGeneric, NULL},
109 {BITWISEAND, "&", picGeneric, NULL},
110 {LEFT_OP, "<<", picGeneric, NULL},
111 {RIGHT_OP, ">>", picGeneric, NULL},
112 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
113 {ADDRESS_OF, "&", picAddrOf, NULL},
114 {CAST, "<>", picCast, NULL},
115 {'=', ":=", picAssign, NULL},
116 {LABEL, "", picLabel, NULL},
117 {GOTO, "", picGoto, NULL},
118 {JUMPTABLE, "jtab", picJumpTable, NULL},
119 {IFX, "if", picIfx, NULL},
120 {INLINEASM, "", picInline, NULL},
121 {RECEIVE, "recv", picReceive, NULL},
122 {SEND, "send", picGenericOne, NULL},
123 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
124 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
125 {CRITICAL, "critical_start", picCritical, NULL},
126 {ENDCRITICAL, "critical_end", picEndCritical, NULL},
127 {SWAP, "swap", picGenericOne, NULL}
130 /*-----------------------------------------------------------------*/
131 /* checkConstantRange: check a constant against the type */
132 /*-----------------------------------------------------------------*/
135 /* pedantic=0: allmost anything is allowed as long as the absolute
136 value is within the bit range of the type, and -1 is treated as
137 0xf..f for unsigned types (e.g. in assign)
138 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
139 pedantic>1: "char c=200" is not allowed (evaluates to -56)
142 void checkConstantRange(sym_link *ltype, value *val, char *msg,
149 max = pow ((double)2.0, (double)bitsForType(ltype));
151 if (IS_LONG(val->type)) {
152 if (IS_UNSIGNED(val->type)) {
153 v=SPEC_CVAL(val->type).v_ulong;
155 v=SPEC_CVAL(val->type).v_long;
158 if (IS_UNSIGNED(val->type)) {
159 v=SPEC_CVAL(val->type).v_uint;
161 v=SPEC_CVAL(val->type).v_int;
167 // this could be a good idea
168 if (options.pedantic)
172 if (IS_FLOAT(ltype)) {
177 if (IS_FIXED(ltype)) {
182 if (!IS_UNSIGNED(val->type) && v<0) {
184 if (IS_UNSIGNED(ltype) && (pedantic>1)) {
190 // if very pedantic: "char c=200" is not allowed
191 if (pedantic>1 && !IS_UNSIGNED(ltype)) {
192 max = max/2 + negative;
199 #if 0 // temporary disabled, leaving the warning as a reminder
201 SNPRINTF (message, sizeof(message), "for %s %s in %s",
202 IS_UNSIGNED(ltype) ? "unsigned" : "signed",
203 nounName(ltype), msg);
204 werror (W_CONST_RANGE, message);
212 /*-----------------------------------------------------------------*/
213 /* operandName - returns the name of the operand */
214 /*-----------------------------------------------------------------*/
216 printOperand (operand * op, FILE * file)
233 opetype = getSpec (operandType (op));
234 if (IS_FLOAT (opetype))
235 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
236 if (IS_FIXED16X16 (opetype))
237 fprintf (file, "%g {", doubleFromFixed16x16(SPEC_CVAL (opetype).v_fixed16x16));
239 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
240 printTypeChain (operandType (op), file);
247 if(REGA && !getenv("PRINT_SHORT_OPERANDS")) {
248 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d a2p%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
249 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
251 OP_LIVEFROM (op), OP_LIVETO (op),
252 OP_SYMBOL (op)->stack,
253 op->isaddr, op->aggr2ptr, OP_SYMBOL (op)->isreqv,
254 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
255 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
259 printTypeChain (operandType (op), file);
260 if (SPIL_LOC (op) && IS_ITEMP (op))
261 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
266 /* if assigned to registers */
267 if (OP_SYMBOL (op)->nRegs)
269 if (OP_SYMBOL (op)->isspilt)
271 if (!OP_SYMBOL (op)->remat)
272 if (OP_SYMBOL (op)->usl.spillLoc)
273 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
274 OP_SYMBOL (op)->usl.spillLoc->rname :
275 OP_SYMBOL (op)->usl.spillLoc->name));
277 fprintf (file, "[err]");
279 fprintf (file, "[remat]");
285 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
286 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
290 //#else /* } else { */
292 /* (getenv("PRINT_SHORT_OPERANDS") != NULL) */
293 fprintf (file, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
295 if(getenv("PRINT_SHORT_OPERANDS")[0] < '1')
297 fprintf (file, "[lr%d:%d so:%d]",
298 OP_LIVEFROM (op), OP_LIVETO (op),
299 OP_SYMBOL (op)->stack);
302 if(getenv("PRINT_SHORT_OPERANDS")[0] < '2')
305 printTypeChain (operandType (op), file);
306 if (SPIL_LOC (op) && IS_ITEMP (op))
307 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
311 /* if assigned to registers */
312 if (OP_SYMBOL (op)->nRegs)
314 if (OP_SYMBOL (op)->isspilt)
316 if (!OP_SYMBOL (op)->remat)
317 if (OP_SYMBOL (op)->usl.spillLoc)
318 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
319 OP_SYMBOL (op)->usl.spillLoc->rname :
320 OP_SYMBOL (op)->usl.spillLoc->name));
322 fprintf (file, "[err]");
324 fprintf (file, "[remat]");
330 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
331 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
341 printTypeChain (op->operand.typeOperand, file);
347 fprintf (file, "\n");
352 /*-----------------------------------------------------------------*/
353 /* print functions */
354 /*-----------------------------------------------------------------*/
355 PRINTFUNC (picGetValueAtAddr)
358 printOperand (IC_RESULT (ic), of);
361 printOperand (IC_LEFT (ic), of);
367 PRINTFUNC (picSetValueAtAddr)
371 printOperand (IC_LEFT (ic), of);
372 fprintf (of, "] = ");
373 printOperand (IC_RIGHT (ic), of);
377 PRINTFUNC (picAddrOf)
380 printOperand (IC_RESULT (ic), of);
381 if (IS_ITEMP (IC_LEFT (ic)))
384 fprintf (of, " = &[");
385 printOperand (IC_LEFT (ic), of);
388 if (IS_ITEMP (IC_LEFT (ic)))
389 fprintf (of, " offsetAdd ");
392 printOperand (IC_RIGHT (ic), of);
394 if (IS_ITEMP (IC_LEFT (ic)))
400 PRINTFUNC (picJumpTable)
405 fprintf (of, "%s\t", s);
406 printOperand (IC_JTCOND (ic), of);
408 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
409 sym = setNextItem (IC_JTLABELS (ic)))
410 fprintf (of, "\t\t\t%s\n", sym->name);
413 PRINTFUNC (picGeneric)
416 printOperand (IC_RESULT (ic), of);
418 printOperand (IC_LEFT (ic), of);
419 fprintf (of, " %s ", s);
420 printOperand (IC_RIGHT (ic), of);
424 PRINTFUNC (picGenericOne)
429 printOperand (IC_RESULT (ic), of);
435 fprintf (of, "%s ", s);
436 printOperand (IC_LEFT (ic), of);
439 if (!IC_RESULT (ic) && !IC_LEFT (ic))
442 if (ic->op == SEND || ic->op == RECEIVE) {
443 fprintf(of,"{argreg = %d}",ic->argreg);
445 if (ic->op == IPUSH) {
446 fprintf(of,"{parmPush = %d}",ic->parmPush);
454 printOperand (IC_RESULT (ic), of);
456 printOperand (IC_LEFT (ic), of);
457 printOperand (IC_RIGHT (ic), of);
462 PRINTFUNC (picAssign)
466 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
469 printOperand (IC_RESULT (ic), of);
471 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
474 fprintf (of, " %s ", s);
475 printOperand (IC_RIGHT (ic), of);
482 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
488 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
495 printOperand (IC_COND (ic), of);
498 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
501 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
503 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
507 PRINTFUNC (picInline)
509 fprintf (of, "%s", IC_INLINE (ic));
512 PRINTFUNC (picReceive)
514 printOperand (IC_RESULT (ic), of);
515 fprintf (of, " = %s ", s);
516 printOperand (IC_LEFT (ic), of);
520 PRINTFUNC (picDummyRead)
523 fprintf (of, "%s ", s);
524 printOperand (IC_RIGHT (ic), of);
528 PRINTFUNC (picCritical)
532 printOperand (IC_RESULT (ic), of);
534 fprintf (of, "(stack)");
535 fprintf (of, " = %s ", s);
539 PRINTFUNC (picEndCritical)
542 fprintf (of, "%s = ", s);
544 printOperand (IC_RIGHT (ic), of);
546 fprintf (of, "(stack)");
550 /*-----------------------------------------------------------------*/
551 /* piCode - prints one iCode */
552 /*-----------------------------------------------------------------*/
554 piCode (void *item, FILE * of)
562 icTab = getTableEntry (ic->op);
563 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
564 ic->filename, ic->lineno,
565 ic->seq, ic->key, ic->depth, ic->supportRtn);
566 icTab->iCodePrint (of, ic, icTab->printName);
572 printiCChain(ic,stdout);
574 /*-----------------------------------------------------------------*/
575 /* printiCChain - prints intermediate code for humans */
576 /*-----------------------------------------------------------------*/
578 printiCChain (iCode * icChain, FILE * of)
585 for (loop = icChain; loop; loop = loop->next)
587 if ((icTab = getTableEntry (loop->op)))
589 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
590 loop->filename, loop->lineno,
591 loop->seq, loop->key, loop->depth, loop->supportRtn);
593 icTab->iCodePrint (of, loop, icTab->printName);
599 /*-----------------------------------------------------------------*/
600 /* newOperand - allocate, init & return a new iCode */
601 /*-----------------------------------------------------------------*/
607 op = Safe_alloc ( sizeof (operand));
613 /*-----------------------------------------------------------------*/
614 /* newiCode - create and return a new iCode entry initialised */
615 /*-----------------------------------------------------------------*/
617 newiCode (int op, operand * left, operand * right)
621 ic = Safe_alloc ( sizeof (iCode));
623 ic->seqPoint = seqPoint;
625 ic->filename = filename;
627 ic->level = scopeLevel;
629 ic->key = iCodeKey++;
631 IC_RIGHT (ic) = right;
636 /*-----------------------------------------------------------------*/
637 /* newiCode for conditional statements */
638 /*-----------------------------------------------------------------*/
640 newiCodeCondition (operand * condition,
646 if (IS_VOID(operandType(condition))) {
647 werror(E_VOID_VALUE_USED);
650 ic = newiCode (IFX, NULL, NULL);
651 IC_COND (ic) = condition;
652 IC_TRUE (ic) = trueLabel;
653 IC_FALSE (ic) = falseLabel;
657 /*-----------------------------------------------------------------*/
658 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
659 /*-----------------------------------------------------------------*/
661 newiCodeLabelGoto (int op, symbol * label)
665 ic = newiCode (op, NULL, NULL);
669 IC_RIGHT (ic) = NULL;
670 IC_RESULT (ic) = NULL;
674 /*-----------------------------------------------------------------*/
675 /* newiTemp - allocate & return a newItemp Variable */
676 /*-----------------------------------------------------------------*/
684 SNPRINTF (buffer, sizeof(buffer), "%s", s);
688 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
691 itmp = newSymbol (buffer, 1);
692 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
698 /*-----------------------------------------------------------------*/
699 /* newiTempLabel - creates a temp variable label */
700 /*-----------------------------------------------------------------*/
702 newiTempLabel (char *s)
706 /* check if this already exists */
707 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
712 itmplbl = newSymbol (s, 1);
716 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
717 itmplbl = newSymbol (buffer, 1);
722 itmplbl->key = labelKey++;
723 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
727 /*-----------------------------------------------------------------*/
728 /* newiTempPreheaderLabel - creates a new preheader label */
729 /*-----------------------------------------------------------------*/
731 newiTempPreheaderLabel ()
735 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
736 itmplbl = newSymbol (buffer, 1);
740 itmplbl->key = labelKey++;
741 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
746 /*-----------------------------------------------------------------*/
747 /* initiCode - initialises some iCode related stuff */
748 /*-----------------------------------------------------------------*/
755 /*-----------------------------------------------------------------*/
756 /* copyiCode - make a copy of the iCode given */
757 /*-----------------------------------------------------------------*/
759 copyiCode (iCode * ic)
761 iCode *nic = newiCode (ic->op, NULL, NULL);
763 nic->lineno = ic->lineno;
764 nic->filename = ic->filename;
765 nic->block = ic->block;
766 nic->level = ic->level;
767 nic->parmBytes = ic->parmBytes;
769 /* deal with the special cases first */
773 IC_COND (nic) = operandFromOperand (IC_COND (ic));
774 IC_TRUE (nic) = IC_TRUE (ic);
775 IC_FALSE (nic) = IC_FALSE (ic);
779 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
780 IC_JTLABELS (nic) = IC_JTLABELS (ic);
785 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
786 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
790 IC_INLINE (nic) = IC_INLINE (ic);
794 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
798 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
799 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
800 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
806 /*-----------------------------------------------------------------*/
807 /* getTableEntry - gets the table entry for the given operator */
808 /*-----------------------------------------------------------------*/
810 getTableEntry (int oper)
814 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
815 if (oper == codeTable[i].icode)
816 return &codeTable[i];
821 /*-----------------------------------------------------------------*/
822 /* newiTempOperand - new intermediate temp operand */
823 /*-----------------------------------------------------------------*/
825 newiTempOperand (sym_link * type, char throwType)
828 operand *op = newOperand ();
832 itmp = newiTemp (NULL);
834 etype = getSpec (type);
836 if (IS_LITERAL (etype))
839 /* copy the type information */
841 itmp->etype = getSpec (itmp->type = (throwType ? type :
842 copyLinkChain (type)));
843 if (IS_LITERAL (itmp->etype))
845 SPEC_SCLS (itmp->etype) = S_REGISTER;
846 SPEC_OCLS (itmp->etype) = reg;
849 op->operand.symOperand = itmp;
850 op->key = itmp->key = ++operandKey;
854 /*-----------------------------------------------------------------*/
855 /* operandType - returns the type chain for an operand */
856 /*-----------------------------------------------------------------*/
858 operandType (operand * op)
860 /* depending on type of operand */
865 return op->operand.valOperand->type;
868 return op->operand.symOperand->type;
871 return op->operand.typeOperand;
873 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
874 " operand type not known ");
875 assert (0); /* should never come here */
876 /* Just to keep the compiler happy */
877 return (sym_link *) 0;
881 /*-----------------------------------------------------------------*/
882 /* isParamterToCall - will return 1 if op is a parameter to args */
883 /*-----------------------------------------------------------------*/
885 isParameterToCall (value * args, operand * op)
889 wassert (IS_SYMOP(op));
894 isSymbolEqual (op->operand.symOperand, tval->sym))
901 /*-----------------------------------------------------------------*/
902 /* isOperandGlobal - return 1 if operand is a global variable */
903 /*-----------------------------------------------------------------*/
905 isOperandGlobal (operand * op)
914 (op->operand.symOperand->level == 0 ||
915 IS_STATIC (op->operand.symOperand->etype) ||
916 IS_EXTERN (op->operand.symOperand->etype))
923 /*-----------------------------------------------------------------*/
924 /* isOperandVolatile - return 1 if the operand is volatile */
925 /*-----------------------------------------------------------------*/
927 isOperandVolatile (operand * op, bool chkTemp)
932 if (IS_ITEMP (op) && !chkTemp)
935 opetype = getSpec (optype = operandType (op));
937 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
940 if (IS_VOLATILE (opetype))
945 /*-----------------------------------------------------------------*/
946 /* isOperandLiteral - returns 1 if an operand contains a literal */
947 /*-----------------------------------------------------------------*/
949 isOperandLiteral (operand * op)
956 opetype = getSpec (operandType (op));
958 if (IS_LITERAL (opetype))
964 /*-----------------------------------------------------------------*/
965 /* isOperandInFarSpace - will return true if operand is in farSpace */
966 /*-----------------------------------------------------------------*/
968 isOperandInFarSpace (operand * op)
978 if (!IS_TRUE_SYMOP (op))
981 etype = SPIL_LOC (op)->etype;
987 etype = getSpec (operandType (op));
989 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
992 /*-----------------------------------------------------------------*/
993 /* 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) ||
1333 retval = operandFromLit (operandLitValue (left) ==
1334 operandLitValue (right));
1337 if (IS_FIXED16X16 (let) ||
1338 IS_FIXED16X16 (ret))
1340 retval = operandFromLit (operandLitValue (left) ==
1341 operandLitValue (right));
1345 /* this op doesn't care about signedness */
1348 l = (TYPE_UDWORD) operandLitValue (left);
1349 r = (TYPE_UDWORD) operandLitValue (right);
1350 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1351 neccessary to strip them to 16 bit.
1352 Literals are reduced to their cheapest type, therefore left and
1353 right might have different types. It's neccessary to find a
1354 common type: int (used for char too) or long */
1355 if (!IS_LONG (let) &&
1361 retval = operandFromLit (l == r);
1365 retval = operandFromLit (operandLitValue (left) <
1366 operandLitValue (right));
1369 retval = operandFromLit (operandLitValue (left) <=
1370 operandLitValue (right));
1373 retval = operandFromLit (operandLitValue (left) !=
1374 operandLitValue (right));
1377 retval = operandFromLit (operandLitValue (left) >
1378 operandLitValue (right));
1381 retval = operandFromLit (operandLitValue (left) >=
1382 operandLitValue (right));
1385 retval = operandFromValue (valCastLiteral (type,
1386 (TYPE_UDWORD)operandLitValue(left) &
1387 (TYPE_UDWORD)operandLitValue(right)));
1390 retval = operandFromValue (valCastLiteral (type,
1391 (TYPE_UDWORD)operandLitValue(left) |
1392 (TYPE_UDWORD)operandLitValue(right)));
1395 retval = operandFromValue (valCastLiteral (type,
1396 (TYPE_UDWORD)operandLitValue(left) ^
1397 (TYPE_UDWORD)operandLitValue(right)));
1400 retval = operandFromLit (operandLitValue (left) &&
1401 operandLitValue (right));
1404 retval = operandFromLit (operandLitValue (left) ||
1405 operandLitValue (right));
1409 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1411 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1417 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1419 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1424 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1425 (TYPE_UDWORD)operandLitValue(right)) & 1);
1428 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1429 (TYPE_UDWORD)operandLitValue(right)) & 0xFF);
1432 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1433 (TYPE_UDWORD)operandLitValue(right)) & 0xFFFF);
1437 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1438 ((getSize (let) * 8) - 1)) & 1);
1442 retval = operandFromValue (valCastLiteral (type,
1443 -1 * operandLitValue (left)));
1447 retval = operandFromValue (valCastLiteral (type,
1449 operandLitValue (left))));
1453 retval = operandFromLit (!operandLitValue (left));
1457 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1458 " operandOperation invalid operator ");
1466 /*-----------------------------------------------------------------*/
1467 /* isOperandEqual - compares two operand & return 1 if they r = */
1468 /*-----------------------------------------------------------------*/
1470 isOperandEqual (operand * left, operand * right)
1472 /* if the pointers are equal then they are equal */
1476 /* if either of them null then false */
1477 if (!left || !right)
1480 if (left->type != right->type)
1483 if (IS_SYMOP (left) && IS_SYMOP (right))
1484 return left->key == right->key;
1486 /* if types are the same */
1490 return isSymbolEqual (left->operand.symOperand,
1491 right->operand.symOperand);
1493 return (compareType (left->operand.valOperand->type,
1494 right->operand.valOperand->type) &&
1495 (floatFromVal (left->operand.valOperand) ==
1496 floatFromVal (right->operand.valOperand)));
1498 if (compareType (left->operand.typeOperand,
1499 right->operand.typeOperand) == 1)
1506 /*-------------------------------------------------------------------*/
1507 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1508 /*-------------------------------------------------------------------*/
1510 isiCodeEqual (iCode * left, iCode * right)
1512 /* if the same pointer */
1516 /* if either of them null */
1517 if (!left || !right)
1520 /* if operand are the same */
1521 if (left->op == right->op)
1524 /* compare all the elements depending on type */
1525 if (left->op != IFX)
1527 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1529 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1535 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1537 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1539 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1548 /*-----------------------------------------------------------------*/
1549 /* newiTempFromOp - create a temp Operand with same attributes */
1550 /*-----------------------------------------------------------------*/
1552 newiTempFromOp (operand * op)
1562 nop = newiTempOperand (operandType (op), TRUE);
1563 nop->isaddr = op->isaddr;
1564 nop->isvolatile = op->isvolatile;
1565 nop->isGlobal = op->isGlobal;
1566 nop->isLiteral = op->isLiteral;
1567 nop->usesDefs = op->usesDefs;
1568 nop->isParm = op->isParm;
1572 /*-----------------------------------------------------------------*/
1573 /* operand from operand - creates an operand holder for the type */
1574 /*-----------------------------------------------------------------*/
1576 operandFromOperand (operand * op)
1582 nop = newOperand ();
1583 nop->type = op->type;
1584 nop->isaddr = op->isaddr;
1586 nop->isvolatile = op->isvolatile;
1587 nop->isGlobal = op->isGlobal;
1588 nop->isLiteral = op->isLiteral;
1589 nop->usesDefs = op->usesDefs;
1590 nop->isParm = op->isParm;
1595 nop->operand.symOperand = op->operand.symOperand;
1598 nop->operand.valOperand = op->operand.valOperand;
1601 nop->operand.typeOperand = op->operand.typeOperand;
1608 /*-----------------------------------------------------------------*/
1609 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1610 /*-----------------------------------------------------------------*/
1612 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1614 operand *nop = operandFromOperand (op);
1616 if (nop->type == SYMBOL)
1618 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1619 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1625 /*-----------------------------------------------------------------*/
1626 /* operandFromSymbol - creates an operand from a symbol */
1627 /*-----------------------------------------------------------------*/
1629 operandFromSymbol (symbol * sym)
1634 /* if the symbol's type is a literal */
1635 /* then it is an enumerator type */
1636 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1637 return operandFromValue (valFromType (sym->etype));
1640 sym->key = ++operandKey;
1642 /* if this an implicit variable, means struct/union */
1643 /* member so just return it */
1644 if (sym->implicit || IS_FUNC (sym->type))
1648 op->operand.symOperand = sym;
1650 op->isvolatile = isOperandVolatile (op, TRUE);
1651 op->isGlobal = isOperandGlobal (op);
1655 /* under the following conditions create a
1656 register equivalent for a local symbol */
1657 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1658 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1660 (!(options.model == MODEL_FLAT24)) ) &&
1661 options.stackAuto == 0)
1664 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1665 !IS_FUNC (sym->type) && /* not a function */
1666 !sym->_isparm && /* not a parameter */
1667 IS_AUTO (sym) && /* is a local auto variable */
1668 !sym->addrtaken && /* whose address has not been taken */
1669 !sym->reqv && /* does not already have a reg equivalence */
1670 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1671 !sym->islbl && /* not a label */
1672 ok /* farspace check */
1676 /* we will use it after all optimizations
1677 and before liveRange calculation */
1678 sym->reqv = newiTempOperand (sym->type, 0);
1679 sym->reqv->key = sym->key;
1680 OP_SYMBOL (sym->reqv)->prereqv = sym;
1681 OP_SYMBOL (sym->reqv)->key = sym->key;
1682 OP_SYMBOL (sym->reqv)->isreqv = 1;
1683 OP_SYMBOL (sym->reqv)->islocal = 1;
1684 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1685 SPIL_LOC (sym->reqv) = sym;
1688 if (!IS_AGGREGATE (sym->type))
1692 op->operand.symOperand = sym;
1695 op->isvolatile = isOperandVolatile (op, TRUE);
1696 op->isGlobal = isOperandGlobal (op);
1697 op->isPtr = IS_PTR (operandType (op));
1698 op->isParm = sym->_isparm;
1703 /* itemp = &[_symbol] */
1705 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1706 IC_LEFT (ic)->type = SYMBOL;
1707 IC_LEFT (ic)->operand.symOperand = sym;
1708 IC_LEFT (ic)->key = sym->key;
1709 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1710 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1711 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1714 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1715 if (IS_ARRAY (sym->type))
1717 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1718 IC_RESULT (ic)->isaddr = 0;
1721 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1725 return IC_RESULT (ic);
1728 /*-----------------------------------------------------------------*/
1729 /* operandFromValue - creates an operand from value */
1730 /*-----------------------------------------------------------------*/
1732 operandFromValue (value * val)
1736 /* if this is a symbol then do the symbol thing */
1738 return operandFromSymbol (val->sym);
1740 /* this is not a symbol */
1743 op->operand.valOperand = val;
1744 op->isLiteral = isOperandLiteral (op);
1748 /*-----------------------------------------------------------------*/
1749 /* operandFromLink - operand from typeChain */
1750 /*-----------------------------------------------------------------*/
1752 operandFromLink (sym_link * type)
1756 /* operand from sym_link */
1762 op->operand.typeOperand = copyLinkChain (type);
1766 /*-----------------------------------------------------------------*/
1767 /* operandFromLit - makes an operand from a literal value */
1768 /*-----------------------------------------------------------------*/
1770 operandFromLit (double i)
1772 return operandFromValue (valueFromLit (i));
1775 /*-----------------------------------------------------------------*/
1776 /* operandFromAst - creates an operand from an ast */
1777 /*-----------------------------------------------------------------*/
1779 operandFromAst (ast * tree,int lvl)
1785 /* depending on type do */
1789 return ast2iCode (tree,lvl+1);
1793 return operandFromValue (tree->opval.val);
1797 return operandFromLink (tree->opval.lnk);
1804 /* Just to keep the compiler happy */
1805 return (operand *) 0;
1808 /*-----------------------------------------------------------------*/
1809 /* setOperandType - sets the operand's type to the given type */
1810 /*-----------------------------------------------------------------*/
1812 setOperandType (operand * op, sym_link * type)
1814 /* depending on the type of operand */
1819 op->operand.valOperand->etype =
1820 getSpec (op->operand.valOperand->type =
1821 copyLinkChain (type));
1825 if (op->operand.symOperand->isitmp)
1826 op->operand.symOperand->etype =
1827 getSpec (op->operand.symOperand->type =
1828 copyLinkChain (type));
1830 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1831 "attempt to modify type of source");
1835 op->operand.typeOperand = copyLinkChain (type);
1841 /*-----------------------------------------------------------------*/
1842 /* Get size in byte of ptr need to access an array */
1843 /*-----------------------------------------------------------------*/
1845 getArraySizePtr (operand * op)
1847 sym_link *ltype = operandType(op);
1851 int size = getSize(ltype);
1852 return((IS_GENPTR(ltype) && GPTRSIZE > FPTRSIZE) ? (size-1) : size);
1857 sym_link *letype = getSpec(ltype);
1858 switch (PTR_TYPE (SPEC_OCLS (letype)))
1870 if (GPTRSIZE > FPTRSIZE)
1871 return (GPTRSIZE-1);
1882 /*-----------------------------------------------------------------*/
1883 /* perform "usual unary conversions" */
1884 /*-----------------------------------------------------------------*/
1887 usualUnaryConversions (operand * op)
1889 if (IS_INTEGRAL (operandType (op)))
1891 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1894 return geniCodeCast (INTTYPE, op, TRUE);
1901 /*-----------------------------------------------------------------*/
1902 /* perform "usual binary conversions" */
1903 /*-----------------------------------------------------------------*/
1906 usualBinaryConversions (operand ** op1, operand ** op2,
1907 RESULT_TYPE resultType, int op)
1910 sym_link *rtype = operandType (*op2);
1911 sym_link *ltype = operandType (*op1);
1913 ctype = computeType (ltype, rtype, resultType, op);
1920 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1922 /* one byte operations: keep signedness for code generator */
1930 *op1 = geniCodeCast (ctype, *op1, TRUE);
1931 *op2 = geniCodeCast (ctype, *op2, TRUE);
1936 /*-----------------------------------------------------------------*/
1937 /* geniCodeValueAtAddress - generate intermeditate code for value */
1939 /*-----------------------------------------------------------------*/
1941 geniCodeRValue (operand * op, bool force)
1944 sym_link *type = operandType (op);
1945 sym_link *etype = getSpec (type);
1947 /* if this is an array & already */
1948 /* an address then return this */
1949 if (IS_AGGREGATE (type) ||
1950 (IS_PTR (type) && !force && !op->isaddr))
1951 return operandFromOperand (op);
1953 /* if this is not an address then must be */
1954 /* rvalue already so return this one */
1958 /* if this is not a temp symbol then */
1959 if (!IS_ITEMP (op) &&
1961 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1963 op = operandFromOperand (op);
1968 if (IS_SPEC (type) &&
1969 IS_TRUE_SYMOP (op) &&
1970 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1971 (options.model == MODEL_FLAT24) ))
1973 op = operandFromOperand (op);
1978 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1979 if (IS_PTR (type) && op->isaddr && force)
1982 type = copyLinkChain (type);
1984 IC_RESULT (ic) = newiTempOperand (type, 1);
1985 IC_RESULT (ic)->isaddr = 0;
1987 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1991 return IC_RESULT (ic);
1994 /*-----------------------------------------------------------------*/
1995 /* geniCodeCast - changes the value from one type to another */
1996 /*-----------------------------------------------------------------*/
1998 geniCodeCast (sym_link * type, operand * op, bool implicit)
2002 sym_link *opetype = getSpec (optype = operandType (op));
2006 /* one of them has size zero then error */
2007 if (IS_VOID (optype))
2009 werror (E_CAST_ZERO);
2013 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
2015 geniCodeArray2Ptr (op);
2019 /* if the operand is already the desired type then do nothing */
2020 if (compareType (type, optype) == 1)
2023 /* if this is a literal then just change the type & return */
2024 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
2026 return operandFromValue (valCastLiteral (type,
2027 operandLitValue (op)));
2030 /* if casting to/from pointers, do some checking */
2031 if (IS_PTR(type)) { // to a pointer
2032 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
2033 if (IS_INTEGRAL(optype)) {
2034 // maybe this is NULL, than it's ok.
2035 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
2036 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
2037 // no way to set the storage
2038 if (IS_LITERAL(optype)) {
2039 werror(E_LITERAL_GENERIC);
2042 werror(E_NONPTR2_GENPTR);
2045 } else if (implicit) {
2046 werror(W_INTEGRAL2PTR_NOCAST);
2051 // shouldn't do that with float, array or structure unless to void
2052 if (!IS_VOID(getSpec(type)) &&
2053 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2054 werror(E_INCOMPAT_TYPES);
2058 } else { // from a pointer to a pointer
2059 if (IS_GENPTR(type) && IS_VOID(type->next))
2060 { // cast to void* is always allowed
2062 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
2063 { // cast from void* is always allowed
2065 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2066 // if not a pointer to a function
2067 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2068 if (implicit) { // if not to generic, they have to match
2069 if (!IS_GENPTR(type) &&
2070 !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
2071 ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
2075 werror(E_INCOMPAT_PTYPES);
2082 } else { // to a non pointer
2083 if (IS_PTR(optype)) { // from a pointer
2084 if (implicit) { // sneaky
2085 if (IS_INTEGRAL(type)) {
2086 werror(W_PTR2INTEGRAL_NOCAST);
2088 } else { // shouldn't do that with float, array or structure
2089 werror(E_INCOMPAT_TYPES);
2096 printFromToType (optype, type);
2099 /* if they are the same size create an assignment */
2101 /* This seems very dangerous to me, since there are several */
2102 /* optimizations (for example, gcse) that don't notice the */
2103 /* cast hidden in this assignement and may simplify an */
2104 /* iCode to use the original (uncasted) operand. */
2105 /* Unfortunately, other things break when this cast is */
2106 /* made explicit. Need to fix this someday. */
2107 /* -- EEP, 2004/01/21 */
2108 if (getSize (type) == getSize (optype) &&
2109 !IS_BITFIELD (type) &&
2111 !IS_FLOAT (optype) &&
2113 !IS_FIXED (optype) &&
2114 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2115 (!IS_SPEC (type) && !IS_SPEC (optype))))
2117 ic = newiCode ('=', NULL, op);
2118 IC_RESULT (ic) = newiTempOperand (type, 0);
2119 if (IS_TRUE_SYMOP (op) && !IS_VOLATILE (optype))
2120 SPIL_LOC (IC_RESULT (ic)) = OP_SYMBOL (op);
2121 IC_RESULT (ic)->isaddr = 0;
2125 ic = newiCode (CAST, operandFromLink (type),
2126 geniCodeRValue (op, FALSE));
2128 IC_RESULT (ic) = newiTempOperand (type, 0);
2131 /* preserve the storage class & output class */
2132 /* of the original variable */
2133 restype = getSpec (operandType (IC_RESULT (ic)));
2134 if (!IS_LITERAL(opetype) &&
2137 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2138 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2141 return IC_RESULT (ic);
2144 /*-----------------------------------------------------------------*/
2145 /* geniCodeLabel - will create a Label */
2146 /*-----------------------------------------------------------------*/
2148 geniCodeLabel (symbol * label)
2152 ic = newiCodeLabelGoto (LABEL, label);
2156 /*-----------------------------------------------------------------*/
2157 /* geniCodeGoto - will create a Goto */
2158 /*-----------------------------------------------------------------*/
2160 geniCodeGoto (symbol * label)
2164 ic = newiCodeLabelGoto (GOTO, label);
2168 /*-----------------------------------------------------------------*/
2169 /* geniCodeMultiply - gen intermediate code for multiplication */
2170 /*-----------------------------------------------------------------*/
2172 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2179 /* if they are both literal then we know the result */
2180 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2181 return operandFromValue (valMult (left->operand.valOperand,
2182 right->operand.valOperand));
2184 if (IS_LITERAL(retype)) {
2185 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2188 resType = usualBinaryConversions (&left, &right, resultType, '*');
2190 rtype = operandType (right);
2191 retype = getSpec (rtype);
2192 ltype = operandType (left);
2193 letype = getSpec (ltype);
2196 /* if the right is a literal & power of 2 */
2197 /* then make it a left shift */
2198 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2199 efficient in most cases than 2 bytes result = 2 bytes << literal
2200 if port has 1 byte muldiv */
2201 if (p2 && !IS_FLOAT (letype) && !IS_FIXED (letype)
2202 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2203 && (port->support.muldiv == 1))
2204 && strcmp (port->target, "pic16") != 0 /* don't shift for pic */
2205 && strcmp (port->target, "pic14") != 0)
2207 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2209 /* LEFT_OP need same size for left and result, */
2210 left = geniCodeCast (resType, left, TRUE);
2211 ltype = operandType (left);
2213 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2217 ic = newiCode ('*', left, right); /* normal multiplication */
2218 /* if the size left or right > 1 then support routine */
2219 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2223 IC_RESULT (ic) = newiTempOperand (resType, 1);
2226 return IC_RESULT (ic);
2229 /*-----------------------------------------------------------------*/
2230 /* geniCodeDivision - gen intermediate code for division */
2231 /*-----------------------------------------------------------------*/
2233 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2238 sym_link *rtype = operandType (right);
2239 sym_link *retype = getSpec (rtype);
2240 sym_link *ltype = operandType (left);
2241 sym_link *letype = getSpec (ltype);
2243 resType = usualBinaryConversions (&left, &right, resultType, '/');
2245 /* if the right is a literal & power of 2
2246 and left is unsigned then make it a
2248 if (IS_LITERAL (retype) &&
2249 !IS_FLOAT (letype) &&
2250 !IS_FIXED (letype) &&
2251 IS_UNSIGNED(letype) &&
2252 (p2 = powof2 ((TYPE_UDWORD)
2253 floatFromVal (right->operand.valOperand)))) {
2254 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2258 ic = newiCode ('/', left, right); /* normal division */
2259 /* if the size left or right > 1 then support routine */
2260 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2263 IC_RESULT (ic) = newiTempOperand (resType, 0);
2266 return IC_RESULT (ic);
2268 /*-----------------------------------------------------------------*/
2269 /* geniCodeModulus - gen intermediate code for modulus */
2270 /*-----------------------------------------------------------------*/
2272 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2278 /* if they are both literal then we know the result */
2279 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2280 return operandFromValue (valMod (left->operand.valOperand,
2281 right->operand.valOperand));
2283 resType = usualBinaryConversions (&left, &right, resultType, '%');
2285 /* now they are the same size */
2286 ic = newiCode ('%', left, right);
2288 /* if the size left or right > 1 then support routine */
2289 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2291 IC_RESULT (ic) = newiTempOperand (resType, 0);
2294 return IC_RESULT (ic);
2297 /*-----------------------------------------------------------------*/
2298 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2299 /*-----------------------------------------------------------------*/
2301 geniCodePtrPtrSubtract (operand * left, operand * right)
2307 /* if they are both literals then */
2308 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2310 result = operandFromValue (valMinus (left->operand.valOperand,
2311 right->operand.valOperand));
2315 ic = newiCode ('-', left, right);
2317 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2321 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2325 // should we really do this? is this ANSI?
2326 return geniCodeDivision (result,
2327 operandFromLit (getSize (ltype->next)),
2331 /*-----------------------------------------------------------------*/
2332 /* geniCodeSubtract - generates code for subtraction */
2333 /*-----------------------------------------------------------------*/
2335 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2342 /* if they both pointers then */
2343 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2344 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2345 return geniCodePtrPtrSubtract (left, right);
2347 /* if they are both literal then we know the result */
2348 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2349 && left->isLiteral && right->isLiteral)
2350 return operandFromValue (valMinus (left->operand.valOperand,
2351 right->operand.valOperand));
2353 /* if left is an array or pointer */
2354 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2356 isarray = left->isaddr;
2357 right = geniCodeMultiply (right,
2358 operandFromLit (getSize (ltype->next)),
2359 (getArraySizePtr(left) >= INTSIZE) ?
2362 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2365 { /* make them the same size */
2366 resType = usualBinaryConversions (&left, &right, resultType, '-');
2369 ic = newiCode ('-', left, right);
2371 IC_RESULT (ic) = newiTempOperand (resType, 1);
2372 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2374 /* if left or right is a float */
2375 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2376 || IS_FIXED (ltype) || IS_FIXED (rtype))
2380 return IC_RESULT (ic);
2383 /*-----------------------------------------------------------------*/
2384 /* geniCodeAdd - generates iCode for addition */
2385 /*-----------------------------------------------------------------*/
2387 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2396 /* if the right side is LITERAL zero */
2397 /* return the left side */
2398 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2401 /* if left is literal zero return right */
2402 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2405 /* if left is a pointer then size */
2406 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2408 isarray = left->isaddr;
2409 // there is no need to multiply with 1
2410 if (getSize (ltype->next) != 1)
2412 size = operandFromLit (getSize (ltype->next));
2413 SPEC_USIGN (getSpec (operandType (size))) = 1;
2414 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2415 right = geniCodeMultiply (right,
2417 (getArraySizePtr(left) >= INTSIZE) ?
2420 /* Even if right is a 'unsigned char',
2421 the result will be a 'signed int' due to the promotion rules.
2422 It doesn't make sense when accessing arrays, so let's fix it here: */
2424 SPEC_USIGN (getSpec (operandType (right))) = 1;
2426 resType = copyLinkChain (ltype);
2429 { // make them the same size
2430 resType = usualBinaryConversions (&left, &right, resultType, '+');
2433 /* if they are both literals then we know */
2434 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2435 && left->isLiteral && right->isLiteral)
2436 return operandFromValue (valPlus (valFromType (ltype),
2437 valFromType (rtype)));
2439 ic = newiCode ('+', left, right);
2441 IC_RESULT (ic) = newiTempOperand (resType, 1);
2442 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2444 /* if left or right is a float then support
2446 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2447 || IS_FIXED (ltype) || IS_FIXED (rtype))
2452 return IC_RESULT (ic);
2456 /*-----------------------------------------------------------------*/
2457 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2458 /*-----------------------------------------------------------------*/
2460 aggrToPtr (sym_link * type, bool force)
2465 if (IS_PTR (type) && !force)
2468 etype = getSpec (type);
2469 ptype = newLink (DECLARATOR);
2473 /* set the pointer depending on the storage class */
2474 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2478 /*------------------------------------------------------------------*/
2479 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2480 /*------------------------------------------------------------------*/
2482 aggrToPtrDclType (sym_link * type, bool force)
2484 if (IS_PTR (type) && !force)
2485 return DCL_TYPE (type);
2487 /* return the pointer depending on the storage class */
2488 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2491 /*-----------------------------------------------------------------*/
2492 /* geniCodeArray2Ptr - array to pointer */
2493 /*-----------------------------------------------------------------*/
2495 geniCodeArray2Ptr (operand * op)
2497 sym_link *optype = operandType (op);
2498 sym_link *opetype = getSpec (optype);
2500 /* set the pointer depending on the storage class */
2501 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2508 /*-----------------------------------------------------------------*/
2509 /* geniCodeArray - array access */
2510 /*-----------------------------------------------------------------*/
2512 geniCodeArray (operand * left, operand * right, int lvl)
2516 sym_link *ltype = operandType (left);
2521 if (IS_PTR (ltype->next) && left->isaddr)
2523 left = geniCodeRValue (left, FALSE);
2526 return geniCodeDerefPtr (geniCodeAdd (left,
2528 (getArraySizePtr(left) >= INTSIZE) ?
2534 size = operandFromLit (getSize (ltype->next));
2535 SPEC_USIGN (getSpec (operandType (size))) = 1;
2536 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2537 right = geniCodeMultiply (right,
2539 (getArraySizePtr(left) >= INTSIZE) ?
2542 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2543 It doesn't make sense when accessing arrays, so let's fix it here: */
2545 SPEC_USIGN (getSpec (operandType (right))) = 1;
2546 /* we can check for limits here */
2547 /* already done in SDCCast.c
2548 if (isOperandLiteral (right) &&
2551 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2553 werror (W_IDX_OUT_OF_BOUNDS,
2554 (int) operandLitValue (right) / getSize (ltype->next),
2559 ic = newiCode ('+', left, right);
2561 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2562 !IS_AGGREGATE (ltype->next) &&
2563 !IS_PTR (ltype->next))
2564 ? ltype : ltype->next), 0);
2566 if (!IS_AGGREGATE (ltype->next))
2568 IC_RESULT (ic)->isaddr = 1;
2569 IC_RESULT (ic)->aggr2ptr = 1;
2573 return IC_RESULT (ic);
2576 /*-----------------------------------------------------------------*/
2577 /* geniCodeStruct - generates intermediate code for structures */
2578 /*-----------------------------------------------------------------*/
2580 geniCodeStruct (operand * left, operand * right, bool islval)
2583 sym_link *type = operandType (left);
2584 sym_link *etype = getSpec (type);
2586 symbol *element = getStructElement (SPEC_STRUCT (etype),
2587 right->operand.symOperand);
2589 wassert(IS_SYMOP(right));
2591 /* add the offset */
2592 ic = newiCode ('+', left, operandFromLit (element->offset));
2594 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2596 /* preserve the storage & output class of the struct */
2597 /* as well as the volatile attribute */
2598 retype = getSpec (operandType (IC_RESULT (ic)));
2599 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2600 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2601 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2602 SPEC_CONST (retype) |= SPEC_CONST (etype);
2604 if (IS_PTR (element->type))
2605 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2607 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2610 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2613 /*-----------------------------------------------------------------*/
2614 /* geniCodePostInc - generate int code for Post increment */
2615 /*-----------------------------------------------------------------*/
2617 geniCodePostInc (operand * op)
2621 sym_link *optype = operandType (op);
2623 operand *rv = (IS_ITEMP (op) ?
2624 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2626 sym_link *rvtype = operandType (rv);
2629 /* if this is not an address we have trouble */
2632 werror (E_LVALUE_REQUIRED, "++");
2636 rOp = newiTempOperand (rvtype, 0);
2637 OP_SYMBOL(rOp)->noSpilLoc = 1;
2640 OP_SYMBOL(rv)->noSpilLoc = 1;
2642 geniCodeAssign (rOp, rv, 0, 0);
2644 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2646 werror(W_SIZEOF_VOID);
2647 if (IS_FLOAT (rvtype))
2648 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2650 if (IS_FIXED16X16 (rvtype))
2651 ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
2653 ic = newiCode ('+', rv, operandFromLit (size));
2655 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2658 geniCodeAssign (op, result, 0, 0);
2664 /*-----------------------------------------------------------------*/
2665 /* geniCodePreInc - generate code for preIncrement */
2666 /*-----------------------------------------------------------------*/
2668 geniCodePreInc (operand * op, bool lvalue)
2671 sym_link *optype = operandType (op);
2672 operand *rop = (IS_ITEMP (op) ?
2673 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2675 sym_link *roptype = operandType (rop);
2681 werror (E_LVALUE_REQUIRED, "++");
2685 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2687 werror(W_SIZEOF_VOID);
2688 if (IS_FLOAT (roptype))
2689 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2691 if (IS_FIXED16X16 (roptype))
2692 ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
2694 ic = newiCode ('+', rop, operandFromLit (size));
2695 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2698 (void) geniCodeAssign (op, result, 0, 0);
2699 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2705 /*-----------------------------------------------------------------*/
2706 /* geniCodePostDec - generates code for Post decrement */
2707 /*-----------------------------------------------------------------*/
2709 geniCodePostDec (operand * op)
2713 sym_link *optype = operandType (op);
2715 operand *rv = (IS_ITEMP (op) ?
2716 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2718 sym_link *rvtype = operandType (rv);
2721 /* if this is not an address we have trouble */
2724 werror (E_LVALUE_REQUIRED, "--");
2728 rOp = newiTempOperand (rvtype, 0);
2729 OP_SYMBOL(rOp)->noSpilLoc = 1;
2732 OP_SYMBOL(rv)->noSpilLoc = 1;
2734 geniCodeAssign (rOp, rv, 0, 0);
2736 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2738 werror(W_SIZEOF_VOID);
2739 if (IS_FLOAT (rvtype))
2740 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2742 if (IS_FIXED16X16 (rvtype))
2743 ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
2745 ic = newiCode ('-', rv, operandFromLit (size));
2747 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2750 geniCodeAssign (op, result, 0, 0);
2756 /*-----------------------------------------------------------------*/
2757 /* geniCodePreDec - generate code for pre decrement */
2758 /*-----------------------------------------------------------------*/
2760 geniCodePreDec (operand * op, bool lvalue)
2763 sym_link *optype = operandType (op);
2764 operand *rop = (IS_ITEMP (op) ?
2765 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2767 sym_link *roptype = operandType (rop);
2773 werror (E_LVALUE_REQUIRED, "--");
2777 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2779 werror(W_SIZEOF_VOID);
2780 if (IS_FLOAT (roptype))
2781 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2783 if (IS_FIXED16X16 (roptype))
2784 ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
2786 ic = newiCode ('-', rop, operandFromLit (size));
2787 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2790 (void) geniCodeAssign (op, result, 0, 0);
2791 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2798 /*-----------------------------------------------------------------*/
2799 /* geniCodeBitwise - gen int code for bitWise operators */
2800 /*-----------------------------------------------------------------*/
2802 geniCodeBitwise (operand * left, operand * right,
2803 int oper, sym_link * resType)
2807 left = geniCodeCast (resType, left, TRUE);
2808 right = geniCodeCast (resType, right, TRUE);
2810 ic = newiCode (oper, left, right);
2811 IC_RESULT (ic) = newiTempOperand (resType, 0);
2814 return IC_RESULT (ic);
2817 /*-----------------------------------------------------------------*/
2818 /* geniCodeAddressOf - gens icode for '&' address of operator */
2819 /*-----------------------------------------------------------------*/
2821 geniCodeAddressOf (operand * op)
2825 sym_link *optype = operandType (op);
2826 sym_link *opetype = getSpec (optype);
2828 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2830 op = operandFromOperand (op);
2835 /* lvalue check already done in decorateType */
2836 /* this must be a lvalue */
2837 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2838 /* werror (E_LVALUE_REQUIRED,"&"); */
2842 p = newLink (DECLARATOR);
2844 /* set the pointer depending on the storage class */
2845 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2847 p->next = copyLinkChain (optype);
2849 /* if already a temp */
2852 setOperandType (op, p);
2857 /* other wise make this of the type coming in */
2858 ic = newiCode (ADDRESS_OF, op, NULL);
2859 IC_RESULT (ic) = newiTempOperand (p, 1);
2860 IC_RESULT (ic)->isaddr = 0;
2862 return IC_RESULT (ic);
2864 /*-----------------------------------------------------------------*/
2865 /* setOClass - sets the output class depending on the pointer type */
2866 /*-----------------------------------------------------------------*/
2868 setOClass (sym_link * ptr, sym_link * spec)
2870 switch (DCL_TYPE (ptr))
2873 SPEC_OCLS (spec) = data;
2877 SPEC_OCLS (spec) = generic;
2881 SPEC_OCLS (spec) = xdata;
2885 SPEC_OCLS (spec) = code;
2889 SPEC_OCLS (spec) = idata;
2893 SPEC_OCLS (spec) = xstack;
2897 SPEC_OCLS (spec) = eeprom;
2906 /*-----------------------------------------------------------------*/
2907 /* geniCodeDerefPtr - dereference pointer with '*' */
2908 /*-----------------------------------------------------------------*/
2910 geniCodeDerefPtr (operand * op,int lvl)
2912 sym_link *rtype, *retype;
2913 sym_link *optype = operandType (op);
2915 // if this is an array then array access
2916 if (IS_ARRAY (optype)) {
2917 // don't worry, this will be optimized out later
2918 return geniCodeArray (op, operandFromLit (0), lvl);
2921 // just in case someone screws up
2922 wassert (IS_PTR (optype));
2924 if (IS_TRUE_SYMOP (op))
2927 op = geniCodeRValue (op, TRUE);
2930 /* now get rid of the pointer part */
2931 if (isLvaluereq(lvl) && IS_ITEMP (op))
2933 retype = getSpec (rtype = copyLinkChain (optype));
2937 retype = getSpec (rtype = copyLinkChain (optype->next));
2938 /* outputclass needs 2b updated */
2939 setOClass (optype, retype);
2942 op->isGptr = IS_GENPTR (optype);
2944 op->isaddr = (IS_PTR (rtype) ||
2945 IS_STRUCT (rtype) ||
2951 if (!isLvaluereq(lvl))
2952 op = geniCodeRValue (op, TRUE);
2954 setOperandType (op, rtype);
2959 /*-----------------------------------------------------------------*/
2960 /* geniCodeUnaryMinus - does a unary minus of the operand */
2961 /*-----------------------------------------------------------------*/
2963 geniCodeUnaryMinus (operand * op)
2966 sym_link *optype = operandType (op);
2968 if (IS_LITERAL (optype))
2969 return operandFromLit (-floatFromVal (op->operand.valOperand));
2971 ic = newiCode (UNARYMINUS, op, NULL);
2972 IC_RESULT (ic) = newiTempOperand (optype, 0);
2974 return IC_RESULT (ic);
2977 /*-----------------------------------------------------------------*/
2978 /* geniCodeLeftShift - gen i code for left shift */
2979 /*-----------------------------------------------------------------*/
2981 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2986 ic = newiCode (LEFT_OP, left, right);
2988 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2989 IC_RESULT (ic) = newiTempOperand (resType, 0);
2991 return IC_RESULT (ic);
2994 /*-----------------------------------------------------------------*/
2995 /* geniCodeRightShift - gen i code for right shift */
2996 /*-----------------------------------------------------------------*/
2998 geniCodeRightShift (operand * left, operand * right)
3002 ic = newiCode (RIGHT_OP, left, right);
3003 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3005 return IC_RESULT (ic);
3008 /*-----------------------------------------------------------------*/
3009 /* geniCodeLogic- logic code */
3010 /*-----------------------------------------------------------------*/
3012 geniCodeLogic (operand * left, operand * right, int op)
3016 sym_link *rtype = operandType (right);
3017 sym_link *ltype = operandType (left);
3019 /* left is integral type and right is literal then
3020 check if the literal value is within bounds */
3021 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
3023 checkConstantRange(ltype,
3024 OP_VALUE(right), "compare operation", 1);
3027 /* if one operand is a pointer and the other is a literal generic void pointer,
3028 change the type of the literal generic void pointer to match the other pointer */
3029 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
3030 && IS_PTR (rtype) && !IS_GENPTR(rtype))
3032 /* find left's definition */
3033 ic = (iCode *) setFirstItem (iCodeChain);
3036 if (((ic->op == CAST) || (ic->op == '='))
3037 && isOperandEqual(left, IC_RESULT (ic)))
3040 ic = setNextItem (iCodeChain);
3042 /* if casting literal to generic pointer, then cast to rtype instead */
3043 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3045 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
3046 ltype = operandType(left);
3049 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
3050 && IS_PTR (ltype) && !IS_GENPTR(ltype))
3052 /* find right's definition */
3053 ic = (iCode *) setFirstItem (iCodeChain);
3056 if (((ic->op == CAST) || (ic->op == '='))
3057 && isOperandEqual(right, IC_RESULT (ic)))
3060 ic = setNextItem (iCodeChain);
3062 /* if casting literal to generic pointer, then cast to rtype instead */
3063 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3065 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
3066 rtype = operandType(right);
3070 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
3072 ic = newiCode (op, left, right);
3073 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
3075 /* if comparing float
3076 and not a '==' || '!=' || '&&' || '||' (these
3078 if (IS_FLOAT(ctype) &&
3085 /* if comparing a fixed type use support functions */
3086 if (IS_FIXED(ctype))
3090 return IC_RESULT (ic);
3093 /*-----------------------------------------------------------------*/
3094 /* geniCodeLogicAndOr - && || operations */
3095 /*-----------------------------------------------------------------*/
3097 geniCodeLogicAndOr (ast *tree, int lvl)
3101 symbol *falseLabel = newiTempLabel (NULL);
3102 symbol *trueLabel = newiTempLabel (NULL);
3103 symbol *exitLabel = newiTempLabel (NULL);
3104 operand *op, *result, *condition;
3106 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3107 They can be reenabled by executing the following block. If you find
3108 a decent optimization you could start right here:
3113 operand *leftOp, *rightOp;
3115 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3116 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3118 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3122 /* generate two IFX for the '&&' or '||' op */
3124 /* evaluate left operand */
3125 condition = ast2iCode (tree->left, lvl + 1);
3126 op = geniCodeRValue (condition, FALSE);
3128 /* test left operand */
3129 if (tree->opval.op == AND_OP)
3130 ic = newiCodeCondition (op, NULL, falseLabel);
3132 ic = newiCodeCondition (op, trueLabel, NULL);
3135 /* evaluate right operand */
3136 condition = ast2iCode (tree->right, lvl + 1);
3137 op = geniCodeRValue (condition, FALSE);
3139 /* test right operand */
3140 ic = newiCodeCondition (op, trueLabel, NULL);
3143 /* store 0 or 1 in result */
3144 type = (SPEC_NOUN(tree->ftype) == V_BIT) ? newBoolLink() : newCharLink();
3145 result = newiTempOperand (type, 1);
3147 geniCodeLabel (falseLabel);
3148 geniCodeAssign (result, operandFromLit (0), 0, 0);
3149 /* generate an unconditional goto */
3150 geniCodeGoto (exitLabel);
3152 geniCodeLabel (trueLabel);
3153 geniCodeAssign (result, operandFromLit (1), 0, 0);
3155 geniCodeLabel (exitLabel);
3160 /*-----------------------------------------------------------------*/
3161 /* geniCodeUnary - for a generic unary operation */
3162 /*-----------------------------------------------------------------*/
3164 geniCodeUnary (operand * op, int oper)
3166 iCode *ic = newiCode (oper, op, NULL);
3168 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3170 return IC_RESULT (ic);
3173 /*-----------------------------------------------------------------*/
3174 /* geniCodeBinary - for a generic binary operation */
3175 /*-----------------------------------------------------------------*/
3177 geniCodeBinary (operand * left, operand * right, int oper)
3179 iCode *ic = newiCode (oper, left, right);
3181 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3183 return IC_RESULT (ic);
3186 /*-----------------------------------------------------------------*/
3187 /* geniCodeConditional - geniCode for '?' ':' operation */
3188 /*-----------------------------------------------------------------*/
3190 geniCodeConditional (ast * tree,int lvl)
3193 symbol *falseLabel = newiTempLabel (NULL);
3194 symbol *exitLabel = newiTempLabel (NULL);
3195 operand *cond = ast2iCode (tree->left,lvl+1);
3196 operand *true, *false, *result;
3198 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3202 true = ast2iCode (tree->right->left,lvl+1);
3204 /* move the value to a new Operand */
3205 result = newiTempOperand (tree->right->ftype, 0);
3206 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3208 /* generate an unconditional goto */
3209 geniCodeGoto (exitLabel);
3211 /* now for the right side */
3212 geniCodeLabel (falseLabel);
3214 false = ast2iCode (tree->right->right,lvl+1);
3215 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3217 /* create the exit label */
3218 geniCodeLabel (exitLabel);
3223 /*-----------------------------------------------------------------*/
3224 /* geniCodeAssign - generate code for assignment */
3225 /*-----------------------------------------------------------------*/
3227 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3230 sym_link *ltype = operandType (left);
3231 sym_link *rtype = operandType (right);
3233 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3235 werror (E_LVALUE_REQUIRED, "assignment");
3239 /* left is integral type and right is literal then
3240 check if the literal value is within bounds */
3241 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3243 checkConstantRange(ltype,
3244 OP_VALUE(right), "= operation", 0);
3247 /* if the left & right type don't exactly match */
3248 /* if pointer set then make sure the check is
3249 done with the type & not the pointer */
3250 /* then cast rights type to left */
3252 /* first check the type for pointer assignement */
3253 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3254 compareType (ltype, rtype) <= 0)
3256 if (compareType (ltype->next, rtype) < 0)
3257 right = geniCodeCast (ltype->next, right, TRUE);
3259 else if (compareType (ltype, rtype) < 0)
3260 right = geniCodeCast (ltype, right, TRUE);
3262 /* If left is a true symbol & ! volatile
3263 create an assignment to temporary for
3264 the right & then assign this temporary
3265 to the symbol. This is SSA (static single
3266 assignment). Isn't it simple and folks have
3267 published mountains of paper on it */
3268 if (IS_TRUE_SYMOP (left) &&
3269 !isOperandVolatile (left, FALSE) &&
3270 isOperandGlobal (left))
3274 if (IS_TRUE_SYMOP (right))
3275 sym = OP_SYMBOL (right);
3276 ic = newiCode ('=', NULL, right);
3277 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3278 SPIL_LOC (right) = sym;
3282 ic = newiCode ('=', NULL, right);
3283 IC_RESULT (ic) = left;
3286 /* if left isgptr flag is set then support
3287 routine will be required */
3291 ic->nosupdate = nosupdate;
3295 /*-----------------------------------------------------------------*/
3296 /* geniCodeDummyRead - generate code for dummy read */
3297 /*-----------------------------------------------------------------*/
3299 geniCodeDummyRead (operand * op)
3302 sym_link *type = operandType (op);
3304 if (!IS_VOLATILE(type))
3307 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3313 /*-----------------------------------------------------------------*/
3314 /* geniCodeSEParms - generate code for side effecting fcalls */
3315 /*-----------------------------------------------------------------*/
3317 geniCodeSEParms (ast * parms,int lvl)
3322 if (parms->type == EX_OP && parms->opval.op == PARAM)
3324 geniCodeSEParms (parms->left,lvl);
3325 geniCodeSEParms (parms->right,lvl);
3329 /* hack don't like this but too lazy to think of
3331 if (IS_ADDRESS_OF_OP (parms))
3332 parms->left->lvalue = 1;
3334 if (IS_CAST_OP (parms) &&
3335 IS_PTR (parms->ftype) &&
3336 IS_ADDRESS_OF_OP (parms->right))
3337 parms->right->left->lvalue = 1;
3339 parms->opval.oprnd =
3340 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3342 parms->type = EX_OPERAND;
3343 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3344 SPEC_ARGREG(parms->ftype);
3347 /*-----------------------------------------------------------------*/
3348 /* geniCodeParms - generates parameters */
3349 /*-----------------------------------------------------------------*/
3351 geniCodeParms (ast * parms, value *argVals, int *stack,
3352 sym_link * ftype, int lvl)
3360 if (argVals==NULL) {
3362 argVals = FUNC_ARGS (ftype);
3365 /* if this is a param node then do the left & right */
3366 if (parms->type == EX_OP && parms->opval.op == PARAM)
3368 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3369 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3373 /* get the parameter value */
3374 if (parms->type == EX_OPERAND)
3375 pval = parms->opval.oprnd;
3378 /* maybe this else should go away ?? */
3379 /* hack don't like this but too lazy to think of
3381 if (IS_ADDRESS_OF_OP (parms))
3382 parms->left->lvalue = 1;
3384 if (IS_CAST_OP (parms) &&
3385 IS_PTR (parms->ftype) &&
3386 IS_ADDRESS_OF_OP (parms->right))
3387 parms->right->left->lvalue = 1;
3389 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3392 /* if register parm then make it a send */
3393 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3394 IFFUNC_ISBUILTIN(ftype))
3396 ic = newiCode (SEND, pval, NULL);
3397 ic->argreg = SPEC_ARGREG(parms->etype);
3398 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3403 /* now decide whether to push or assign */
3404 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3408 operand *top = operandFromSymbol (argVals->sym);
3409 /* clear useDef and other bitVectors */
3410 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3411 geniCodeAssign (top, pval, 1, 0);
3415 sym_link *p = operandType (pval);
3417 ic = newiCode (IPUSH, pval, NULL);
3419 /* update the stack adjustment */
3420 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3425 argVals=argVals->next;
3429 /*-----------------------------------------------------------------*/
3430 /* geniCodeCall - generates temp code for calling */
3431 /*-----------------------------------------------------------------*/
3433 geniCodeCall (operand * left, ast * parms,int lvl)
3437 sym_link *type, *etype;
3441 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3442 !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3443 werror (E_FUNCTION_EXPECTED);
3444 return operandFromValue(valueFromLit(0));
3447 /* take care of parameters with side-effecting
3448 function calls in them, this is required to take care
3449 of overlaying function parameters */
3450 geniCodeSEParms (parms,lvl);
3452 ftype = operandType (left);
3453 if (IS_FUNCPTR (ftype))
3454 ftype = ftype->next;
3456 /* first the parameters */
3457 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3459 /* now call : if symbol then pcall */
3460 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3461 ic = newiCode (PCALL, left, NULL);
3463 ic = newiCode (CALL, left, NULL);
3466 type = copyLinkChain (ftype->next);
3467 etype = getSpec (type);
3468 SPEC_EXTR (etype) = 0;
3469 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3473 /* stack adjustment after call */
3474 ic->parmBytes = stack;
3479 /*-----------------------------------------------------------------*/
3480 /* geniCodeReceive - generate intermediate code for "receive" */
3481 /*-----------------------------------------------------------------*/
3483 geniCodeReceive (value * args, operand * func)
3485 unsigned char paramByteCounter = 0;
3487 /* for all arguments that are passed in registers */
3490 if (IS_REGPARM (args->etype))
3492 operand *opr = operandFromValue (args);
3494 symbol *sym = OP_SYMBOL (opr);
3497 /* we will use it after all optimizations
3498 and before liveRange calculation */
3499 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3502 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3503 options.stackAuto == 0 &&
3504 (!(options.model == MODEL_FLAT24)) )
3509 opl = newiTempOperand (args->type, 0);
3511 sym->reqv->key = sym->key;
3512 OP_SYMBOL (sym->reqv)->key = sym->key;
3513 OP_SYMBOL (sym->reqv)->isreqv = 1;
3514 OP_SYMBOL (sym->reqv)->islocal = 0;
3515 SPIL_LOC (sym->reqv) = sym;
3519 ic = newiCode (RECEIVE, func, NULL);
3520 ic->argreg = SPEC_ARGREG(args->etype);
3521 if (ic->argreg == 1) {
3522 currFunc->recvSize = getSize (sym->type);
3524 IC_RESULT (ic) = opr;
3526 /* misuse of parmBytes (normally used for functions)
3527 * to save estimated stack position of this argument.
3528 * Normally this should be zero for RECEIVE iCodes.
3529 * No idea if this causes side effects on other ports. - dw
3531 ic->parmBytes = paramByteCounter;
3533 /* what stack position do we have? */
3534 paramByteCounter += getSize (sym->type);
3543 /*-----------------------------------------------------------------*/
3544 /* geniCodeFunctionBody - create the function body */
3545 /*-----------------------------------------------------------------*/
3547 geniCodeFunctionBody (ast * tree,int lvl)
3554 /* reset the auto generation */
3560 func = ast2iCode (tree->left,lvl+1);
3561 fetype = getSpec (operandType (func));
3563 savelineno = lineno;
3564 lineno = OP_SYMBOL (func)->lineDef;
3565 /* create an entry label */
3566 geniCodeLabel (entryLabel);
3567 lineno = savelineno;
3569 /* create a proc icode */
3570 ic = newiCode (FUNCTION, func, NULL);
3571 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3576 /* for all parameters that are passed
3577 on registers add a "receive" */
3578 geniCodeReceive (tree->values.args, func);
3580 /* generate code for the body */
3581 ast2iCode (tree->right,lvl+1);
3583 /* create a label for return */
3584 geniCodeLabel (returnLabel);
3586 /* now generate the end proc */
3587 ic = newiCode (ENDFUNCTION, func, NULL);
3593 /*-----------------------------------------------------------------*/
3594 /* geniCodeReturn - gen icode for 'return' statement */
3595 /*-----------------------------------------------------------------*/
3597 geniCodeReturn (operand * op)
3601 /* if the operand is present force an rvalue */
3603 op = geniCodeRValue (op, FALSE);
3605 ic = newiCode (RETURN, op, NULL);
3609 /*-----------------------------------------------------------------*/
3610 /* geniCodeIfx - generates code for extended if statement */
3611 /*-----------------------------------------------------------------*/
3613 geniCodeIfx (ast * tree,int lvl)
3616 operand *condition = ast2iCode (tree->left,lvl+1);
3619 /* if condition is null then exit */
3623 condition = geniCodeRValue (condition, FALSE);
3625 cetype = getSpec (operandType (condition));
3626 /* if the condition is a literal */
3627 if (IS_LITERAL (cetype))
3629 if (floatFromVal (condition->operand.valOperand))
3631 if (tree->trueLabel)
3632 geniCodeGoto (tree->trueLabel);
3638 if (tree->falseLabel)
3639 geniCodeGoto (tree->falseLabel);
3646 if (tree->trueLabel)
3648 ic = newiCodeCondition (condition,
3653 if (tree->falseLabel)
3654 geniCodeGoto (tree->falseLabel);
3658 ic = newiCodeCondition (condition,
3665 ast2iCode (tree->right,lvl+1);
3668 /*-----------------------------------------------------------------*/
3669 /* geniCodeJumpTable - tries to create a jump table for switch */
3670 /*-----------------------------------------------------------------*/
3672 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3674 int min, max, cnt = 1;
3681 int needRangeCheck = !optimize.noJTabBoundary
3682 || tree->values.switchVals.swDefault;
3683 sym_link *cetype = getSpec (operandType (cond));
3684 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3685 int sizeofMatchJump, sizeofJumpTable;
3688 if (!tree || !caseVals)
3691 /* the criteria for creating a jump table is */
3692 /* all integer numbers between the maximum & minimum must */
3693 /* be present , the maximum value should not exceed 255 */
3694 /* If not all integer numbers are present the algorithm */
3695 /* inserts jumps to the default label for the missing numbers */
3696 /* and decides later whether it is worth it */
3697 min = (int) floatFromVal (vch = caseVals);
3704 max = (int) floatFromVal (vch);
3706 /* Exit if the range is too large to handle with a jump table. */
3707 if (1 + max - min > port->jumptableCost.maxCount)
3710 switch (getSize (operandType (cond)))
3712 case 1: sizeIndex = 0; break;
3713 case 2: sizeIndex = 1; break;
3714 case 4: sizeIndex = 2; break;
3718 /* Compute the size cost of the range check and subtraction. */
3720 sizeofZeroMinCost = 0;
3724 if (!(min==0 && IS_UNSIGNED (cetype)))
3725 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3726 if (!IS_UNSIGNED (cetype))
3727 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3728 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3731 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3733 /* If the size cost of handling a non-zero minimum exceeds the */
3734 /* cost of extending the range down to zero, then it might be */
3735 /* better to extend the range to zero. */
3736 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3737 >= (min * port->jumptableCost.sizeofElement))
3739 /* Only extend the jump table if it would still be manageable. */
3740 if (1 + max <= port->jumptableCost.maxCount)
3743 if (IS_UNSIGNED (cetype))
3746 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3750 /* Compute the total size cost of a jump table. */
3751 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3752 + port->jumptableCost.sizeofDispatch
3753 + sizeofMinCost + sizeofMaxCost;
3755 /* Compute the total size cost of a match & jump sequence */
3756 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3758 /* If the size cost of the jump table is uneconomical then exit */
3759 if (sizeofMatchJump < sizeofJumpTable)
3762 /* The jump table is preferable. */
3764 /* First, a label for the default or missing cases. */
3765 if (tree->values.switchVals.swDefault)
3767 SNPRINTF (buffer, sizeof(buffer),
3769 tree->values.switchVals.swNum);
3773 SNPRINTF (buffer, sizeof(buffer),
3775 tree->values.switchVals.swNum);
3777 falseLabel = newiTempLabel (buffer);
3779 /* Build the list of labels for the jump table. */
3781 t = (int) floatFromVal (vch);
3782 for (i=min; i<=max; i++)
3786 /* Explicit case: make a new label for it. */
3787 SNPRINTF (buffer, sizeof(buffer),
3789 tree->values.switchVals.swNum,
3791 addSet (&labels, newiTempLabel (buffer));
3794 t = (int) floatFromVal (vch);
3798 /* Implicit case: use the default label. */
3799 addSet (&labels, falseLabel);
3803 /* first we rule out the boundary conditions */
3804 /* if only optimization says so */
3807 sym_link *cetype = getSpec (operandType (cond));
3808 /* no need to check the lower bound if
3809 the condition is unsigned & minimum value is zero */
3810 if (!(min == 0 && IS_UNSIGNED (cetype)))
3812 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3813 ic = newiCodeCondition (boundary, falseLabel, NULL);
3817 /* now for upper bounds */
3818 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3819 ic = newiCodeCondition (boundary, falseLabel, NULL);
3823 /* if the min is not zero then we no make it zero */
3826 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3827 if (!IS_LITERAL(getSpec(operandType(cond))))
3828 setOperandType (cond, UCHARTYPE);
3831 /* now create the jumptable */
3832 ic = newiCode (JUMPTABLE, NULL, NULL);
3833 IC_JTCOND (ic) = cond;
3834 IC_JTLABELS (ic) = labels;
3839 /*-----------------------------------------------------------------*/
3840 /* geniCodeSwitch - changes a switch to a if statement */
3841 /*-----------------------------------------------------------------*/
3843 geniCodeSwitch (ast * tree,int lvl)
3846 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3847 value *caseVals = tree->values.switchVals.swVals;
3848 symbol *trueLabel, *falseLabel;
3850 /* If the condition is a literal, then just jump to the */
3851 /* appropriate case label. */
3852 if (IS_LITERAL(getSpec(operandType(cond))))
3854 int switchVal, caseVal;
3856 switchVal = (int) floatFromVal (cond->operand.valOperand);
3859 caseVal = (int) floatFromVal (caseVals);
3860 if (caseVal == switchVal)
3862 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3863 tree->values.switchVals.swNum, caseVal);
3864 trueLabel = newiTempLabel (buffer);
3865 geniCodeGoto (trueLabel);
3868 caseVals = caseVals->next;
3870 goto defaultOrBreak;
3873 /* If cond is volatile, it might change while we are trying to */
3874 /* find the matching case. To avoid this possibility, make a */
3875 /* non-volatile copy to use instead. */
3876 if (IS_OP_VOLATILE (cond))
3881 newcond = newiTempOperand (operandType (cond), TRUE);
3882 newcond->isvolatile = 0;
3883 ic = newiCode ('=', NULL, cond);
3884 IC_RESULT (ic) = newcond;
3889 /* if we can make this a jump table */
3890 if (geniCodeJumpTable (cond, caseVals, tree))
3891 goto jumpTable; /* no need for the comparison */
3893 /* for the cases defined do */
3897 operand *compare = geniCodeLogic (cond,
3898 operandFromValue (caseVals),
3901 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3902 tree->values.switchVals.swNum,
3903 (int) floatFromVal (caseVals));
3904 trueLabel = newiTempLabel (buffer);
3906 ic = newiCodeCondition (compare, trueLabel, NULL);
3908 caseVals = caseVals->next;
3913 /* if default is present then goto break else break */
3914 if (tree->values.switchVals.swDefault)
3916 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3920 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3923 falseLabel = newiTempLabel (buffer);
3924 geniCodeGoto (falseLabel);
3927 ast2iCode (tree->right,lvl+1);
3930 /*-----------------------------------------------------------------*/
3931 /* geniCodeInline - intermediate code for inline assembler */
3932 /*-----------------------------------------------------------------*/
3934 geniCodeInline (ast * tree)
3938 ic = newiCode (INLINEASM, NULL, NULL);
3939 IC_INLINE (ic) = tree->values.inlineasm;
3943 /*-----------------------------------------------------------------*/
3944 /* geniCodeArrayInit - intermediate code for array initializer */
3945 /*-----------------------------------------------------------------*/
3947 geniCodeArrayInit (ast * tree, operand *array)
3951 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3952 ic = newiCode (ARRAYINIT, array, NULL);
3953 IC_ARRAYILIST (ic) = tree->values.constlist;
3955 operand *left=newOperand(), *right=newOperand();
3956 left->type=right->type=SYMBOL;
3957 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3958 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3959 ic = newiCode (ARRAYINIT, left, right);
3964 /*-----------------------------------------------------------------*/
3965 /* geniCodeCritical - intermediate code for a critical statement */
3966 /*-----------------------------------------------------------------*/
3968 geniCodeCritical (ast *tree, int lvl)
3974 if (!options.stackAuto)
3976 type = newLink(SPECIFIER);
3977 SPEC_VOLATILE(type) = 1;
3978 SPEC_NOUN(type) = V_BIT;
3979 SPEC_SCLS(type) = S_BIT;
3980 SPEC_BLEN(type) = 1;
3981 SPEC_BSTR(type) = 0;
3982 op = newiTempOperand(type, 1);
3985 /* If op is NULL, the original interrupt state will saved on */
3986 /* the stack. Otherwise, it will be saved in op. */
3988 /* Generate a save of the current interrupt state & disable */
3989 ic = newiCode (CRITICAL, NULL, NULL);
3990 IC_RESULT (ic) = op;
3993 /* Generate the critical code sequence */
3994 if (tree->left && tree->left->type == EX_VALUE)
3995 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3997 ast2iCode (tree->left,lvl+1);
3999 /* Generate a restore of the original interrupt state */
4000 ic = newiCode (ENDCRITICAL, NULL, op);
4004 /*-----------------------------------------------------------------*/
4005 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
4006 /* particular case. Ie : assigning or dereferencing array or ptr */
4007 /*-----------------------------------------------------------------*/
4008 set * lvaluereqSet = NULL;
4009 typedef struct lvalItem
4016 /*-----------------------------------------------------------------*/
4017 /* addLvaluereq - add a flag for lvalreq for current ast level */
4018 /*-----------------------------------------------------------------*/
4019 void addLvaluereq(int lvl)
4021 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
4024 addSetHead(&lvaluereqSet,lpItem);
4027 /*-----------------------------------------------------------------*/
4028 /* delLvaluereq - del a flag for lvalreq for current ast level */
4029 /*-----------------------------------------------------------------*/
4033 lpItem = getSet(&lvaluereqSet);
4034 if(lpItem) Safe_free(lpItem);
4036 /*-----------------------------------------------------------------*/
4037 /* clearLvaluereq - clear lvalreq flag */
4038 /*-----------------------------------------------------------------*/
4039 void clearLvaluereq()
4042 lpItem = peekSet(lvaluereqSet);
4043 if(lpItem) lpItem->req = 0;
4045 /*-----------------------------------------------------------------*/
4046 /* getLvaluereq - get the last lvalreq level */
4047 /*-----------------------------------------------------------------*/
4048 int getLvaluereqLvl()
4051 lpItem = peekSet(lvaluereqSet);
4052 if(lpItem) return lpItem->lvl;
4055 /*-----------------------------------------------------------------*/
4056 /* isLvaluereq - is lvalreq valid for this level ? */
4057 /*-----------------------------------------------------------------*/
4058 int isLvaluereq(int lvl)
4061 lpItem = peekSet(lvaluereqSet);
4062 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4066 /*-----------------------------------------------------------------*/
4067 /* ast2iCode - creates an icodeList from an ast */
4068 /*-----------------------------------------------------------------*/
4070 ast2iCode (ast * tree,int lvl)
4072 operand *left = NULL;
4073 operand *right = NULL;
4077 /* set the global variables for filename & line number */
4079 filename = tree->filename;
4081 lineno = tree->lineno;
4083 block = tree->block;
4085 scopeLevel = tree->level;
4087 seqPoint = tree->seqPoint;
4089 if (tree->type == EX_VALUE)
4090 return operandFromValue (tree->opval.val);
4092 if (tree->type == EX_LINK)
4093 return operandFromLink (tree->opval.lnk);
4095 /* if we find a nullop */
4096 if (tree->type == EX_OP &&
4097 (tree->opval.op == NULLOP ||
4098 tree->opval.op == BLOCK))
4100 if (tree->left && tree->left->type == EX_VALUE)
4101 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4103 ast2iCode (tree->left,lvl+1);
4104 if (tree->right && tree->right->type == EX_VALUE)
4105 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4107 ast2iCode (tree->right,lvl+1);
4111 /* special cases for not evaluating */
4112 if (tree->opval.op != ':' &&
4113 tree->opval.op != '?' &&
4114 tree->opval.op != CALL &&
4115 tree->opval.op != IFX &&
4116 tree->opval.op != AND_OP &&
4117 tree->opval.op != OR_OP &&
4118 tree->opval.op != LABEL &&
4119 tree->opval.op != GOTO &&
4120 tree->opval.op != SWITCH &&
4121 tree->opval.op != FUNCTION &&
4122 tree->opval.op != INLINEASM &&
4123 tree->opval.op != CRITICAL)
4126 if (IS_ASSIGN_OP (tree->opval.op) ||
4127 IS_DEREF_OP (tree) ||
4128 (tree->opval.op == '&' && !tree->right) ||
4129 tree->opval.op == PTR_OP)
4132 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4133 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4136 left = operandFromAst (tree->left,lvl);
4138 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4139 left = geniCodeRValue (left, TRUE);
4143 left = operandFromAst (tree->left,lvl);
4145 if (tree->opval.op == INC_OP ||
4146 tree->opval.op == DEC_OP)
4149 right = operandFromAst (tree->right,lvl);
4154 right = operandFromAst (tree->right,lvl);
4158 /* now depending on the type of operand */
4159 /* this will be a biggy */
4160 switch (tree->opval.op)
4163 case '[': /* array operation */
4165 //sym_link *ltype = operandType (left);
4166 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4167 left = geniCodeRValue (left, FALSE);
4168 right = geniCodeRValue (right, TRUE);
4171 return geniCodeArray (left, right,lvl);
4173 case '.': /* structure dereference */
4174 if (IS_PTR (operandType (left)))
4175 left = geniCodeRValue (left, TRUE);
4177 left = geniCodeRValue (left, FALSE);
4179 return geniCodeStruct (left, right, tree->lvalue);
4181 case PTR_OP: /* structure pointer dereference */
4184 pType = operandType (left);
4185 left = geniCodeRValue (left, TRUE);
4187 setOClass (pType, getSpec (operandType (left)));
4190 return geniCodeStruct (left, right, tree->lvalue);
4192 case INC_OP: /* increment operator */
4194 return geniCodePostInc (left);
4196 return geniCodePreInc (right, tree->lvalue);
4198 case DEC_OP: /* decrement operator */
4200 return geniCodePostDec (left);
4202 return geniCodePreDec (right, tree->lvalue);
4204 case '&': /* bitwise and or address of operator */
4206 { /* this is a bitwise operator */
4207 left = geniCodeRValue (left, FALSE);
4208 right = geniCodeRValue (right, FALSE);
4209 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4212 return geniCodeAddressOf (left);
4214 case '|': /* bitwise or & xor */
4216 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4217 geniCodeRValue (right, FALSE),
4222 return geniCodeDivision (geniCodeRValue (left, FALSE),
4223 geniCodeRValue (right, FALSE),
4224 getResultTypeFromType (tree->ftype));
4227 return geniCodeModulus (geniCodeRValue (left, FALSE),
4228 geniCodeRValue (right, FALSE),
4229 getResultTypeFromType (tree->ftype));
4232 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4233 geniCodeRValue (right, FALSE),
4234 getResultTypeFromType (tree->ftype));
4236 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4240 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4241 geniCodeRValue (right, FALSE),
4242 getResultTypeFromType (tree->ftype));
4244 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4248 return geniCodeAdd (geniCodeRValue (left, FALSE),
4249 geniCodeRValue (right, FALSE),
4250 getResultTypeFromType (tree->ftype),
4253 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4256 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4257 geniCodeRValue (right, FALSE),
4258 getResultTypeFromType (tree->ftype));
4261 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4262 geniCodeRValue (right, FALSE));
4264 #if 0 // this indeed needs a second thought
4268 // let's keep this simple: get the rvalue we need
4269 op=geniCodeRValue (right, FALSE);
4270 // now cast it to whatever we want
4271 op=geniCodeCast (operandType(left), op, FALSE);
4272 // if this is going to be used as an lvalue, make it so
4278 #else // bug #604575, is it a bug ????
4279 return geniCodeCast (operandType (left),
4280 geniCodeRValue (right, FALSE), FALSE);
4287 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4292 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4293 setOperandType (op, UCHARTYPE);
4300 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4301 geniCodeRValue (right, FALSE),
4303 setOperandType (op, (tree->opval.op == GETWORD) ? UINTTYPE : UCHARTYPE);
4308 return geniCodeLogicAndOr (tree, lvl);
4315 /* different compilers (even different gccs) evaluate
4316 the two calls in a different order. to get the same
4317 result on all machines we've to specify a clear sequence.
4318 return geniCodeLogic (geniCodeRValue (left, FALSE),
4319 geniCodeRValue (right, FALSE),
4323 operand *leftOp, *rightOp;
4325 leftOp = geniCodeRValue (left , FALSE);
4326 rightOp = geniCodeRValue (right, FALSE);
4328 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4331 return geniCodeConditional (tree,lvl);
4334 return operandFromLit (getSize (tree->right->ftype));
4338 sym_link *rtype = operandType (right);
4339 sym_link *ltype = operandType (left);
4340 if (IS_PTR (rtype) && IS_ITEMP (right)
4341 && right->isaddr && compareType (rtype->next, ltype) == 1)
4342 right = geniCodeRValue (right, TRUE);
4344 right = geniCodeRValue (right, FALSE);
4346 geniCodeAssign (left, right, 0, 1);
4351 geniCodeAssign (left,
4352 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4354 geniCodeRValue (right, FALSE),
4355 getResultTypeFromType (tree->ftype)),
4360 geniCodeAssign (left,
4361 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4363 geniCodeRValue (right, FALSE),
4364 getResultTypeFromType (tree->ftype)),
4368 geniCodeAssign (left,
4369 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4371 geniCodeRValue (right, FALSE),
4372 getResultTypeFromType (tree->ftype)),
4376 sym_link *rtype = operandType (right);
4377 sym_link *ltype = operandType (left);
4378 if (IS_PTR (rtype) && IS_ITEMP (right)
4379 && right->isaddr && compareType (rtype->next, ltype) == 1)
4380 right = geniCodeRValue (right, TRUE);
4382 right = geniCodeRValue (right, FALSE);
4385 return geniCodeAssign (left,
4386 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4389 getResultTypeFromType (tree->ftype),
4395 sym_link *rtype = operandType (right);
4396 sym_link *ltype = operandType (left);
4397 if (IS_PTR (rtype) && IS_ITEMP (right)
4398 && right->isaddr && compareType (rtype->next, ltype) == 1)
4400 right = geniCodeRValue (right, TRUE);
4404 right = geniCodeRValue (right, FALSE);
4407 geniCodeAssign (left,
4408 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4411 getResultTypeFromType (tree->ftype)),
4416 geniCodeAssign (left,
4417 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4419 geniCodeRValue (right, FALSE),
4420 getResultTypeFromType (tree->ftype)),
4424 geniCodeAssign (left,
4425 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4427 geniCodeRValue (right, FALSE)), 0, 1);
4430 geniCodeAssign (left,
4431 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4433 geniCodeRValue (right, FALSE),
4435 operandType (left)), 0, 1);
4438 geniCodeAssign (left,
4439 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4441 geniCodeRValue (right, FALSE),
4443 operandType (left)), 0, 1);
4446 geniCodeAssign (left,
4447 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4449 geniCodeRValue (right, FALSE),
4451 operandType (left)), 0, 1);
4453 return geniCodeRValue (right, FALSE);
4456 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4459 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4460 return ast2iCode (tree->right,lvl+1);
4463 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4464 return ast2iCode (tree->right,lvl+1);
4467 geniCodeFunctionBody (tree,lvl);
4471 geniCodeReturn (right);
4475 geniCodeIfx (tree,lvl);
4479 geniCodeSwitch (tree,lvl);
4483 geniCodeInline (tree);
4487 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4491 geniCodeCritical (tree, lvl);
4497 /*-----------------------------------------------------------------*/
4498 /* reverseICChain - gets from the list and creates a linkedlist */
4499 /*-----------------------------------------------------------------*/
4506 while ((loop = getSet (&iCodeChain)))
4518 /*-----------------------------------------------------------------*/
4519 /* iCodeFromAst - given an ast will convert it to iCode */
4520 /*-----------------------------------------------------------------*/
4522 iCodeFromAst (ast * tree)
4524 returnLabel = newiTempLabel ("_return");
4525 entryLabel = newiTempLabel ("_entry");
4527 return reverseiCChain ();
4530 static const char *opTypeToStr(OPTYPE op)
4534 case SYMBOL: return "symbol";
4535 case VALUE: return "value";
4536 case TYPE: return "type";
4538 return "undefined type";
4542 operand *validateOpType(operand *op,
4549 if (op && op->type == type)
4554 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4555 " expected %s, got %s\n",
4556 macro, args, file, line,
4557 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4559 return op; // never reached, makes compiler happy.