1 /*-------------------------------------------------------------------------
3 SDCCicode.c - intermediate code generation etc.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
29 /*-----------------------------------------------------------------*/
30 /* global variables */
32 set *iCodeChain = NULL;
43 symbol *returnLabel; /* function return label */
44 symbol *entryLabel; /* function entry label */
46 /*-----------------------------------------------------------------*/
47 /* forward definition of some functions */
48 operand *geniCodeAssign (operand *, operand *, int, int);
49 static operand *geniCodeArray (operand *, operand *,int);
50 static operand *geniCodeArray2Ptr (operand *);
51 operand *geniCodeRValue (operand *, bool);
52 operand *geniCodeDerefPtr (operand *,int);
53 int isLvaluereq(int lvl);
54 void setOClass (sym_link * ptr, sym_link * spec);
55 static operand *geniCodeCast (sym_link *, operand *, bool);
57 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
58 /* forward definition of ic print functions */
59 PRINTFUNC (picGetValueAtAddr);
60 PRINTFUNC (picSetValueAtAddr);
61 PRINTFUNC (picAddrOf);
62 PRINTFUNC (picGeneric);
63 PRINTFUNC (picGenericOne);
65 PRINTFUNC (picAssign);
69 PRINTFUNC (picJumpTable);
70 PRINTFUNC (picInline);
71 PRINTFUNC (picReceive);
72 PRINTFUNC (picDummyRead);
73 PRINTFUNC (picCritical);
74 PRINTFUNC (picEndCritical);
76 iCodeTable codeTable[] =
78 {'!', "not", picGenericOne, NULL},
79 {'~', "~", picGenericOne, NULL},
80 {RRC, "rrc", picGenericOne, NULL},
81 {RLC, "rlc", picGenericOne, NULL},
82 {GETHBIT, "ghbit", picGenericOne, NULL},
83 {UNARYMINUS, "-", picGenericOne, NULL},
84 {IPUSH, "push", picGenericOne, NULL},
85 {IPOP, "pop", picGenericOne, NULL},
86 {CALL, "call", picGenericOne, NULL},
87 {PCALL, "pcall", picGenericOne, NULL},
88 {FUNCTION, "proc", picGenericOne, NULL},
89 {ENDFUNCTION, "eproc", picGenericOne, NULL},
90 {RETURN, "ret", picGenericOne, NULL},
91 {'+', "+", picGeneric, NULL},
92 {'-', "-", picGeneric, NULL},
93 {'*', "*", picGeneric, NULL},
94 {'/', "/", picGeneric, NULL},
95 {'%', "%", picGeneric, NULL},
96 {'>', ">", picGeneric, NULL},
97 {'<', "<", picGeneric, NULL},
98 {LE_OP, "<=", picGeneric, NULL},
99 {GE_OP, ">=", picGeneric, NULL},
100 {EQ_OP, "==", picGeneric, NULL},
101 {NE_OP, "!=", picGeneric, NULL},
102 {AND_OP, "&&", picGeneric, NULL},
103 {OR_OP, "||", picGeneric, NULL},
104 {'^', "^", picGeneric, NULL},
105 {'|', "|", picGeneric, NULL},
106 {BITWISEAND, "&", picGeneric, NULL},
107 {LEFT_OP, "<<", picGeneric, NULL},
108 {RIGHT_OP, ">>", picGeneric, NULL},
109 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
110 {ADDRESS_OF, "&", picAddrOf, NULL},
111 {CAST, "<>", picCast, NULL},
112 {'=', ":=", picAssign, NULL},
113 {LABEL, "", picLabel, NULL},
114 {GOTO, "", picGoto, NULL},
115 {JUMPTABLE, "jtab", picJumpTable, NULL},
116 {IFX, "if", picIfx, NULL},
117 {INLINEASM, "", picInline, NULL},
118 {RECEIVE, "recv", picReceive, NULL},
119 {SEND, "send", picGenericOne, NULL},
120 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
121 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
122 {CRITICAL, "critical_start", picCritical, NULL},
123 {ENDCRITICAL, "critical_end", picEndCritical, NULL},
124 {SWAP, "swap", picGenericOne, NULL}
127 /*-----------------------------------------------------------------*/
128 /* checkConstantRange: check a constant against the type */
129 /*-----------------------------------------------------------------*/
132 /* pedantic=0: allmost anything is allowed as long as the absolute
133 value is within the bit range of the type, and -1 is treated as
134 0xf..f for unsigned types (e.g. in assign)
135 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
136 pedantic>1: "char c=200" is not allowed (evaluates to -56)
139 void checkConstantRange(sym_link *ltype, value *val, char *msg,
146 max = pow ((double)2.0, (double)bitsForType(ltype));
148 if (IS_LONG(val->type)) {
149 if (IS_UNSIGNED(val->type)) {
150 v=SPEC_CVAL(val->type).v_ulong;
152 v=SPEC_CVAL(val->type).v_long;
155 if (IS_UNSIGNED(val->type)) {
156 v=SPEC_CVAL(val->type).v_uint;
158 v=SPEC_CVAL(val->type).v_int;
164 // this could be a good idea
165 if (options.pedantic)
169 if (IS_FLOAT(ltype)) {
174 if (!IS_UNSIGNED(val->type) && v<0) {
176 if (IS_UNSIGNED(ltype) && (pedantic>1)) {
182 // if very pedantic: "char c=200" is not allowed
183 if (pedantic>1 && !IS_UNSIGNED(ltype)) {
184 max = max/2 + negative;
191 #if 0 // temporary disabled, leaving the warning as a reminder
193 SNPRINTF (message, sizeof(message), "for %s %s in %s",
194 IS_UNSIGNED(ltype) ? "unsigned" : "signed",
195 nounName(ltype), msg);
196 werror (W_CONST_RANGE, message);
204 /*-----------------------------------------------------------------*/
205 /* operandName - returns the name of the operand */
206 /*-----------------------------------------------------------------*/
208 printOperand (operand * op, FILE * file)
225 opetype = getSpec (operandType (op));
226 if (IS_FLOAT (opetype))
227 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
229 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
230 printTypeChain (operandType (op), file);
237 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d a2p%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
238 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
240 OP_LIVEFROM (op), OP_LIVETO (op),
241 OP_SYMBOL (op)->stack,
242 op->isaddr, op->aggr2ptr, OP_SYMBOL (op)->isreqv,
243 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
244 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
248 printTypeChain (operandType (op), file);
249 if (SPIL_LOC (op) && IS_ITEMP (op))
250 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
255 /* if assigned to registers */
256 if (OP_SYMBOL (op)->nRegs)
258 if (OP_SYMBOL (op)->isspilt)
260 if (!OP_SYMBOL (op)->remat)
261 if (OP_SYMBOL (op)->usl.spillLoc)
262 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
263 OP_SYMBOL (op)->usl.spillLoc->rname :
264 OP_SYMBOL (op)->usl.spillLoc->name));
266 fprintf (file, "[err]");
268 fprintf (file, "[remat]");
274 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
275 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
281 fprintf (file, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
285 fprintf (file, "[lr%d:%d so:%d]",
286 OP_LIVEFROM (op), OP_LIVETO (op),
287 OP_SYMBOL (op)->stack
294 printTypeChain (operandType (op), file);
295 if (SPIL_LOC (op) && IS_ITEMP (op))
296 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
302 /* if assigned to registers */
303 if (OP_SYMBOL (op)->nRegs)
305 if (OP_SYMBOL (op)->isspilt)
307 if (!OP_SYMBOL (op)->remat)
308 if (OP_SYMBOL (op)->usl.spillLoc)
309 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
310 OP_SYMBOL (op)->usl.spillLoc->rname :
311 OP_SYMBOL (op)->usl.spillLoc->name));
313 fprintf (file, "[err]");
315 fprintf (file, "[remat]");
321 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
322 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
332 printTypeChain (op->operand.typeOperand, file);
338 fprintf (file, "\n");
343 /*-----------------------------------------------------------------*/
344 /* print functions */
345 /*-----------------------------------------------------------------*/
346 PRINTFUNC (picGetValueAtAddr)
349 printOperand (IC_RESULT (ic), of);
352 printOperand (IC_LEFT (ic), of);
358 PRINTFUNC (picSetValueAtAddr)
362 printOperand (IC_LEFT (ic), of);
363 fprintf (of, "] = ");
364 printOperand (IC_RIGHT (ic), of);
368 PRINTFUNC (picAddrOf)
371 printOperand (IC_RESULT (ic), of);
372 if (IS_ITEMP (IC_LEFT (ic)))
375 fprintf (of, " = &[");
376 printOperand (IC_LEFT (ic), of);
379 if (IS_ITEMP (IC_LEFT (ic)))
380 fprintf (of, " offsetAdd ");
383 printOperand (IC_RIGHT (ic), of);
385 if (IS_ITEMP (IC_LEFT (ic)))
391 PRINTFUNC (picJumpTable)
396 fprintf (of, "%s\t", s);
397 printOperand (IC_JTCOND (ic), of);
399 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
400 sym = setNextItem (IC_JTLABELS (ic)))
401 fprintf (of, "\t\t\t%s\n", sym->name);
404 PRINTFUNC (picGeneric)
407 printOperand (IC_RESULT (ic), of);
409 printOperand (IC_LEFT (ic), of);
410 fprintf (of, " %s ", s);
411 printOperand (IC_RIGHT (ic), of);
415 PRINTFUNC (picGenericOne)
420 printOperand (IC_RESULT (ic), of);
426 fprintf (of, "%s ", s);
427 printOperand (IC_LEFT (ic), of);
430 if (!IC_RESULT (ic) && !IC_LEFT (ic))
433 if (ic->op == SEND || ic->op == RECEIVE) {
434 fprintf(of,"{argreg = %d}",ic->argreg);
436 if (ic->op == IPUSH) {
437 fprintf(of,"{parmPush = %d}",ic->parmPush);
445 printOperand (IC_RESULT (ic), of);
447 printOperand (IC_LEFT (ic), of);
448 printOperand (IC_RIGHT (ic), of);
453 PRINTFUNC (picAssign)
457 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
460 printOperand (IC_RESULT (ic), of);
462 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
465 fprintf (of, " %s ", s);
466 printOperand (IC_RIGHT (ic), of);
473 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
479 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
486 printOperand (IC_COND (ic), of);
489 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
492 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
494 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
498 PRINTFUNC (picInline)
500 fprintf (of, "%s", IC_INLINE (ic));
503 PRINTFUNC (picReceive)
505 printOperand (IC_RESULT (ic), of);
506 fprintf (of, " = %s ", s);
507 printOperand (IC_LEFT (ic), of);
511 PRINTFUNC (picDummyRead)
514 fprintf (of, "%s ", s);
515 printOperand (IC_RIGHT (ic), of);
519 PRINTFUNC (picCritical)
523 printOperand (IC_RESULT (ic), of);
525 fprintf (of, "(stack)");
526 fprintf (of, " = %s ", s);
530 PRINTFUNC (picEndCritical)
533 fprintf (of, "%s = ", s);
535 printOperand (IC_RIGHT (ic), of);
537 fprintf (of, "(stack)");
541 /*-----------------------------------------------------------------*/
542 /* piCode - prints one iCode */
543 /*-----------------------------------------------------------------*/
545 piCode (void *item, FILE * of)
553 icTab = getTableEntry (ic->op);
554 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
555 ic->filename, ic->lineno,
556 ic->seq, ic->key, ic->depth, ic->supportRtn);
557 icTab->iCodePrint (of, ic, icTab->printName);
563 printiCChain(ic,stdout);
565 /*-----------------------------------------------------------------*/
566 /* printiCChain - prints intermediate code for humans */
567 /*-----------------------------------------------------------------*/
569 printiCChain (iCode * icChain, FILE * of)
576 for (loop = icChain; loop; loop = loop->next)
578 if ((icTab = getTableEntry (loop->op)))
580 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
581 loop->filename, loop->lineno,
582 loop->seq, loop->key, loop->depth, loop->supportRtn);
584 icTab->iCodePrint (of, loop, icTab->printName);
590 /*-----------------------------------------------------------------*/
591 /* newOperand - allocate, init & return a new iCode */
592 /*-----------------------------------------------------------------*/
598 op = Safe_alloc ( sizeof (operand));
604 /*-----------------------------------------------------------------*/
605 /* newiCode - create and return a new iCode entry initialised */
606 /*-----------------------------------------------------------------*/
608 newiCode (int op, operand * left, operand * right)
612 ic = Safe_alloc ( sizeof (iCode));
614 ic->seqPoint = seqPoint;
616 ic->filename = filename;
618 ic->level = scopeLevel;
620 ic->key = iCodeKey++;
622 IC_RIGHT (ic) = right;
627 /*-----------------------------------------------------------------*/
628 /* newiCode for conditional statements */
629 /*-----------------------------------------------------------------*/
631 newiCodeCondition (operand * condition,
637 if (IS_VOID(operandType(condition))) {
638 werror(E_VOID_VALUE_USED);
641 ic = newiCode (IFX, NULL, NULL);
642 IC_COND (ic) = condition;
643 IC_TRUE (ic) = trueLabel;
644 IC_FALSE (ic) = falseLabel;
648 /*-----------------------------------------------------------------*/
649 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
650 /*-----------------------------------------------------------------*/
652 newiCodeLabelGoto (int op, symbol * label)
656 ic = newiCode (op, NULL, NULL);
660 IC_RIGHT (ic) = NULL;
661 IC_RESULT (ic) = NULL;
665 /*-----------------------------------------------------------------*/
666 /* newiTemp - allocate & return a newItemp Variable */
667 /*-----------------------------------------------------------------*/
675 SNPRINTF (buffer, sizeof(buffer), "%s", s);
679 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
682 itmp = newSymbol (buffer, 1);
683 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
689 /*-----------------------------------------------------------------*/
690 /* newiTempLabel - creates a temp variable label */
691 /*-----------------------------------------------------------------*/
693 newiTempLabel (char *s)
697 /* check if this already exists */
698 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
703 itmplbl = newSymbol (s, 1);
707 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
708 itmplbl = newSymbol (buffer, 1);
713 itmplbl->key = labelKey++;
714 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
718 /*-----------------------------------------------------------------*/
719 /* newiTempPreheaderLabel - creates a new preheader label */
720 /*-----------------------------------------------------------------*/
722 newiTempPreheaderLabel ()
726 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
727 itmplbl = newSymbol (buffer, 1);
731 itmplbl->key = labelKey++;
732 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
737 /*-----------------------------------------------------------------*/
738 /* initiCode - initialises some iCode related stuff */
739 /*-----------------------------------------------------------------*/
746 /*-----------------------------------------------------------------*/
747 /* copyiCode - make a copy of the iCode given */
748 /*-----------------------------------------------------------------*/
750 copyiCode (iCode * ic)
752 iCode *nic = newiCode (ic->op, NULL, NULL);
754 nic->lineno = ic->lineno;
755 nic->filename = ic->filename;
756 nic->block = ic->block;
757 nic->level = ic->level;
758 nic->parmBytes = ic->parmBytes;
760 /* deal with the special cases first */
764 IC_COND (nic) = operandFromOperand (IC_COND (ic));
765 IC_TRUE (nic) = IC_TRUE (ic);
766 IC_FALSE (nic) = IC_FALSE (ic);
770 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
771 IC_JTLABELS (nic) = IC_JTLABELS (ic);
776 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
777 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
781 IC_INLINE (nic) = IC_INLINE (ic);
785 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
789 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
790 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
791 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
797 /*-----------------------------------------------------------------*/
798 /* getTableEntry - gets the table entry for the given operator */
799 /*-----------------------------------------------------------------*/
801 getTableEntry (int oper)
805 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
806 if (oper == codeTable[i].icode)
807 return &codeTable[i];
812 /*-----------------------------------------------------------------*/
813 /* newiTempOperand - new intermediate temp operand */
814 /*-----------------------------------------------------------------*/
816 newiTempOperand (sym_link * type, char throwType)
819 operand *op = newOperand ();
823 itmp = newiTemp (NULL);
825 etype = getSpec (type);
827 if (IS_LITERAL (etype))
830 /* copy the type information */
832 itmp->etype = getSpec (itmp->type = (throwType ? type :
833 copyLinkChain (type)));
834 if (IS_LITERAL (itmp->etype))
836 SPEC_SCLS (itmp->etype) = S_REGISTER;
837 SPEC_OCLS (itmp->etype) = reg;
840 op->operand.symOperand = itmp;
841 op->key = itmp->key = ++operandKey;
845 /*-----------------------------------------------------------------*/
846 /* operandType - returns the type chain for an operand */
847 /*-----------------------------------------------------------------*/
849 operandType (operand * op)
851 /* depending on type of operand */
856 return op->operand.valOperand->type;
859 return op->operand.symOperand->type;
862 return op->operand.typeOperand;
864 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
865 " operand type not known ");
866 assert (0); /* should never come here */
867 /* Just to keep the compiler happy */
868 return (sym_link *) 0;
872 /*-----------------------------------------------------------------*/
873 /* isParamterToCall - will return 1 if op is a parameter to args */
874 /*-----------------------------------------------------------------*/
876 isParameterToCall (value * args, operand * op)
880 wassert (IS_SYMOP(op));
885 isSymbolEqual (op->operand.symOperand, tval->sym))
892 /*-----------------------------------------------------------------*/
893 /* isOperandGlobal - return 1 if operand is a global variable */
894 /*-----------------------------------------------------------------*/
896 isOperandGlobal (operand * op)
905 (op->operand.symOperand->level == 0 ||
906 IS_STATIC (op->operand.symOperand->etype) ||
907 IS_EXTERN (op->operand.symOperand->etype))
914 /*-----------------------------------------------------------------*/
915 /* isOperandVolatile - return 1 if the operand is volatile */
916 /*-----------------------------------------------------------------*/
918 isOperandVolatile (operand * op, bool chkTemp)
923 if (IS_ITEMP (op) && !chkTemp)
926 opetype = getSpec (optype = operandType (op));
928 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
931 if (IS_VOLATILE (opetype))
936 /*-----------------------------------------------------------------*/
937 /* isOperandLiteral - returns 1 if an operand contains a literal */
938 /*-----------------------------------------------------------------*/
940 isOperandLiteral (operand * op)
947 opetype = getSpec (operandType (op));
949 if (IS_LITERAL (opetype))
955 /*-----------------------------------------------------------------*/
956 /* isOperandInFarSpace - will return true if operand is in farSpace */
957 /*-----------------------------------------------------------------*/
959 isOperandInFarSpace (operand * op)
969 if (!IS_TRUE_SYMOP (op))
972 etype = SPIL_LOC (op)->etype;
978 etype = getSpec (operandType (op));
980 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
983 /*------------------------------------------------------------------*/
984 /* isOperandInDirSpace - will return true if operand is in dirSpace */
985 /*------------------------------------------------------------------*/
987 isOperandInDirSpace (operand * op)
997 if (!IS_TRUE_SYMOP (op))
1000 etype = SPIL_LOC (op)->etype;
1006 etype = getSpec (operandType (op));
1008 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1011 /*--------------------------------------------------------------------*/
1012 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
1013 /*--------------------------------------------------------------------*/
1015 isOperandInCodeSpace (operand * op)
1025 etype = getSpec (operandType (op));
1027 if (!IS_TRUE_SYMOP (op))
1030 etype = SPIL_LOC (op)->etype;
1036 etype = getSpec (operandType (op));
1038 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1041 /*-----------------------------------------------------------------*/
1042 /* isOperandOnStack - will return true if operand is on stack */
1043 /*-----------------------------------------------------------------*/
1045 isOperandOnStack (operand * op)
1055 etype = getSpec (operandType (op));
1056 if (IN_STACK (etype) ||
1057 OP_SYMBOL(op)->onStack ||
1058 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1064 /*-----------------------------------------------------------------*/
1065 /* isOclsExpensive - will return true if accesses to an output */
1066 /* storage class are expensive */
1067 /*-----------------------------------------------------------------*/
1069 isOclsExpensive (struct memmap *oclass)
1071 if (port->oclsExpense)
1072 return port->oclsExpense (oclass) > 0;
1074 /* In the absence of port specific guidance, assume only */
1075 /* farspace is expensive. */
1076 return IN_FARSPACE (oclass);
1079 /*-----------------------------------------------------------------*/
1080 /* isiCodeInFunctionCall - return TRUE if an iCode is between a */
1081 /* CALL/PCALL and the first IPUSH/SEND associated with the call */
1082 /*-----------------------------------------------------------------*/
1084 isiCodeInFunctionCall (iCode * ic)
1088 /* Find the next CALL/PCALL */
1091 if (lic->op == CALL || lic->op == PCALL)
1099 /* A function call was found. Scan backwards and see if an */
1100 /* IPUSH or SEND is encountered */
1103 if (lic != ic && (ic->op == CALL || ic->op == PCALL))
1105 if (ic->op == SEND || (ic->op == IPUSH && ic->parmPush))
1113 /*-----------------------------------------------------------------*/
1114 /* operandLitValue - literal value of an operand */
1115 /*-----------------------------------------------------------------*/
1117 operandLitValue (operand * op)
1119 assert (isOperandLiteral (op));
1121 return floatFromVal (op->operand.valOperand);
1124 /*-----------------------------------------------------------------*/
1125 /* getBuiltInParms - returns parameters to a builtin functions */
1126 /*-----------------------------------------------------------------*/
1127 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1132 /* builtin functions uses only SEND for parameters */
1133 while (ic->op != CALL) {
1134 assert(ic->op == SEND && ic->builtinSEND);
1135 ic->generated = 1; /* mark the icode as generated */
1136 parms[*pcount] = IC_LEFT(ic);
1142 /* make sure this is a builtin function call */
1143 assert(IS_SYMOP(IC_LEFT(ic)));
1144 ftype = operandType(IC_LEFT(ic));
1145 assert(IFFUNC_ISBUILTIN(ftype));
1149 /*-----------------------------------------------------------------*/
1150 /* operandOperation - performs operations on operands */
1151 /*-----------------------------------------------------------------*/
1153 operandOperation (operand * left, operand * right,
1154 int op, sym_link * type)
1156 sym_link *let , *ret=NULL;
1157 operand *retval = (operand *) 0;
1159 assert (isOperandLiteral (left));
1160 let = getSpec(operandType(left));
1162 assert (isOperandLiteral (right));
1163 ret = getSpec(operandType(right));
1169 retval = operandFromValue (valCastLiteral (type,
1170 operandLitValue (left) +
1171 operandLitValue (right)));
1174 retval = operandFromValue (valCastLiteral (type,
1175 operandLitValue (left) -
1176 operandLitValue (right)));
1180 retval = operandFromValue (valCastLiteral (type,
1181 operandLitValue (left) *
1182 operandLitValue (right)));
1183 This could be all we've to do, but with gcc we've to take care about
1184 overflows. Two examples:
1185 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1186 significant bits are lost (52 in fraction, 63 bits would be
1187 necessary to keep full precision).
1188 If the resulting double value is greater than ULONG_MAX (resp.
1189 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1192 /* if it is not a specifier then we can assume that */
1193 /* it will be an unsigned long */
1194 if (IS_INT (type) ||
1197 /* long is handled here, because it can overflow with double */
1198 if (IS_LONG (type) ||
1200 /* signed and unsigned mul are the same, as long as the precision
1201 of the result isn't bigger than the precision of the operands. */
1202 retval = operandFromValue (valCastLiteral (type,
1203 (TYPE_UDWORD) operandLitValue (left) *
1204 (TYPE_UDWORD) operandLitValue (right)));
1205 else if (IS_UNSIGNED (type)) /* unsigned int */
1207 /* unsigned int is handled here in order to detect overflow */
1208 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1209 (TYPE_UWORD) operandLitValue (right);
1211 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1212 if (ul != (TYPE_UWORD) ul)
1215 else /* signed int */
1217 /* signed int is handled here in order to detect overflow */
1218 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1219 (TYPE_WORD) operandLitValue (right);
1221 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1222 if (l != (TYPE_WORD) l)
1227 /* all others go here: */
1228 retval = operandFromValue (valCastLiteral (type,
1229 operandLitValue (left) *
1230 operandLitValue (right)));
1233 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1235 werror (E_DIVIDE_BY_ZERO);
1241 if (IS_UNSIGNED (type))
1243 SPEC_USIGN (let) = 1;
1244 SPEC_USIGN (ret) = 1;
1245 retval = operandFromValue (valCastLiteral (type,
1246 (TYPE_UDWORD) operandLitValue (left) /
1247 (TYPE_UDWORD) operandLitValue (right)));
1251 retval = operandFromValue (valCastLiteral (type,
1252 operandLitValue (left) /
1253 operandLitValue (right)));
1258 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1260 werror (E_DIVIDE_BY_ZERO);
1265 if (IS_UNSIGNED (type))
1266 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1267 (TYPE_UDWORD) operandLitValue (right));
1269 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1270 (TYPE_DWORD) operandLitValue (right));
1274 /* The number of left shifts is always unsigned. Signed doesn't make
1275 sense here. Shifting by a negative number is impossible. */
1276 retval = operandFromValue (valCastLiteral (type,
1277 ((TYPE_UDWORD) operandLitValue (left) <<
1278 (TYPE_UDWORD) operandLitValue (right))));
1281 /* The number of right shifts is always unsigned. Signed doesn't make
1282 sense here. Shifting by a negative number is impossible. */
1283 if (IS_UNSIGNED(let))
1284 /* unsigned: logic shift right */
1285 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1286 (TYPE_UDWORD) operandLitValue (right));
1288 /* signed: arithmetic shift right */
1289 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1290 (TYPE_UDWORD) operandLitValue (right));
1293 if (IS_FLOAT (let) ||
1296 retval = operandFromLit (operandLitValue (left) ==
1297 operandLitValue (right));
1301 /* this op doesn't care about signedness */
1304 l = (TYPE_UDWORD) operandLitValue (left);
1305 r = (TYPE_UDWORD) operandLitValue (right);
1306 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1307 neccessary to strip them to 16 bit.
1308 Literals are reduced to their cheapest type, therefore left and
1309 right might have different types. It's neccessary to find a
1310 common type: int (used for char too) or long */
1311 if (!IS_LONG (let) &&
1317 retval = operandFromLit (l == r);
1321 retval = operandFromLit (operandLitValue (left) <
1322 operandLitValue (right));
1325 retval = operandFromLit (operandLitValue (left) <=
1326 operandLitValue (right));
1329 retval = operandFromLit (operandLitValue (left) !=
1330 operandLitValue (right));
1333 retval = operandFromLit (operandLitValue (left) >
1334 operandLitValue (right));
1337 retval = operandFromLit (operandLitValue (left) >=
1338 operandLitValue (right));
1341 retval = operandFromValue (valCastLiteral (type,
1342 (TYPE_UDWORD)operandLitValue(left) &
1343 (TYPE_UDWORD)operandLitValue(right)));
1346 retval = operandFromValue (valCastLiteral (type,
1347 (TYPE_UDWORD)operandLitValue(left) |
1348 (TYPE_UDWORD)operandLitValue(right)));
1351 retval = operandFromValue (valCastLiteral (type,
1352 (TYPE_UDWORD)operandLitValue(left) ^
1353 (TYPE_UDWORD)operandLitValue(right)));
1356 retval = operandFromLit (operandLitValue (left) &&
1357 operandLitValue (right));
1360 retval = operandFromLit (operandLitValue (left) ||
1361 operandLitValue (right));
1365 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1367 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1373 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1375 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1381 retval = operandFromValue (valCastLiteral (type,
1382 -1 * operandLitValue (left)));
1386 retval = operandFromValue (valCastLiteral (type,
1388 operandLitValue (left))));
1392 retval = operandFromLit (!operandLitValue (left));
1396 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1397 " operandOperation invalid operator ");
1405 /*-----------------------------------------------------------------*/
1406 /* isOperandEqual - compares two operand & return 1 if they r = */
1407 /*-----------------------------------------------------------------*/
1409 isOperandEqual (operand * left, operand * right)
1411 /* if the pointers are equal then they are equal */
1415 /* if either of them null then false */
1416 if (!left || !right)
1419 if (left->type != right->type)
1422 if (IS_SYMOP (left) && IS_SYMOP (right))
1423 return left->key == right->key;
1425 /* if types are the same */
1429 return isSymbolEqual (left->operand.symOperand,
1430 right->operand.symOperand);
1432 return (floatFromVal (left->operand.valOperand) ==
1433 floatFromVal (right->operand.valOperand));
1435 if (compareType (left->operand.typeOperand,
1436 right->operand.typeOperand) == 1)
1443 /*-------------------------------------------------------------------*/
1444 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1445 /*-------------------------------------------------------------------*/
1447 isiCodeEqual (iCode * left, iCode * right)
1449 /* if the same pointer */
1453 /* if either of them null */
1454 if (!left || !right)
1457 /* if operand are the same */
1458 if (left->op == right->op)
1461 /* compare all the elements depending on type */
1462 if (left->op != IFX)
1464 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1466 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1472 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1474 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1476 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1485 /*-----------------------------------------------------------------*/
1486 /* newiTempFromOp - create a temp Operand with same attributes */
1487 /*-----------------------------------------------------------------*/
1489 newiTempFromOp (operand * op)
1499 nop = newiTempOperand (operandType (op), TRUE);
1500 nop->isaddr = op->isaddr;
1501 nop->isvolatile = op->isvolatile;
1502 nop->isGlobal = op->isGlobal;
1503 nop->isLiteral = op->isLiteral;
1504 nop->usesDefs = op->usesDefs;
1505 nop->isParm = op->isParm;
1509 /*-----------------------------------------------------------------*/
1510 /* operand from operand - creates an operand holder for the type */
1511 /*-----------------------------------------------------------------*/
1513 operandFromOperand (operand * op)
1519 nop = newOperand ();
1520 nop->type = op->type;
1521 nop->isaddr = op->isaddr;
1523 nop->isvolatile = op->isvolatile;
1524 nop->isGlobal = op->isGlobal;
1525 nop->isLiteral = op->isLiteral;
1526 nop->usesDefs = op->usesDefs;
1527 nop->isParm = op->isParm;
1532 nop->operand.symOperand = op->operand.symOperand;
1535 nop->operand.valOperand = op->operand.valOperand;
1538 nop->operand.typeOperand = op->operand.typeOperand;
1545 /*-----------------------------------------------------------------*/
1546 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1547 /*-----------------------------------------------------------------*/
1549 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1551 operand *nop = operandFromOperand (op);
1553 if (nop->type == SYMBOL)
1555 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1556 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1562 /*-----------------------------------------------------------------*/
1563 /* operandFromSymbol - creates an operand from a symbol */
1564 /*-----------------------------------------------------------------*/
1566 operandFromSymbol (symbol * sym)
1571 /* if the symbol's type is a literal */
1572 /* then it is an enumerator type */
1573 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1574 return operandFromValue (valFromType (sym->etype));
1577 sym->key = ++operandKey;
1579 /* if this an implicit variable, means struct/union */
1580 /* member so just return it */
1581 if (sym->implicit || IS_FUNC (sym->type))
1585 op->operand.symOperand = sym;
1587 op->isvolatile = isOperandVolatile (op, TRUE);
1588 op->isGlobal = isOperandGlobal (op);
1592 /* under the following conditions create a
1593 register equivalent for a local symbol */
1594 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1595 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1597 (!(options.model == MODEL_FLAT24)) ) &&
1598 options.stackAuto == 0)
1601 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1602 !IS_FUNC (sym->type) && /* not a function */
1603 !sym->_isparm && /* not a parameter */
1604 IS_AUTO (sym) && /* is a local auto variable */
1605 !sym->addrtaken && /* whose address has not been taken */
1606 !sym->reqv && /* does not already have a reg equivalence */
1607 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1608 !sym->islbl && /* not a label */
1609 ok && /* farspace check */
1610 !IS_BITVAR (sym->etype) /* not a bit variable */
1614 /* we will use it after all optimizations
1615 and before liveRange calculation */
1616 sym->reqv = newiTempOperand (sym->type, 0);
1617 sym->reqv->key = sym->key;
1618 OP_SYMBOL (sym->reqv)->prereqv = sym;
1619 OP_SYMBOL (sym->reqv)->key = sym->key;
1620 OP_SYMBOL (sym->reqv)->isreqv = 1;
1621 OP_SYMBOL (sym->reqv)->islocal = 1;
1622 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1623 SPIL_LOC (sym->reqv) = sym;
1626 if (!IS_AGGREGATE (sym->type))
1630 op->operand.symOperand = sym;
1633 op->isvolatile = isOperandVolatile (op, TRUE);
1634 op->isGlobal = isOperandGlobal (op);
1635 op->isPtr = IS_PTR (operandType (op));
1636 op->isParm = sym->_isparm;
1641 /* itemp = &[_symbol] */
1643 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1644 IC_LEFT (ic)->type = SYMBOL;
1645 IC_LEFT (ic)->operand.symOperand = sym;
1646 IC_LEFT (ic)->key = sym->key;
1647 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1648 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1649 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1652 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1653 if (IS_ARRAY (sym->type))
1655 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1656 IC_RESULT (ic)->isaddr = 0;
1659 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1663 return IC_RESULT (ic);
1666 /*-----------------------------------------------------------------*/
1667 /* operandFromValue - creates an operand from value */
1668 /*-----------------------------------------------------------------*/
1670 operandFromValue (value * val)
1674 /* if this is a symbol then do the symbol thing */
1676 return operandFromSymbol (val->sym);
1678 /* this is not a symbol */
1681 op->operand.valOperand = val;
1682 op->isLiteral = isOperandLiteral (op);
1686 /*-----------------------------------------------------------------*/
1687 /* operandFromLink - operand from typeChain */
1688 /*-----------------------------------------------------------------*/
1690 operandFromLink (sym_link * type)
1694 /* operand from sym_link */
1700 op->operand.typeOperand = copyLinkChain (type);
1704 /*-----------------------------------------------------------------*/
1705 /* operandFromLit - makes an operand from a literal value */
1706 /*-----------------------------------------------------------------*/
1708 operandFromLit (double i)
1710 return operandFromValue (valueFromLit (i));
1713 /*-----------------------------------------------------------------*/
1714 /* operandFromAst - creates an operand from an ast */
1715 /*-----------------------------------------------------------------*/
1717 operandFromAst (ast * tree,int lvl)
1723 /* depending on type do */
1727 return ast2iCode (tree,lvl+1);
1731 return operandFromValue (tree->opval.val);
1735 return operandFromLink (tree->opval.lnk);
1742 /* Just to keep the compiler happy */
1743 return (operand *) 0;
1746 /*-----------------------------------------------------------------*/
1747 /* setOperandType - sets the operand's type to the given type */
1748 /*-----------------------------------------------------------------*/
1750 setOperandType (operand * op, sym_link * type)
1752 /* depending on the type of operand */
1757 op->operand.valOperand->etype =
1758 getSpec (op->operand.valOperand->type =
1759 copyLinkChain (type));
1763 if (op->operand.symOperand->isitmp)
1764 op->operand.symOperand->etype =
1765 getSpec (op->operand.symOperand->type =
1766 copyLinkChain (type));
1768 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1769 "attempt to modify type of source");
1773 op->operand.typeOperand = copyLinkChain (type);
1779 /*-----------------------------------------------------------------*/
1780 /* Get size in byte of ptr need to access an array */
1781 /*-----------------------------------------------------------------*/
1783 getArraySizePtr (operand * op)
1785 sym_link *ltype = operandType(op);
1789 int size = getSize(ltype);
1790 return(IS_GENPTR(ltype)?(size-1):size);
1795 sym_link *letype = getSpec(ltype);
1796 switch (PTR_TYPE (SPEC_OCLS (letype)))
1808 return (GPTRSIZE-1);
1817 /*-----------------------------------------------------------------*/
1818 /* perform "usual unary conversions" */
1819 /*-----------------------------------------------------------------*/
1822 usualUnaryConversions (operand * op)
1824 if (IS_INTEGRAL (operandType (op)))
1826 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1829 return geniCodeCast (INTTYPE, op, TRUE);
1836 /*-----------------------------------------------------------------*/
1837 /* perform "usual binary conversions" */
1838 /*-----------------------------------------------------------------*/
1841 usualBinaryConversions (operand ** op1, operand ** op2,
1842 RESULT_TYPE resultType, int op)
1845 sym_link *rtype = operandType (*op2);
1846 sym_link *ltype = operandType (*op1);
1848 ctype = computeType (ltype, rtype, resultType, op);
1855 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1857 /* one byte operations: keep signedness for code generator */
1865 *op1 = geniCodeCast (ctype, *op1, TRUE);
1866 *op2 = geniCodeCast (ctype, *op2, TRUE);
1871 /*-----------------------------------------------------------------*/
1872 /* geniCodeValueAtAddress - generate intermeditate code for value */
1874 /*-----------------------------------------------------------------*/
1876 geniCodeRValue (operand * op, bool force)
1879 sym_link *type = operandType (op);
1880 sym_link *etype = getSpec (type);
1882 /* if this is an array & already */
1883 /* an address then return this */
1884 if (IS_AGGREGATE (type) ||
1885 (IS_PTR (type) && !force && !op->isaddr))
1886 return operandFromOperand (op);
1888 /* if this is not an address then must be */
1889 /* rvalue already so return this one */
1893 /* if this is not a temp symbol then */
1894 if (!IS_ITEMP (op) &&
1896 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1898 op = operandFromOperand (op);
1903 if (IS_SPEC (type) &&
1904 IS_TRUE_SYMOP (op) &&
1905 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1906 (options.model == MODEL_FLAT24) ))
1908 op = operandFromOperand (op);
1913 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1914 if (IS_PTR (type) && op->isaddr && force)
1917 type = copyLinkChain (type);
1919 IC_RESULT (ic) = newiTempOperand (type, 1);
1920 IC_RESULT (ic)->isaddr = 0;
1922 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1926 return IC_RESULT (ic);
1929 /*-----------------------------------------------------------------*/
1930 /* geniCodeCast - changes the value from one type to another */
1931 /*-----------------------------------------------------------------*/
1933 geniCodeCast (sym_link * type, operand * op, bool implicit)
1937 sym_link *opetype = getSpec (optype = operandType (op));
1941 /* one of them has size zero then error */
1942 if (IS_VOID (optype))
1944 werror (E_CAST_ZERO);
1948 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1950 geniCodeArray2Ptr (op);
1954 /* if the operand is already the desired type then do nothing */
1955 if (compareType (type, optype) == 1)
1958 /* if this is a literal then just change the type & return */
1959 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1961 return operandFromValue (valCastLiteral (type,
1962 operandLitValue (op)));
1965 /* if casting to/from pointers, do some checking */
1966 if (IS_PTR(type)) { // to a pointer
1967 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1968 if (IS_INTEGRAL(optype)) {
1969 // maybe this is NULL, than it's ok.
1970 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1971 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1972 // no way to set the storage
1973 if (IS_LITERAL(optype)) {
1974 werror(E_LITERAL_GENERIC);
1977 werror(E_NONPTR2_GENPTR);
1980 } else if (implicit) {
1981 werror(W_INTEGRAL2PTR_NOCAST);
1986 // shouldn't do that with float, array or structure unless to void
1987 if (!IS_VOID(getSpec(type)) &&
1988 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1989 werror(E_INCOMPAT_TYPES);
1993 } else { // from a pointer to a pointer
1994 if (IS_GENPTR(type) && IS_VOID(type->next))
1995 { // cast to void* is always allowed
1997 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
1998 { // cast from void* is always allowed
2000 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2001 // if not a pointer to a function
2002 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2003 if (implicit) { // if not to generic, they have to match
2004 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
2005 werror(E_INCOMPAT_PTYPES);
2012 } else { // to a non pointer
2013 if (IS_PTR(optype)) { // from a pointer
2014 if (implicit) { // sneaky
2015 if (IS_INTEGRAL(type)) {
2016 werror(W_PTR2INTEGRAL_NOCAST);
2018 } else { // shouldn't do that with float, array or structure
2019 werror(E_INCOMPAT_TYPES);
2026 printFromToType (optype, type);
2029 /* if they are the same size create an assignment */
2031 /* This seems very dangerous to me, since there are several */
2032 /* optimizations (for example, gcse) that don't notice the */
2033 /* cast hidden in this assignement and may simplify an */
2034 /* iCode to use the original (uncasted) operand. */
2035 /* Unfortunately, other things break when this cast is */
2036 /* made explicit. Need to fix this someday. */
2037 /* -- EEP, 2004/01/21 */
2038 if (getSize (type) == getSize (optype) &&
2039 !IS_BITFIELD (type) &&
2041 !IS_FLOAT (optype) &&
2042 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2043 (!IS_SPEC (type) && !IS_SPEC (optype))))
2045 ic = newiCode ('=', NULL, op);
2046 IC_RESULT (ic) = newiTempOperand (type, 0);
2047 SPIL_LOC (IC_RESULT (ic)) =
2048 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
2049 IC_RESULT (ic)->isaddr = 0;
2053 ic = newiCode (CAST, operandFromLink (type),
2054 geniCodeRValue (op, FALSE));
2056 IC_RESULT (ic) = newiTempOperand (type, 0);
2059 /* preserve the storage class & output class */
2060 /* of the original variable */
2061 restype = getSpec (operandType (IC_RESULT (ic)));
2062 if (!IS_LITERAL(opetype) &&
2065 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2066 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2069 return IC_RESULT (ic);
2072 /*-----------------------------------------------------------------*/
2073 /* geniCodeLabel - will create a Label */
2074 /*-----------------------------------------------------------------*/
2076 geniCodeLabel (symbol * label)
2080 ic = newiCodeLabelGoto (LABEL, label);
2084 /*-----------------------------------------------------------------*/
2085 /* geniCodeGoto - will create a Goto */
2086 /*-----------------------------------------------------------------*/
2088 geniCodeGoto (symbol * label)
2092 ic = newiCodeLabelGoto (GOTO, label);
2096 /*-----------------------------------------------------------------*/
2097 /* geniCodeMultiply - gen intermediate code for multiplication */
2098 /*-----------------------------------------------------------------*/
2100 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2107 /* if they are both literal then we know the result */
2108 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2109 return operandFromValue (valMult (left->operand.valOperand,
2110 right->operand.valOperand));
2112 if (IS_LITERAL(retype)) {
2113 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2116 resType = usualBinaryConversions (&left, &right, resultType, '*');
2118 rtype = operandType (right);
2119 retype = getSpec (rtype);
2120 ltype = operandType (left);
2121 letype = getSpec (ltype);
2124 /* if the right is a literal & power of 2 */
2125 /* then make it a left shift */
2126 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2127 efficient in most cases than 2 bytes result = 2 bytes << literal
2128 if port has 1 byte muldiv */
2129 if (p2 && !IS_FLOAT (letype)
2130 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2131 && (port->support.muldiv == 1))
2132 && strcmp (port->target, "pic16") != 0 /* don't shift for pic */
2133 && strcmp (port->target, "pic14") != 0)
2135 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2137 /* LEFT_OP need same size for left and result, */
2138 left = geniCodeCast (resType, left, TRUE);
2139 ltype = operandType (left);
2141 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2145 ic = newiCode ('*', left, right); /* normal multiplication */
2146 /* if the size left or right > 1 then support routine */
2147 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2151 IC_RESULT (ic) = newiTempOperand (resType, 1);
2154 return IC_RESULT (ic);
2157 /*-----------------------------------------------------------------*/
2158 /* geniCodeDivision - gen intermediate code for division */
2159 /*-----------------------------------------------------------------*/
2161 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2166 sym_link *rtype = operandType (right);
2167 sym_link *retype = getSpec (rtype);
2168 sym_link *ltype = operandType (left);
2169 sym_link *letype = getSpec (ltype);
2171 resType = usualBinaryConversions (&left, &right, resultType, '/');
2173 /* if the right is a literal & power of 2
2174 and left is unsigned then make it a
2176 if (IS_LITERAL (retype) &&
2177 !IS_FLOAT (letype) &&
2178 IS_UNSIGNED(letype) &&
2179 (p2 = powof2 ((TYPE_UDWORD)
2180 floatFromVal (right->operand.valOperand)))) {
2181 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2185 ic = newiCode ('/', left, right); /* normal division */
2186 /* if the size left or right > 1 then support routine */
2187 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2190 IC_RESULT (ic) = newiTempOperand (resType, 0);
2193 return IC_RESULT (ic);
2195 /*-----------------------------------------------------------------*/
2196 /* geniCodeModulus - gen intermediate code for modulus */
2197 /*-----------------------------------------------------------------*/
2199 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2205 /* if they are both literal then we know the result */
2206 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2207 return operandFromValue (valMod (left->operand.valOperand,
2208 right->operand.valOperand));
2210 resType = usualBinaryConversions (&left, &right, resultType, '%');
2212 /* now they are the same size */
2213 ic = newiCode ('%', left, right);
2215 /* if the size left or right > 1 then support routine */
2216 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2218 IC_RESULT (ic) = newiTempOperand (resType, 0);
2221 return IC_RESULT (ic);
2224 /*-----------------------------------------------------------------*/
2225 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2226 /*-----------------------------------------------------------------*/
2228 geniCodePtrPtrSubtract (operand * left, operand * right)
2234 /* if they are both literals then */
2235 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2237 result = operandFromValue (valMinus (left->operand.valOperand,
2238 right->operand.valOperand));
2242 ic = newiCode ('-', left, right);
2244 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2248 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2252 // should we really do this? is this ANSI?
2253 return geniCodeDivision (result,
2254 operandFromLit (getSize (ltype->next)),
2258 /*-----------------------------------------------------------------*/
2259 /* geniCodeSubtract - generates code for subtraction */
2260 /*-----------------------------------------------------------------*/
2262 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2269 /* if they both pointers then */
2270 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2271 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2272 return geniCodePtrPtrSubtract (left, right);
2274 /* if they are both literal then we know the result */
2275 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2276 && left->isLiteral && right->isLiteral)
2277 return operandFromValue (valMinus (left->operand.valOperand,
2278 right->operand.valOperand));
2280 /* if left is an array or pointer */
2281 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2283 isarray = left->isaddr;
2284 right = geniCodeMultiply (right,
2285 operandFromLit (getSize (ltype->next)),
2286 (getArraySizePtr(left) >= INTSIZE) ?
2289 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2292 { /* make them the same size */
2293 resType = usualBinaryConversions (&left, &right, resultType, '-');
2296 ic = newiCode ('-', left, right);
2298 IC_RESULT (ic) = newiTempOperand (resType, 1);
2299 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2301 /* if left or right is a float */
2302 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2306 return IC_RESULT (ic);
2309 /*-----------------------------------------------------------------*/
2310 /* geniCodeAdd - generates iCode for addition */
2311 /*-----------------------------------------------------------------*/
2313 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2322 /* if the right side is LITERAL zero */
2323 /* return the left side */
2324 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2327 /* if left is literal zero return right */
2328 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2331 /* if left is a pointer then size */
2332 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2334 isarray = left->isaddr;
2335 // there is no need to multiply with 1
2336 if (getSize (ltype->next) != 1)
2338 size = operandFromLit (getSize (ltype->next));
2339 SPEC_USIGN (getSpec (operandType (size))) = 1;
2340 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2341 right = geniCodeMultiply (right,
2343 (getArraySizePtr(left) >= INTSIZE) ?
2346 /* Even if right is a 'unsigned char',
2347 the result will be a 'signed int' due to the promotion rules.
2348 It doesn't make sense when accessing arrays, so let's fix it here: */
2350 SPEC_USIGN (getSpec (operandType (right))) = 1;
2352 resType = copyLinkChain (ltype);
2355 { // make them the same size
2356 resType = usualBinaryConversions (&left, &right, resultType, '+');
2359 /* if they are both literals then we know */
2360 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2361 && left->isLiteral && right->isLiteral)
2362 return operandFromValue (valPlus (valFromType (ltype),
2363 valFromType (rtype)));
2365 ic = newiCode ('+', left, right);
2367 IC_RESULT (ic) = newiTempOperand (resType, 1);
2368 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2370 /* if left or right is a float then support
2372 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2377 return IC_RESULT (ic);
2381 /*-----------------------------------------------------------------*/
2382 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2383 /*-----------------------------------------------------------------*/
2385 aggrToPtr (sym_link * type, bool force)
2390 if (IS_PTR (type) && !force)
2393 etype = getSpec (type);
2394 ptype = newLink (DECLARATOR);
2398 /* set the pointer depending on the storage class */
2399 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2403 /*------------------------------------------------------------------*/
2404 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2405 /*------------------------------------------------------------------*/
2407 aggrToPtrDclType (sym_link * type, bool force)
2409 if (IS_PTR (type) && !force)
2410 return DCL_TYPE (type);
2412 /* return the pointer depending on the storage class */
2413 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2416 /*-----------------------------------------------------------------*/
2417 /* geniCodeArray2Ptr - array to pointer */
2418 /*-----------------------------------------------------------------*/
2420 geniCodeArray2Ptr (operand * op)
2422 sym_link *optype = operandType (op);
2423 sym_link *opetype = getSpec (optype);
2425 /* set the pointer depending on the storage class */
2426 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2433 /*-----------------------------------------------------------------*/
2434 /* geniCodeArray - array access */
2435 /*-----------------------------------------------------------------*/
2437 geniCodeArray (operand * left, operand * right, int lvl)
2441 sym_link *ltype = operandType (left);
2446 if (IS_PTR (ltype->next) && left->isaddr)
2448 left = geniCodeRValue (left, FALSE);
2451 return geniCodeDerefPtr (geniCodeAdd (left,
2453 (getArraySizePtr(left) >= INTSIZE) ?
2459 size = operandFromLit (getSize (ltype->next));
2460 SPEC_USIGN (getSpec (operandType (size))) = 1;
2461 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2462 right = geniCodeMultiply (right,
2464 (getArraySizePtr(left) >= INTSIZE) ?
2467 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2468 It doesn't make sense when accessing arrays, so let's fix it here: */
2470 SPEC_USIGN (getSpec (operandType (right))) = 1;
2471 /* we can check for limits here */
2472 /* already done in SDCCast.c
2473 if (isOperandLiteral (right) &&
2476 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2478 werror (W_IDX_OUT_OF_BOUNDS,
2479 (int) operandLitValue (right) / getSize (ltype->next),
2484 ic = newiCode ('+', left, right);
2486 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2487 !IS_AGGREGATE (ltype->next) &&
2488 !IS_PTR (ltype->next))
2489 ? ltype : ltype->next), 0);
2491 if (!IS_AGGREGATE (ltype->next))
2493 IC_RESULT (ic)->isaddr = 1;
2494 IC_RESULT (ic)->aggr2ptr = 1;
2498 return IC_RESULT (ic);
2501 /*-----------------------------------------------------------------*/
2502 /* geniCodeStruct - generates intermediate code for structures */
2503 /*-----------------------------------------------------------------*/
2505 geniCodeStruct (operand * left, operand * right, bool islval)
2508 sym_link *type = operandType (left);
2509 sym_link *etype = getSpec (type);
2511 symbol *element = getStructElement (SPEC_STRUCT (etype),
2512 right->operand.symOperand);
2514 wassert(IS_SYMOP(right));
2516 /* add the offset */
2517 ic = newiCode ('+', left, operandFromLit (element->offset));
2519 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2521 /* preserve the storage & output class of the struct */
2522 /* as well as the volatile attribute */
2523 retype = getSpec (operandType (IC_RESULT (ic)));
2524 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2525 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2526 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2527 SPEC_CONST (retype) |= SPEC_CONST (etype);
2529 if (IS_PTR (element->type))
2530 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2532 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2535 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2538 /*-----------------------------------------------------------------*/
2539 /* geniCodePostInc - generate int code for Post increment */
2540 /*-----------------------------------------------------------------*/
2542 geniCodePostInc (operand * op)
2546 sym_link *optype = operandType (op);
2548 operand *rv = (IS_ITEMP (op) ?
2549 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2551 sym_link *rvtype = operandType (rv);
2554 /* if this is not an address we have trouble */
2557 werror (E_LVALUE_REQUIRED, "++");
2561 rOp = newiTempOperand (rvtype, 0);
2562 OP_SYMBOL(rOp)->noSpilLoc = 1;
2565 OP_SYMBOL(rv)->noSpilLoc = 1;
2567 geniCodeAssign (rOp, rv, 0, 0);
2569 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2571 werror(W_SIZEOF_VOID);
2572 if (IS_FLOAT (rvtype))
2573 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2575 ic = newiCode ('+', rv, operandFromLit (size));
2577 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2580 geniCodeAssign (op, result, 0, 0);
2586 /*-----------------------------------------------------------------*/
2587 /* geniCodePreInc - generate code for preIncrement */
2588 /*-----------------------------------------------------------------*/
2590 geniCodePreInc (operand * op, bool lvalue)
2593 sym_link *optype = operandType (op);
2594 operand *rop = (IS_ITEMP (op) ?
2595 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2597 sym_link *roptype = operandType (rop);
2603 werror (E_LVALUE_REQUIRED, "++");
2607 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2609 werror(W_SIZEOF_VOID);
2610 if (IS_FLOAT (roptype))
2611 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2613 ic = newiCode ('+', rop, operandFromLit (size));
2614 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2617 (void) geniCodeAssign (op, result, 0, 0);
2618 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2624 /*-----------------------------------------------------------------*/
2625 /* geniCodePostDec - generates code for Post decrement */
2626 /*-----------------------------------------------------------------*/
2628 geniCodePostDec (operand * op)
2632 sym_link *optype = operandType (op);
2634 operand *rv = (IS_ITEMP (op) ?
2635 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2637 sym_link *rvtype = operandType (rv);
2640 /* if this is not an address we have trouble */
2643 werror (E_LVALUE_REQUIRED, "--");
2647 rOp = newiTempOperand (rvtype, 0);
2648 OP_SYMBOL(rOp)->noSpilLoc = 1;
2651 OP_SYMBOL(rv)->noSpilLoc = 1;
2653 geniCodeAssign (rOp, rv, 0, 0);
2655 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2657 werror(W_SIZEOF_VOID);
2658 if (IS_FLOAT (rvtype))
2659 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2661 ic = newiCode ('-', rv, operandFromLit (size));
2663 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2666 geniCodeAssign (op, result, 0, 0);
2672 /*-----------------------------------------------------------------*/
2673 /* geniCodePreDec - generate code for pre decrement */
2674 /*-----------------------------------------------------------------*/
2676 geniCodePreDec (operand * op, bool lvalue)
2679 sym_link *optype = operandType (op);
2680 operand *rop = (IS_ITEMP (op) ?
2681 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2683 sym_link *roptype = operandType (rop);
2689 werror (E_LVALUE_REQUIRED, "--");
2693 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2695 werror(W_SIZEOF_VOID);
2696 if (IS_FLOAT (roptype))
2697 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2699 ic = newiCode ('-', rop, operandFromLit (size));
2700 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2703 (void) geniCodeAssign (op, result, 0, 0);
2704 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2711 /*-----------------------------------------------------------------*/
2712 /* geniCodeBitwise - gen int code for bitWise operators */
2713 /*-----------------------------------------------------------------*/
2715 geniCodeBitwise (operand * left, operand * right,
2716 int oper, sym_link * resType)
2720 left = geniCodeCast (resType, left, TRUE);
2721 right = geniCodeCast (resType, right, TRUE);
2723 ic = newiCode (oper, left, right);
2724 IC_RESULT (ic) = newiTempOperand (resType, 0);
2727 return IC_RESULT (ic);
2730 /*-----------------------------------------------------------------*/
2731 /* geniCodeAddressOf - gens icode for '&' address of operator */
2732 /*-----------------------------------------------------------------*/
2734 geniCodeAddressOf (operand * op)
2738 sym_link *optype = operandType (op);
2739 sym_link *opetype = getSpec (optype);
2741 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2743 op = operandFromOperand (op);
2748 /* lvalue check already done in decorateType */
2749 /* this must be a lvalue */
2750 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2751 /* werror (E_LVALUE_REQUIRED,"&"); */
2755 p = newLink (DECLARATOR);
2757 /* set the pointer depending on the storage class */
2758 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2760 p->next = copyLinkChain (optype);
2762 /* if already a temp */
2765 setOperandType (op, p);
2770 /* other wise make this of the type coming in */
2771 ic = newiCode (ADDRESS_OF, op, NULL);
2772 IC_RESULT (ic) = newiTempOperand (p, 1);
2773 IC_RESULT (ic)->isaddr = 0;
2775 return IC_RESULT (ic);
2777 /*-----------------------------------------------------------------*/
2778 /* setOClass - sets the output class depending on the pointer type */
2779 /*-----------------------------------------------------------------*/
2781 setOClass (sym_link * ptr, sym_link * spec)
2783 switch (DCL_TYPE (ptr))
2786 SPEC_OCLS (spec) = data;
2790 SPEC_OCLS (spec) = generic;
2794 SPEC_OCLS (spec) = xdata;
2798 SPEC_OCLS (spec) = code;
2802 SPEC_OCLS (spec) = idata;
2806 SPEC_OCLS (spec) = xstack;
2810 SPEC_OCLS (spec) = eeprom;
2819 /*-----------------------------------------------------------------*/
2820 /* geniCodeDerefPtr - dereference pointer with '*' */
2821 /*-----------------------------------------------------------------*/
2823 geniCodeDerefPtr (operand * op,int lvl)
2825 sym_link *rtype, *retype;
2826 sym_link *optype = operandType (op);
2828 // if this is an array then array access
2829 if (IS_ARRAY (optype)) {
2830 // don't worry, this will be optimized out later
2831 return geniCodeArray (op, operandFromLit (0), lvl);
2834 // just in case someone screws up
2835 wassert (IS_PTR (optype));
2837 if (IS_TRUE_SYMOP (op))
2840 op = geniCodeRValue (op, TRUE);
2843 /* now get rid of the pointer part */
2844 if (isLvaluereq(lvl) && IS_ITEMP (op))
2846 retype = getSpec (rtype = copyLinkChain (optype));
2850 retype = getSpec (rtype = copyLinkChain (optype->next));
2851 /* outputclass needs 2b updated */
2852 setOClass (optype, retype);
2855 op->isGptr = IS_GENPTR (optype);
2857 op->isaddr = (IS_PTR (rtype) ||
2858 IS_STRUCT (rtype) ||
2863 if (!isLvaluereq(lvl))
2864 op = geniCodeRValue (op, TRUE);
2866 setOperandType (op, rtype);
2871 /*-----------------------------------------------------------------*/
2872 /* geniCodeUnaryMinus - does a unary minus of the operand */
2873 /*-----------------------------------------------------------------*/
2875 geniCodeUnaryMinus (operand * op)
2878 sym_link *optype = operandType (op);
2880 if (IS_LITERAL (optype))
2881 return operandFromLit (-floatFromVal (op->operand.valOperand));
2883 ic = newiCode (UNARYMINUS, op, NULL);
2884 IC_RESULT (ic) = newiTempOperand (optype, 0);
2886 return IC_RESULT (ic);
2889 /*-----------------------------------------------------------------*/
2890 /* geniCodeLeftShift - gen i code for left shift */
2891 /*-----------------------------------------------------------------*/
2893 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2898 ic = newiCode (LEFT_OP, left, right);
2900 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2901 IC_RESULT (ic) = newiTempOperand (resType, 0);
2903 return IC_RESULT (ic);
2906 /*-----------------------------------------------------------------*/
2907 /* geniCodeRightShift - gen i code for right shift */
2908 /*-----------------------------------------------------------------*/
2910 geniCodeRightShift (operand * left, operand * right)
2914 ic = newiCode (RIGHT_OP, left, right);
2915 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2917 return IC_RESULT (ic);
2920 /*-----------------------------------------------------------------*/
2921 /* geniCodeLogic- logic code */
2922 /*-----------------------------------------------------------------*/
2924 geniCodeLogic (operand * left, operand * right, int op)
2928 sym_link *rtype = operandType (right);
2929 sym_link *ltype = operandType (left);
2931 /* left is integral type and right is literal then
2932 check if the literal value is within bounds */
2933 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2935 checkConstantRange(ltype,
2936 OP_VALUE(right), "compare operation", 1);
2939 /* if one operand is a pointer and the other is a literal generic void pointer,
2940 change the type of the literal generic void pointer to match the other pointer */
2941 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2942 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2944 /* find left's definition */
2945 ic = (iCode *) setFirstItem (iCodeChain);
2948 if (((ic->op == CAST) || (ic->op == '='))
2949 && isOperandEqual(left, IC_RESULT (ic)))
2952 ic = setNextItem (iCodeChain);
2954 /* if casting literal to generic pointer, then cast to rtype instead */
2955 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2957 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2958 ltype = operandType(left);
2961 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2962 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2964 /* find right's definition */
2965 ic = (iCode *) setFirstItem (iCodeChain);
2968 if (((ic->op == CAST) || (ic->op == '='))
2969 && isOperandEqual(right, IC_RESULT (ic)))
2972 ic = setNextItem (iCodeChain);
2974 /* if casting literal to generic pointer, then cast to rtype instead */
2975 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2977 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2978 rtype = operandType(right);
2982 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
2984 ic = newiCode (op, left, right);
2985 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2987 /* if comparing float
2988 and not a '==' || '!=' || '&&' || '||' (these
2990 if (IS_FLOAT(ctype) &&
2998 return IC_RESULT (ic);
3001 /*-----------------------------------------------------------------*/
3002 /* geniCodeLogicAndOr - && || operations */
3003 /*-----------------------------------------------------------------*/
3005 geniCodeLogicAndOr (ast *tree, int lvl)
3008 symbol *falseLabel = newiTempLabel (NULL);
3009 symbol *trueLabel = newiTempLabel (NULL);
3010 symbol *exitLabel = newiTempLabel (NULL);
3011 operand *op, *result, *condition;
3013 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3014 They can be reenabled by executing the following block. If you find
3015 a decent optimization you could start right here:
3020 operand *leftOp, *rightOp;
3022 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3023 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3025 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3029 /* generate two IFX for the '&&' or '||' op */
3031 /* evaluate left operand */
3032 condition = ast2iCode (tree->left, lvl + 1);
3033 op = geniCodeRValue (condition, FALSE);
3035 /* test left operand */
3036 if (tree->opval.op == AND_OP)
3037 ic = newiCodeCondition (op, NULL, falseLabel);
3039 ic = newiCodeCondition (op, trueLabel, NULL);
3042 /* evaluate right operand */
3043 condition = ast2iCode (tree->right, lvl + 1);
3044 op = geniCodeRValue (condition, FALSE);
3046 /* test right operand */
3047 ic = newiCodeCondition (op, trueLabel, NULL);
3050 /* store 0 or 1 in result */
3051 result = newiTempOperand (newCharLink(), 1);
3053 geniCodeLabel (falseLabel);
3054 geniCodeAssign (result, operandFromLit (0), 0, 0);
3055 /* generate an unconditional goto */
3056 geniCodeGoto (exitLabel);
3058 geniCodeLabel (trueLabel);
3059 geniCodeAssign (result, operandFromLit (1), 0, 0);
3061 geniCodeLabel (exitLabel);
3066 /*-----------------------------------------------------------------*/
3067 /* geniCodeUnary - for a a generic unary operation */
3068 /*-----------------------------------------------------------------*/
3070 geniCodeUnary (operand * op, int oper)
3072 iCode *ic = newiCode (oper, op, NULL);
3074 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3076 return IC_RESULT (ic);
3079 /*-----------------------------------------------------------------*/
3080 /* geniCodeConditional - geniCode for '?' ':' operation */
3081 /*-----------------------------------------------------------------*/
3083 geniCodeConditional (ast * tree,int lvl)
3086 symbol *falseLabel = newiTempLabel (NULL);
3087 symbol *exitLabel = newiTempLabel (NULL);
3088 operand *cond = ast2iCode (tree->left,lvl+1);
3089 operand *true, *false, *result;
3091 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3095 true = ast2iCode (tree->right->left,lvl+1);
3097 /* move the value to a new Operand */
3098 result = newiTempOperand (tree->right->ftype, 0);
3099 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3101 /* generate an unconditional goto */
3102 geniCodeGoto (exitLabel);
3104 /* now for the right side */
3105 geniCodeLabel (falseLabel);
3107 false = ast2iCode (tree->right->right,lvl+1);
3108 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3110 /* create the exit label */
3111 geniCodeLabel (exitLabel);
3116 /*-----------------------------------------------------------------*/
3117 /* geniCodeAssign - generate code for assignment */
3118 /*-----------------------------------------------------------------*/
3120 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3123 sym_link *ltype = operandType (left);
3124 sym_link *rtype = operandType (right);
3126 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3128 werror (E_LVALUE_REQUIRED, "assignment");
3132 /* left is integral type and right is literal then
3133 check if the literal value is within bounds */
3134 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3136 checkConstantRange(ltype,
3137 OP_VALUE(right), "= operation", 0);
3140 /* if the left & right type don't exactly match */
3141 /* if pointer set then make sure the check is
3142 done with the type & not the pointer */
3143 /* then cast rights type to left */
3145 /* first check the type for pointer assignement */
3146 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3147 compareType (ltype, rtype) <= 0)
3149 if (compareType (ltype->next, rtype) < 0)
3150 right = geniCodeCast (ltype->next, right, TRUE);
3152 else if (compareType (ltype, rtype) < 0)
3153 right = geniCodeCast (ltype, right, TRUE);
3155 /* If left is a true symbol & ! volatile
3156 create an assignment to temporary for
3157 the right & then assign this temporary
3158 to the symbol. This is SSA (static single
3159 assignment). Isn't it simple and folks have
3160 published mountains of paper on it */
3161 if (IS_TRUE_SYMOP (left) &&
3162 !isOperandVolatile (left, FALSE) &&
3163 isOperandGlobal (left))
3167 if (IS_TRUE_SYMOP (right))
3168 sym = OP_SYMBOL (right);
3169 ic = newiCode ('=', NULL, right);
3170 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3171 SPIL_LOC (right) = sym;
3175 ic = newiCode ('=', NULL, right);
3176 IC_RESULT (ic) = left;
3179 /* if left isgptr flag is set then support
3180 routine will be required */
3184 ic->nosupdate = nosupdate;
3188 /*-----------------------------------------------------------------*/
3189 /* geniCodeDummyRead - generate code for dummy read */
3190 /*-----------------------------------------------------------------*/
3192 geniCodeDummyRead (operand * op)
3195 sym_link *type = operandType (op);
3197 if (!IS_VOLATILE(type))
3200 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3206 /*-----------------------------------------------------------------*/
3207 /* geniCodeSEParms - generate code for side effecting fcalls */
3208 /*-----------------------------------------------------------------*/
3210 geniCodeSEParms (ast * parms,int lvl)
3215 if (parms->type == EX_OP && parms->opval.op == PARAM)
3217 geniCodeSEParms (parms->left,lvl);
3218 geniCodeSEParms (parms->right,lvl);
3222 /* hack don't like this but too lazy to think of
3224 if (IS_ADDRESS_OF_OP (parms))
3225 parms->left->lvalue = 1;
3227 if (IS_CAST_OP (parms) &&
3228 IS_PTR (parms->ftype) &&
3229 IS_ADDRESS_OF_OP (parms->right))
3230 parms->right->left->lvalue = 1;
3232 parms->opval.oprnd =
3233 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3235 parms->type = EX_OPERAND;
3236 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3237 SPEC_ARGREG(parms->ftype);
3240 /*-----------------------------------------------------------------*/
3241 /* geniCodeParms - generates parameters */
3242 /*-----------------------------------------------------------------*/
3244 geniCodeParms (ast * parms, value *argVals, int *stack,
3245 sym_link * ftype, int lvl)
3253 if (argVals==NULL) {
3255 argVals = FUNC_ARGS (ftype);
3258 /* if this is a param node then do the left & right */
3259 if (parms->type == EX_OP && parms->opval.op == PARAM)
3261 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3262 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3266 /* get the parameter value */
3267 if (parms->type == EX_OPERAND)
3268 pval = parms->opval.oprnd;
3271 /* maybe this else should go away ?? */
3272 /* hack don't like this but too lazy to think of
3274 if (IS_ADDRESS_OF_OP (parms))
3275 parms->left->lvalue = 1;
3277 if (IS_CAST_OP (parms) &&
3278 IS_PTR (parms->ftype) &&
3279 IS_ADDRESS_OF_OP (parms->right))
3280 parms->right->left->lvalue = 1;
3282 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3285 /* if register parm then make it a send */
3286 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3287 IFFUNC_ISBUILTIN(ftype))
3289 ic = newiCode (SEND, pval, NULL);
3290 ic->argreg = SPEC_ARGREG(parms->etype);
3291 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3296 /* now decide whether to push or assign */
3297 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3301 operand *top = operandFromSymbol (argVals->sym);
3302 /* clear useDef and other bitVectors */
3303 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3304 geniCodeAssign (top, pval, 1, 0);
3308 sym_link *p = operandType (pval);
3310 ic = newiCode (IPUSH, pval, NULL);
3312 /* update the stack adjustment */
3313 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3318 argVals=argVals->next;
3322 /*-----------------------------------------------------------------*/
3323 /* geniCodeCall - generates temp code for calling */
3324 /*-----------------------------------------------------------------*/
3326 geniCodeCall (operand * left, ast * parms,int lvl)
3330 sym_link *type, *etype;
3334 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3335 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3336 werror (E_FUNCTION_EXPECTED);
3337 return operandFromValue(valueFromLit(0));
3340 /* take care of parameters with side-effecting
3341 function calls in them, this is required to take care
3342 of overlaying function parameters */
3343 geniCodeSEParms (parms,lvl);
3345 ftype = operandType (left);
3346 if (IS_CODEPTR (ftype))
3347 ftype = ftype->next;
3349 /* first the parameters */
3350 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3352 /* now call : if symbol then pcall */
3353 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3354 ic = newiCode (PCALL, left, NULL);
3356 ic = newiCode (CALL, left, NULL);
3359 type = copyLinkChain (ftype->next);
3360 etype = getSpec (type);
3361 SPEC_EXTR (etype) = 0;
3362 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3366 /* stack adjustment after call */
3367 ic->parmBytes = stack;
3372 /*-----------------------------------------------------------------*/
3373 /* geniCodeReceive - generate intermediate code for "receive" */
3374 /*-----------------------------------------------------------------*/
3376 geniCodeReceive (value * args)
3378 /* for all arguments that are passed in registers */
3382 if (IS_REGPARM (args->etype))
3384 operand *opr = operandFromValue (args);
3386 symbol *sym = OP_SYMBOL (opr);
3389 /* we will use it after all optimizations
3390 and before liveRange calculation */
3391 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3394 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3395 options.stackAuto == 0 &&
3396 (!(options.model == MODEL_FLAT24)) )
3401 opl = newiTempOperand (args->type, 0);
3403 sym->reqv->key = sym->key;
3404 OP_SYMBOL (sym->reqv)->key = sym->key;
3405 OP_SYMBOL (sym->reqv)->isreqv = 1;
3406 OP_SYMBOL (sym->reqv)->islocal = 0;
3407 SPIL_LOC (sym->reqv) = sym;
3411 ic = newiCode (RECEIVE, NULL, NULL);
3412 ic->argreg = SPEC_ARGREG(args->etype);
3414 currFunc->recvSize = getSize (sym->type);
3417 IC_RESULT (ic) = opr;
3425 /*-----------------------------------------------------------------*/
3426 /* geniCodeFunctionBody - create the function body */
3427 /*-----------------------------------------------------------------*/
3429 geniCodeFunctionBody (ast * tree,int lvl)
3436 /* reset the auto generation */
3442 func = ast2iCode (tree->left,lvl+1);
3443 fetype = getSpec (operandType (func));
3445 savelineno = lineno;
3446 lineno = OP_SYMBOL (func)->lineDef;
3447 /* create an entry label */
3448 geniCodeLabel (entryLabel);
3449 lineno = savelineno;
3451 /* create a proc icode */
3452 ic = newiCode (FUNCTION, func, NULL);
3453 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3458 /* for all parameters that are passed
3459 on registers add a "receive" */
3460 geniCodeReceive (tree->values.args);
3462 /* generate code for the body */
3463 ast2iCode (tree->right,lvl+1);
3465 /* create a label for return */
3466 geniCodeLabel (returnLabel);
3468 /* now generate the end proc */
3469 ic = newiCode (ENDFUNCTION, func, NULL);
3475 /*-----------------------------------------------------------------*/
3476 /* geniCodeReturn - gen icode for 'return' statement */
3477 /*-----------------------------------------------------------------*/
3479 geniCodeReturn (operand * op)
3483 /* if the operand is present force an rvalue */
3485 op = geniCodeRValue (op, FALSE);
3487 ic = newiCode (RETURN, op, NULL);
3491 /*-----------------------------------------------------------------*/
3492 /* geniCodeIfx - generates code for extended if statement */
3493 /*-----------------------------------------------------------------*/
3495 geniCodeIfx (ast * tree,int lvl)
3498 operand *condition = ast2iCode (tree->left,lvl+1);
3501 /* if condition is null then exit */
3505 condition = geniCodeRValue (condition, FALSE);
3507 cetype = getSpec (operandType (condition));
3508 /* if the condition is a literal */
3509 if (IS_LITERAL (cetype))
3511 if (floatFromVal (condition->operand.valOperand))
3513 if (tree->trueLabel)
3514 geniCodeGoto (tree->trueLabel);
3520 if (tree->falseLabel)
3521 geniCodeGoto (tree->falseLabel);
3528 if (tree->trueLabel)
3530 ic = newiCodeCondition (condition,
3535 if (tree->falseLabel)
3536 geniCodeGoto (tree->falseLabel);
3540 ic = newiCodeCondition (condition,
3547 ast2iCode (tree->right,lvl+1);
3550 /*-----------------------------------------------------------------*/
3551 /* geniCodeJumpTable - tries to create a jump table for switch */
3552 /*-----------------------------------------------------------------*/
3554 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3556 int min, max, cnt = 1;
3563 int needRangeCheck = !optimize.noJTabBoundary
3564 || tree->values.switchVals.swDefault;
3565 sym_link *cetype = getSpec (operandType (cond));
3566 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3567 int sizeofMatchJump, sizeofJumpTable;
3570 if (!tree || !caseVals)
3573 /* the criteria for creating a jump table is */
3574 /* all integer numbers between the maximum & minimum must */
3575 /* be present , the maximum value should not exceed 255 */
3576 /* If not all integer numbers are present the algorithm */
3577 /* inserts jumps to the default label for the missing numbers */
3578 /* and decides later whether it is worth it */
3579 min = (int) floatFromVal (vch = caseVals);
3586 max = (int) floatFromVal (vch);
3588 /* Exit if the range is too large to handle with a jump table. */
3589 if (1 + max - min > port->jumptableCost.maxCount)
3592 switch (getSize (operandType (cond)))
3594 case 1: sizeIndex = 0; break;
3595 case 2: sizeIndex = 1; break;
3596 case 4: sizeIndex = 2; break;
3600 /* Compute the size cost of the range check and subtraction. */
3602 sizeofZeroMinCost = 0;
3606 if (!(min==0 && IS_UNSIGNED (cetype)))
3607 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3608 if (!IS_UNSIGNED (cetype))
3609 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3610 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3613 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3615 /* If the size cost of handling a non-zero minimum exceeds the */
3616 /* cost of extending the range down to zero, then it might be */
3617 /* better to extend the range to zero. */
3618 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3619 >= (min * port->jumptableCost.sizeofElement))
3621 /* Only extend the jump table if it would still be manageable. */
3622 if (1 + max <= port->jumptableCost.maxCount)
3625 if (IS_UNSIGNED (cetype))
3628 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3632 /* Compute the total size cost of a jump table. */
3633 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3634 + port->jumptableCost.sizeofDispatch
3635 + sizeofMinCost + sizeofMaxCost;
3637 /* Compute the total size cost of a match & jump sequence */
3638 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3640 /* If the size cost of the jump table is uneconomical then exit */
3641 if (sizeofMatchJump < sizeofJumpTable)
3644 /* The jump table is preferable. */
3646 /* First, a label for the default or missing cases. */
3647 if (tree->values.switchVals.swDefault)
3649 SNPRINTF (buffer, sizeof(buffer),
3651 tree->values.switchVals.swNum);
3655 SNPRINTF (buffer, sizeof(buffer),
3657 tree->values.switchVals.swNum);
3659 falseLabel = newiTempLabel (buffer);
3661 /* Build the list of labels for the jump table. */
3663 t = (int) floatFromVal (vch);
3664 for (i=min; i<=max; i++)
3668 /* Explicit case: make a new label for it. */
3669 SNPRINTF (buffer, sizeof(buffer),
3671 tree->values.switchVals.swNum,
3673 addSet (&labels, newiTempLabel (buffer));
3676 t = (int) floatFromVal (vch);
3680 /* Implicit case: use the default label. */
3681 addSet (&labels, falseLabel);
3685 /* If cond is volatile, it might change after the boundary */
3686 /* conditions are tested to an out of bounds value, causing */
3687 /* a jump to a location outside of the jump table. To avoid */
3688 /* this possibility, use a non-volatile copy of it instead. */
3689 if (IS_OP_VOLATILE (cond))
3694 newcond = newiTempOperand (operandType (cond), TRUE);
3695 newcond->isvolatile = 0;
3696 ic = newiCode ('=', NULL, cond);
3697 IC_RESULT (ic) = newcond;
3702 /* first we rule out the boundary conditions */
3703 /* if only optimization says so */
3706 sym_link *cetype = getSpec (operandType (cond));
3707 /* no need to check the lower bound if
3708 the condition is unsigned & minimum value is zero */
3709 if (!(min == 0 && IS_UNSIGNED (cetype)))
3711 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3712 ic = newiCodeCondition (boundary, falseLabel, NULL);
3716 /* now for upper bounds */
3717 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3718 ic = newiCodeCondition (boundary, falseLabel, NULL);
3722 /* if the min is not zero then we no make it zero */
3725 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3726 if (!IS_LITERAL(getSpec(operandType(cond))))
3727 setOperandType (cond, UCHARTYPE);
3730 /* now create the jumptable */
3731 ic = newiCode (JUMPTABLE, NULL, NULL);
3732 IC_JTCOND (ic) = cond;
3733 IC_JTLABELS (ic) = labels;
3738 /*-----------------------------------------------------------------*/
3739 /* geniCodeSwitch - changes a switch to a if statement */
3740 /*-----------------------------------------------------------------*/
3742 geniCodeSwitch (ast * tree,int lvl)
3745 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3746 value *caseVals = tree->values.switchVals.swVals;
3747 symbol *trueLabel, *falseLabel;
3749 /* If the condition is a literal, then just jump to the */
3750 /* appropriate case label. */
3751 if (IS_LITERAL(getSpec(operandType(cond))))
3753 int switchVal, caseVal;
3755 switchVal = (int) floatFromVal (cond->operand.valOperand);
3758 caseVal = (int) floatFromVal (caseVals);
3759 if (caseVal == switchVal)
3761 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3762 tree->values.switchVals.swNum, caseVal);
3763 trueLabel = newiTempLabel (buffer);
3764 geniCodeGoto (trueLabel);
3767 caseVals = caseVals->next;
3769 goto defaultOrBreak;
3772 /* if we can make this a jump table */
3773 if (geniCodeJumpTable (cond, caseVals, tree))
3774 goto jumpTable; /* no need for the comparison */
3776 /* for the cases defined do */
3780 operand *compare = geniCodeLogic (cond,
3781 operandFromValue (caseVals),
3784 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3785 tree->values.switchVals.swNum,
3786 (int) floatFromVal (caseVals));
3787 trueLabel = newiTempLabel (buffer);
3789 ic = newiCodeCondition (compare, trueLabel, NULL);
3791 caseVals = caseVals->next;
3796 /* if default is present then goto break else break */
3797 if (tree->values.switchVals.swDefault)
3799 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3803 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3806 falseLabel = newiTempLabel (buffer);
3807 geniCodeGoto (falseLabel);
3810 ast2iCode (tree->right,lvl+1);
3813 /*-----------------------------------------------------------------*/
3814 /* geniCodeInline - intermediate code for inline assembler */
3815 /*-----------------------------------------------------------------*/
3817 geniCodeInline (ast * tree)
3821 ic = newiCode (INLINEASM, NULL, NULL);
3822 IC_INLINE (ic) = tree->values.inlineasm;
3826 /*-----------------------------------------------------------------*/
3827 /* geniCodeArrayInit - intermediate code for array initializer */
3828 /*-----------------------------------------------------------------*/
3830 geniCodeArrayInit (ast * tree, operand *array)
3834 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3835 ic = newiCode (ARRAYINIT, array, NULL);
3836 IC_ARRAYILIST (ic) = tree->values.constlist;
3838 operand *left=newOperand(), *right=newOperand();
3839 left->type=right->type=SYMBOL;
3840 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3841 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3842 ic = newiCode (ARRAYINIT, left, right);
3847 /*-----------------------------------------------------------------*/
3848 /* geniCodeCritical - intermediate code for a critical statement */
3849 /*-----------------------------------------------------------------*/
3851 geniCodeCritical (ast *tree, int lvl)
3857 if (!options.stackAuto)
3859 type = newLink(SPECIFIER);
3860 SPEC_VOLATILE(type) = 1;
3861 SPEC_NOUN(type) = V_BIT;
3862 SPEC_SCLS(type) = S_BIT;
3863 SPEC_BLEN(type) = 1;
3864 SPEC_BSTR(type) = 0;
3865 op = newiTempOperand(type, 1);
3868 /* If op is NULL, the original interrupt state will saved on */
3869 /* the stack. Otherwise, it will be saved in op. */
3871 /* Generate a save of the current interrupt state & disable */
3872 ic = newiCode (CRITICAL, NULL, NULL);
3873 IC_RESULT (ic) = op;
3876 /* Generate the critical code sequence */
3877 if (tree->left && tree->left->type == EX_VALUE)
3878 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3880 ast2iCode (tree->left,lvl+1);
3882 /* Generate a restore of the original interrupt state */
3883 ic = newiCode (ENDCRITICAL, NULL, op);
3887 /*-----------------------------------------------------------------*/
3888 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3889 /* particular case. Ie : assigning or dereferencing array or ptr */
3890 /*-----------------------------------------------------------------*/
3891 set * lvaluereqSet = NULL;
3892 typedef struct lvalItem
3899 /*-----------------------------------------------------------------*/
3900 /* addLvaluereq - add a flag for lvalreq for current ast level */
3901 /*-----------------------------------------------------------------*/
3902 void addLvaluereq(int lvl)
3904 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3907 addSetHead(&lvaluereqSet,lpItem);
3910 /*-----------------------------------------------------------------*/
3911 /* delLvaluereq - del a flag for lvalreq for current ast level */
3912 /*-----------------------------------------------------------------*/
3916 lpItem = getSet(&lvaluereqSet);
3917 if(lpItem) Safe_free(lpItem);
3919 /*-----------------------------------------------------------------*/
3920 /* clearLvaluereq - clear lvalreq flag */
3921 /*-----------------------------------------------------------------*/
3922 void clearLvaluereq()
3925 lpItem = peekSet(lvaluereqSet);
3926 if(lpItem) lpItem->req = 0;
3928 /*-----------------------------------------------------------------*/
3929 /* getLvaluereq - get the last lvalreq level */
3930 /*-----------------------------------------------------------------*/
3931 int getLvaluereqLvl()
3934 lpItem = peekSet(lvaluereqSet);
3935 if(lpItem) return lpItem->lvl;
3938 /*-----------------------------------------------------------------*/
3939 /* isLvaluereq - is lvalreq valid for this level ? */
3940 /*-----------------------------------------------------------------*/
3941 int isLvaluereq(int lvl)
3944 lpItem = peekSet(lvaluereqSet);
3945 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3949 /*-----------------------------------------------------------------*/
3950 /* ast2iCode - creates an icodeList from an ast */
3951 /*-----------------------------------------------------------------*/
3953 ast2iCode (ast * tree,int lvl)
3955 operand *left = NULL;
3956 operand *right = NULL;
3960 /* set the global variables for filename & line number */
3962 filename = tree->filename;
3964 lineno = tree->lineno;
3966 block = tree->block;
3968 scopeLevel = tree->level;
3970 seqPoint = tree->seqPoint;
3972 if (tree->type == EX_VALUE)
3973 return operandFromValue (tree->opval.val);
3975 if (tree->type == EX_LINK)
3976 return operandFromLink (tree->opval.lnk);
3978 /* if we find a nullop */
3979 if (tree->type == EX_OP &&
3980 (tree->opval.op == NULLOP ||
3981 tree->opval.op == BLOCK))
3983 if (tree->left && tree->left->type == EX_VALUE)
3984 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3986 ast2iCode (tree->left,lvl+1);
3987 if (tree->right && tree->right->type == EX_VALUE)
3988 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3990 ast2iCode (tree->right,lvl+1);
3994 /* special cases for not evaluating */
3995 if (tree->opval.op != ':' &&
3996 tree->opval.op != '?' &&
3997 tree->opval.op != CALL &&
3998 tree->opval.op != IFX &&
3999 tree->opval.op != AND_OP &&
4000 tree->opval.op != OR_OP &&
4001 tree->opval.op != LABEL &&
4002 tree->opval.op != GOTO &&
4003 tree->opval.op != SWITCH &&
4004 tree->opval.op != FUNCTION &&
4005 tree->opval.op != INLINEASM &&
4006 tree->opval.op != CRITICAL)
4009 if (IS_ASSIGN_OP (tree->opval.op) ||
4010 IS_DEREF_OP (tree) ||
4011 (tree->opval.op == '&' && !tree->right) ||
4012 tree->opval.op == PTR_OP)
4015 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4016 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4019 left = operandFromAst (tree->left,lvl);
4021 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4022 left = geniCodeRValue (left, TRUE);
4026 left = operandFromAst (tree->left,lvl);
4028 if (tree->opval.op == INC_OP ||
4029 tree->opval.op == DEC_OP)
4032 right = operandFromAst (tree->right,lvl);
4037 right = operandFromAst (tree->right,lvl);
4041 /* now depending on the type of operand */
4042 /* this will be a biggy */
4043 switch (tree->opval.op)
4046 case '[': /* array operation */
4048 //sym_link *ltype = operandType (left);
4049 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4050 left = geniCodeRValue (left, FALSE);
4051 right = geniCodeRValue (right, TRUE);
4054 return geniCodeArray (left, right,lvl);
4056 case '.': /* structure dereference */
4057 if (IS_PTR (operandType (left)))
4058 left = geniCodeRValue (left, TRUE);
4060 left = geniCodeRValue (left, FALSE);
4062 return geniCodeStruct (left, right, tree->lvalue);
4064 case PTR_OP: /* structure pointer dereference */
4067 pType = operandType (left);
4068 left = geniCodeRValue (left, TRUE);
4070 setOClass (pType, getSpec (operandType (left)));
4073 return geniCodeStruct (left, right, tree->lvalue);
4075 case INC_OP: /* increment operator */
4077 return geniCodePostInc (left);
4079 return geniCodePreInc (right, tree->lvalue);
4081 case DEC_OP: /* decrement operator */
4083 return geniCodePostDec (left);
4085 return geniCodePreDec (right, tree->lvalue);
4087 case '&': /* bitwise and or address of operator */
4089 { /* this is a bitwise operator */
4090 left = geniCodeRValue (left, FALSE);
4091 right = geniCodeRValue (right, FALSE);
4092 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4095 return geniCodeAddressOf (left);
4097 case '|': /* bitwise or & xor */
4099 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4100 geniCodeRValue (right, FALSE),
4105 return geniCodeDivision (geniCodeRValue (left, FALSE),
4106 geniCodeRValue (right, FALSE),
4107 getResultTypeFromType (tree->ftype));
4110 return geniCodeModulus (geniCodeRValue (left, FALSE),
4111 geniCodeRValue (right, FALSE),
4112 getResultTypeFromType (tree->ftype));
4115 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4116 geniCodeRValue (right, FALSE),
4117 getResultTypeFromType (tree->ftype));
4119 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4123 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4124 geniCodeRValue (right, FALSE),
4125 getResultTypeFromType (tree->ftype));
4127 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4131 return geniCodeAdd (geniCodeRValue (left, FALSE),
4132 geniCodeRValue (right, FALSE),
4133 getResultTypeFromType (tree->ftype),
4136 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4139 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4140 geniCodeRValue (right, FALSE),
4141 getResultTypeFromType (tree->ftype));
4144 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4145 geniCodeRValue (right, FALSE));
4147 #if 0 // this indeed needs a second thought
4151 // let's keep this simple: get the rvalue we need
4152 op=geniCodeRValue (right, FALSE);
4153 // now cast it to whatever we want
4154 op=geniCodeCast (operandType(left), op, FALSE);
4155 // if this is going to be used as an lvalue, make it so
4161 #else // bug #604575, is it a bug ????
4162 return geniCodeCast (operandType (left),
4163 geniCodeRValue (right, FALSE), FALSE);
4170 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4175 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4176 setOperandType (op, UCHARTYPE);
4181 return geniCodeLogicAndOr (tree, lvl);
4188 /* different compilers (even different gccs) evaluate
4189 the two calls in a different order. to get the same
4190 result on all machines we've to specify a clear sequence.
4191 return geniCodeLogic (geniCodeRValue (left, FALSE),
4192 geniCodeRValue (right, FALSE),
4196 operand *leftOp, *rightOp;
4198 leftOp = geniCodeRValue (left , FALSE);
4199 rightOp = geniCodeRValue (right, FALSE);
4201 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4204 return geniCodeConditional (tree,lvl);
4207 return operandFromLit (getSize (tree->right->ftype));
4211 sym_link *rtype = operandType (right);
4212 sym_link *ltype = operandType (left);
4213 if (IS_PTR (rtype) && IS_ITEMP (right)
4214 && right->isaddr && compareType (rtype->next, ltype) == 1)
4215 right = geniCodeRValue (right, TRUE);
4217 right = geniCodeRValue (right, FALSE);
4219 geniCodeAssign (left, right, 0, 1);
4224 geniCodeAssign (left,
4225 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4227 geniCodeRValue (right, FALSE),
4228 getResultTypeFromType (tree->ftype)),
4233 geniCodeAssign (left,
4234 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4236 geniCodeRValue (right, FALSE),
4237 getResultTypeFromType (tree->ftype)),
4241 geniCodeAssign (left,
4242 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4244 geniCodeRValue (right, FALSE),
4245 getResultTypeFromType (tree->ftype)),
4249 sym_link *rtype = operandType (right);
4250 sym_link *ltype = operandType (left);
4251 if (IS_PTR (rtype) && IS_ITEMP (right)
4252 && right->isaddr && compareType (rtype->next, ltype) == 1)
4253 right = geniCodeRValue (right, TRUE);
4255 right = geniCodeRValue (right, FALSE);
4258 return geniCodeAssign (left,
4259 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4262 getResultTypeFromType (tree->ftype),
4268 sym_link *rtype = operandType (right);
4269 sym_link *ltype = operandType (left);
4270 if (IS_PTR (rtype) && IS_ITEMP (right)
4271 && right->isaddr && compareType (rtype->next, ltype) == 1)
4273 right = geniCodeRValue (right, TRUE);
4277 right = geniCodeRValue (right, FALSE);
4280 geniCodeAssign (left,
4281 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4284 getResultTypeFromType (tree->ftype)),
4289 geniCodeAssign (left,
4290 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4292 geniCodeRValue (right, FALSE),
4293 getResultTypeFromType (tree->ftype)),
4297 geniCodeAssign (left,
4298 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4300 geniCodeRValue (right, FALSE)), 0, 1);
4303 geniCodeAssign (left,
4304 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4306 geniCodeRValue (right, FALSE),
4308 operandType (left)), 0, 1);
4311 geniCodeAssign (left,
4312 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4314 geniCodeRValue (right, FALSE),
4316 operandType (left)), 0, 1);
4319 geniCodeAssign (left,
4320 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4322 geniCodeRValue (right, FALSE),
4324 operandType (left)), 0, 1);
4326 return geniCodeRValue (right, FALSE);
4329 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4332 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4333 return ast2iCode (tree->right,lvl+1);
4336 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4337 return ast2iCode (tree->right,lvl+1);
4340 geniCodeFunctionBody (tree,lvl);
4344 geniCodeReturn (right);
4348 geniCodeIfx (tree,lvl);
4352 geniCodeSwitch (tree,lvl);
4356 geniCodeInline (tree);
4360 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4364 geniCodeCritical (tree, lvl);
4370 /*-----------------------------------------------------------------*/
4371 /* reverseICChain - gets from the list and creates a linkedlist */
4372 /*-----------------------------------------------------------------*/
4379 while ((loop = getSet (&iCodeChain)))
4391 /*-----------------------------------------------------------------*/
4392 /* iCodeFromAst - given an ast will convert it to iCode */
4393 /*-----------------------------------------------------------------*/
4395 iCodeFromAst (ast * tree)
4397 returnLabel = newiTempLabel ("_return");
4398 entryLabel = newiTempLabel ("_entry");
4400 return reverseiCChain ();
4403 static const char *opTypeToStr(OPTYPE op)
4407 case SYMBOL: return "symbol";
4408 case VALUE: return "value";
4409 case TYPE: return "type";
4411 return "undefined type";
4415 operand *validateOpType(operand *op,
4422 if (op && op->type == type)
4427 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4428 " expected %s, got %s\n",
4429 macro, args, file, line,
4430 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4432 return op; // never reached, makes compiler happy.