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;
42 symbol *returnLabel; /* function return label */
43 symbol *entryLabel; /* function entry label */
45 /*-----------------------------------------------------------------*/
46 /* forward definition of some functions */
47 operand *geniCodeDivision (operand *, operand *);
48 operand *geniCodeAssign (operand *, operand *, int);
49 operand *geniCodeArray (operand *, operand *,int);
50 operand *geniCodeArray2Ptr (operand *);
51 operand *geniCodeRValue (operand *, bool);
52 operand *geniCodeDerefPtr (operand *,int);
53 int isLvaluereq(int lvl);
55 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
56 /* forward definition of ic print functions */
57 PRINTFUNC (picGetValueAtAddr);
58 PRINTFUNC (picSetValueAtAddr);
59 PRINTFUNC (picAddrOf);
60 PRINTFUNC (picGeneric);
61 PRINTFUNC (picGenericOne);
63 PRINTFUNC (picAssign);
67 PRINTFUNC (picJumpTable);
68 PRINTFUNC (picInline);
69 PRINTFUNC (picReceive);
71 iCodeTable codeTable[] =
73 {'!', "not", picGenericOne, NULL},
74 {'~', "~", picGenericOne, NULL},
75 {RRC, "rrc", picGenericOne, NULL},
76 {RLC, "rlc", picGenericOne, NULL},
77 {GETHBIT, "ghbit", picGenericOne, NULL},
78 {UNARYMINUS, "-", picGenericOne, NULL},
79 {IPUSH, "push", picGenericOne, NULL},
80 {IPOP, "pop", picGenericOne, NULL},
81 {CALL, "call", picGenericOne, NULL},
82 {PCALL, "pcall", picGenericOne, NULL},
83 {FUNCTION, "proc", picGenericOne, NULL},
84 {ENDFUNCTION, "eproc", picGenericOne, NULL},
85 {RETURN, "ret", picGenericOne, NULL},
86 {'+', "+", picGeneric, NULL},
87 {'-', "-", picGeneric, NULL},
88 {'*', "*", picGeneric, NULL},
89 {'/', "/", picGeneric, NULL},
90 {'%', "%", picGeneric, NULL},
91 {'>', ">", picGeneric, NULL},
92 {'<', "<", picGeneric, NULL},
93 {LE_OP, "<=", picGeneric, NULL},
94 {GE_OP, ">=", picGeneric, NULL},
95 {EQ_OP, "==", picGeneric, NULL},
96 {NE_OP, "!=", picGeneric, NULL},
97 {AND_OP, "&&", picGeneric, NULL},
98 {OR_OP, "||", picGeneric, NULL},
99 {'^', "^", picGeneric, NULL},
100 {'|', "|", picGeneric, NULL},
101 {BITWISEAND, "&", picGeneric, NULL},
102 {LEFT_OP, "<<", picGeneric, NULL},
103 {RIGHT_OP, ">>", picGeneric, NULL},
104 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
105 {ADDRESS_OF, "&", picAddrOf, NULL},
106 {CAST, "<>", picCast, NULL},
107 {'=', ":=", picAssign, NULL},
108 {LABEL, "", picLabel, NULL},
109 {GOTO, "", picGoto, NULL},
110 {JUMPTABLE, "jtab", picJumpTable, NULL},
111 {IFX, "if", picIfx, NULL},
112 {INLINEASM, "", picInline, NULL},
113 {RECEIVE, "recv", picReceive, NULL},
114 {SEND, "send", picGenericOne, NULL},
115 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
118 /*-----------------------------------------------------------------*/
119 /* checkConstantRange: check a constant against the type */
120 /*-----------------------------------------------------------------*/
122 /* pedantic=0: allmost anything is allowed as long as the absolute
123 value is within the bit range of the type, and -1 is treated as
124 0xf..f for unsigned types (e.g. in assign)
125 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
126 pedantic>1: "char c=200" is not allowed (evaluates to -56)
129 void checkConstantRange(sym_link *ltype, value *val, char *msg, int pedantic) {
131 char message[132]="";
136 max = pow ((double)2.0, (double)bitsForType(ltype));
138 if (SPEC_LONG(val->type)) {
139 if (SPEC_USIGN(val->type)) {
140 v=SPEC_CVAL(val->type).v_ulong;
142 v=SPEC_CVAL(val->type).v_long;
145 if (SPEC_USIGN(val->type)) {
146 v=SPEC_CVAL(val->type).v_uint;
148 v=SPEC_CVAL(val->type).v_int;
154 // this could be a good idea
155 if (options.pedantic)
159 if (SPEC_NOUN(ltype)==FLOAT) {
164 if (!SPEC_USIGN(val->type) && v<0) {
166 if (SPEC_USIGN(ltype) && (pedantic>1)) {
172 // if very pedantic: "char c=200" is not allowed
173 if (pedantic>1 && !SPEC_USIGN(ltype)) {
174 max = max/2 + negative;
182 sprintf (message, "for %s %s in %s",
183 SPEC_USIGN(ltype) ? "unsigned" : "signed",
184 nounName(ltype), msg);
185 werror (W_CONST_RANGE, message);
192 /*-----------------------------------------------------------------*/
193 /* operandName - returns the name of the operand */
194 /*-----------------------------------------------------------------*/
196 printOperand (operand * op, FILE * file)
213 opetype = getSpec (operandType (op));
214 if (SPEC_NOUN (opetype) == V_FLOAT)
215 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
217 fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
218 printTypeChain (operandType (op), file);
225 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d ru%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
226 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
228 OP_LIVEFROM (op), OP_LIVETO (op),
229 OP_SYMBOL (op)->stack,
230 op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
231 OP_SYMBOL(op)->ruonly
235 printTypeChain (operandType (op), file);
236 if (SPIL_LOC (op) && IS_ITEMP (op))
237 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
242 /* if assigned to registers */
243 if (OP_SYMBOL (op)->nRegs)
245 if (OP_SYMBOL (op)->isspilt)
247 if (!OP_SYMBOL (op)->remat)
248 if (OP_SYMBOL (op)->usl.spillLoc)
249 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
250 OP_SYMBOL (op)->usl.spillLoc->rname :
251 OP_SYMBOL (op)->usl.spillLoc->name));
253 fprintf (file, "[err]");
255 fprintf (file, "[remat]");
261 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
262 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
267 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
268 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
269 /* if assigned to registers */
270 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
274 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
275 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
276 OP_SYMBOL (op)->regs[i]->name :
285 printTypeChain (op->operand.typeOperand, file);
291 fprintf (file, "\n");
296 /*-----------------------------------------------------------------*/
297 /* print functions */
298 /*-----------------------------------------------------------------*/
299 PRINTFUNC (picGetValueAtAddr)
302 printOperand (IC_RESULT (ic), of);
305 printOperand (IC_LEFT (ic), of);
311 PRINTFUNC (picSetValueAtAddr)
315 printOperand (IC_LEFT (ic), of);
316 fprintf (of, "] = ");
317 printOperand (IC_RIGHT (ic), of);
321 PRINTFUNC (picAddrOf)
324 printOperand (IC_RESULT (ic), of);
325 if (IS_ITEMP (IC_LEFT (ic)))
328 fprintf (of, " = &[");
329 printOperand (IC_LEFT (ic), of);
332 if (IS_ITEMP (IC_LEFT (ic)))
333 fprintf (of, " offsetAdd ");
336 printOperand (IC_RIGHT (ic), of);
338 if (IS_ITEMP (IC_LEFT (ic)))
344 PRINTFUNC (picJumpTable)
349 fprintf (of, "%s\t", s);
350 printOperand (IC_JTCOND (ic), of);
352 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
353 sym = setNextItem (IC_JTLABELS (ic)))
354 fprintf (of, "\t\t\t%s\n", sym->name);
357 PRINTFUNC (picGeneric)
360 printOperand (IC_RESULT (ic), of);
362 printOperand (IC_LEFT (ic), of);
363 fprintf (of, " %s ", s);
364 printOperand (IC_RIGHT (ic), of);
368 PRINTFUNC (picGenericOne)
373 printOperand (IC_RESULT (ic), of);
379 fprintf (of, "%s ", s);
380 printOperand (IC_LEFT (ic), of);
383 if (!IC_RESULT (ic) && !IC_LEFT (ic))
392 printOperand (IC_RESULT (ic), of);
394 printOperand (IC_LEFT (ic), of);
395 printOperand (IC_RIGHT (ic), of);
400 PRINTFUNC (picAssign)
404 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
407 printOperand (IC_RESULT (ic), of);
409 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
412 fprintf (of, " %s ", s);
413 printOperand (IC_RIGHT (ic), of);
420 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
426 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
433 printOperand (IC_COND (ic), of);
436 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
439 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
441 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
445 PRINTFUNC (picInline)
447 fprintf (of, "%s", IC_INLINE (ic));
450 PRINTFUNC (picReceive)
452 printOperand (IC_RESULT (ic), of);
453 fprintf (of, " = %s ", s);
454 printOperand (IC_LEFT (ic), of);
458 /*-----------------------------------------------------------------*/
459 /* piCode - prints one iCode */
460 /*-----------------------------------------------------------------*/
462 piCode (void *item, FILE * of)
470 icTab = getTableEntry (ic->op);
471 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
472 ic->filename, ic->lineno,
473 ic->seq, ic->key, ic->depth, ic->supportRtn);
474 icTab->iCodePrint (of, ic, icTab->printName);
480 printiCChain(ic,stdout);
482 /*-----------------------------------------------------------------*/
483 /* printiCChain - prints intermediate code for humans */
484 /*-----------------------------------------------------------------*/
486 printiCChain (iCode * icChain, FILE * of)
493 for (loop = icChain; loop; loop = loop->next)
495 if ((icTab = getTableEntry (loop->op)))
497 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
498 loop->filename, loop->lineno,
499 loop->seq, loop->key, loop->depth, loop->supportRtn);
501 icTab->iCodePrint (of, loop, icTab->printName);
507 /*-----------------------------------------------------------------*/
508 /* newOperand - allocate, init & return a new iCode */
509 /*-----------------------------------------------------------------*/
515 op = Safe_alloc ( sizeof (operand));
521 /*-----------------------------------------------------------------*/
522 /* newiCode - create and return a new iCode entry initialised */
523 /*-----------------------------------------------------------------*/
525 newiCode (int op, operand * left, operand * right)
529 ic = Safe_alloc ( sizeof (iCode));
532 ic->filename = filename;
534 ic->level = scopeLevel;
536 ic->key = iCodeKey++;
538 IC_RIGHT (ic) = right;
543 /*-----------------------------------------------------------------*/
544 /* newiCode for conditional statements */
545 /*-----------------------------------------------------------------*/
547 newiCodeCondition (operand * condition,
553 if (IS_VOID(operandType(condition))) {
554 werror(E_VOID_VALUE_USED);
557 ic = newiCode (IFX, NULL, NULL);
558 IC_COND (ic) = condition;
559 IC_TRUE (ic) = trueLabel;
560 IC_FALSE (ic) = falseLabel;
564 /*-----------------------------------------------------------------*/
565 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
566 /*-----------------------------------------------------------------*/
568 newiCodeLabelGoto (int op, symbol * label)
572 ic = newiCode (op, NULL, NULL);
574 ic->argLabel.label = label;
576 IC_RIGHT (ic) = NULL;
577 IC_RESULT (ic) = NULL;
581 /*-----------------------------------------------------------------*/
582 /* newiTemp - allocate & return a newItemp Variable */
583 /*-----------------------------------------------------------------*/
590 sprintf (buffer, "%s", s);
592 sprintf (buffer, "iTemp%d", iTempNum++);
593 itmp = newSymbol (buffer, 1);
594 strcpy (itmp->rname, itmp->name);
600 /*-----------------------------------------------------------------*/
601 /* newiTempLabel - creates a temp variable label */
602 /*-----------------------------------------------------------------*/
604 newiTempLabel (char *s)
608 /* check if this alredy exists */
609 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
613 itmplbl = newSymbol (s, 1);
616 sprintf (buffer, "iTempLbl%d", iTempLblNum++);
617 itmplbl = newSymbol (buffer, 1);
622 itmplbl->key = labelKey++;
623 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
627 /*-----------------------------------------------------------------*/
628 /* newiTempPreheaderLabel - creates a new preheader label */
629 /*-----------------------------------------------------------------*/
631 newiTempPreheaderLabel ()
635 sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
636 itmplbl = newSymbol (buffer, 1);
640 itmplbl->key = labelKey++;
641 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
646 /*-----------------------------------------------------------------*/
647 /* initiCode - initialises some iCode related stuff */
648 /*-----------------------------------------------------------------*/
655 /*-----------------------------------------------------------------*/
656 /* copyiCode - make a copy of the iCode given */
657 /*-----------------------------------------------------------------*/
659 copyiCode (iCode * ic)
661 iCode *nic = newiCode (ic->op, NULL, NULL);
663 nic->lineno = ic->lineno;
664 nic->filename = ic->filename;
665 nic->block = ic->block;
666 nic->level = ic->level;
667 nic->parmBytes = ic->parmBytes;
669 /* deal with the special cases first */
673 IC_COND (nic) = operandFromOperand (IC_COND (ic));
674 IC_TRUE (nic) = IC_TRUE (ic);
675 IC_FALSE (nic) = IC_FALSE (ic);
679 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
680 IC_JTLABELS (nic) = IC_JTLABELS (ic);
685 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
686 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
690 IC_INLINE (nic) = IC_INLINE (ic);
694 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
698 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
699 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
700 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
706 /*-----------------------------------------------------------------*/
707 /* getTableEntry - gets the table entry for the given operator */
708 /*-----------------------------------------------------------------*/
710 getTableEntry (int oper)
714 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
715 if (oper == codeTable[i].icode)
716 return &codeTable[i];
721 /*-----------------------------------------------------------------*/
722 /* newiTempOperand - new intermediate temp operand */
723 /*-----------------------------------------------------------------*/
725 newiTempOperand (sym_link * type, char throwType)
728 operand *op = newOperand ();
732 itmp = newiTemp (NULL);
734 etype = getSpec (type);
736 if (IS_LITERAL (etype))
739 /* copy the type information */
741 itmp->etype = getSpec (itmp->type = (throwType ? type :
742 copyLinkChain (type)));
743 if (IS_LITERAL (itmp->etype))
745 SPEC_SCLS (itmp->etype) = S_REGISTER;
746 SPEC_OCLS (itmp->etype) = reg;
749 op->operand.symOperand = itmp;
750 op->key = itmp->key = ++operandKey;
754 /*-----------------------------------------------------------------*/
755 /* operandType - returns the type chain for an operand */
756 /*-----------------------------------------------------------------*/
758 operandType (operand * op)
760 /* depending on type of operand */
765 return op->operand.valOperand->type;
768 return op->operand.symOperand->type;
771 return op->operand.typeOperand;
773 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
774 " operand type not known ");
775 assert (0); /* should never come here */
776 /* Just to keep the compiler happy */
777 return (sym_link *) 0;
781 /*-----------------------------------------------------------------*/
782 /* isParamterToCall - will return 1 if op is a parameter to args */
783 /*-----------------------------------------------------------------*/
785 isParameterToCall (value * args, operand * op)
792 isSymbolEqual (op->operand.symOperand, tval->sym))
799 /*-----------------------------------------------------------------*/
800 /* isOperandGlobal - return 1 if operand is a global variable */
801 /*-----------------------------------------------------------------*/
803 isOperandGlobal (operand * op)
811 if (op->type == SYMBOL &&
812 (op->operand.symOperand->level == 0 ||
813 IS_STATIC (op->operand.symOperand->etype) ||
814 IS_EXTERN (op->operand.symOperand->etype))
821 /*-----------------------------------------------------------------*/
822 /* isOperandVolatile - return 1 if the operand is volatile */
823 /*-----------------------------------------------------------------*/
825 isOperandVolatile (operand * op, bool chkTemp)
830 if (IS_ITEMP (op) && !chkTemp)
833 opetype = getSpec (optype = operandType (op));
835 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
838 if (IS_VOLATILE (opetype))
843 /*-----------------------------------------------------------------*/
844 /* isOperandLiteral - returns 1 if an operand contains a literal */
845 /*-----------------------------------------------------------------*/
847 isOperandLiteral (operand * op)
854 opetype = getSpec (operandType (op));
856 if (IS_LITERAL (opetype))
862 /*-----------------------------------------------------------------*/
863 /* isOperandInFarSpace - will return true if operand is in farSpace */
864 /*-----------------------------------------------------------------*/
866 isOperandInFarSpace (operand * op)
876 if (!IS_TRUE_SYMOP (op))
879 etype = SPIL_LOC (op)->etype;
885 etype = getSpec (operandType (op));
887 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
890 /*------------------------------------------------------------------*/
891 /* isOperandInDirSpace - will return true if operand is in dirSpace */
892 /*------------------------------------------------------------------*/
894 isOperandInDirSpace (operand * op)
904 if (!IS_TRUE_SYMOP (op))
907 etype = SPIL_LOC (op)->etype;
913 etype = getSpec (operandType (op));
915 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
918 /*-----------------------------------------------------------------*/
919 /* isOperandOnStack - will return true if operand is on stack */
920 /*-----------------------------------------------------------------*/
923 isOperandOnStack (operand * op)
933 etype = getSpec (operandType (op));
935 return ((IN_STACK (etype)) ? TRUE : FALSE);
939 isOperandOnStack (operand * op)
949 etype = getSpec (operandType (op));
950 if (IN_STACK (etype) ||
951 OP_SYMBOL(op)->onStack ||
952 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
959 /*-----------------------------------------------------------------*/
960 /* operandLitValue - literal value of an operand */
961 /*-----------------------------------------------------------------*/
963 operandLitValue (operand * op)
965 assert (isOperandLiteral (op));
967 return floatFromVal (op->operand.valOperand);
970 /*-----------------------------------------------------------------*/
971 /* getBuiltInParms - returns parameters to a builtin functions */
972 /*-----------------------------------------------------------------*/
973 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
978 /* builtin functions uses only SEND for parameters */
979 while (ic->op != CALL) {
980 assert(ic->op == SEND && ic->builtinSEND);
981 ic->generated = 1; /* mark the icode as generated */
982 parms[*pcount] = IC_LEFT(ic);
988 /* make sure this is a builtin function call */
989 assert(IS_SYMOP(IC_LEFT(ic)));
990 ftype = operandType(IC_LEFT(ic));
991 assert(IFFUNC_ISBUILTIN(ftype));
995 /*-----------------------------------------------------------------*/
996 /* operandOperation - perforoms operations on operands */
997 /*-----------------------------------------------------------------*/
999 operandOperation (operand * left, operand * right,
1000 int op, sym_link * type)
1002 sym_link *let , *ret=NULL;
1003 operand *retval = (operand *) 0;
1005 assert (isOperandLiteral (left));
1006 let = getSpec(operandType(left));
1008 assert (isOperandLiteral (right));
1009 ret = getSpec(operandType(left));
1015 retval = operandFromValue (valCastLiteral (type,
1016 operandLitValue (left) +
1017 operandLitValue (right)));
1020 retval = operandFromValue (valCastLiteral (type,
1021 operandLitValue (left) -
1022 operandLitValue (right)));
1025 retval = operandFromValue (valCastLiteral (type,
1026 operandLitValue (left) *
1027 operandLitValue (right)));
1030 if ((unsigned long) operandLitValue (right) == 0)
1032 werror (E_DIVIDE_BY_ZERO);
1037 retval = operandFromValue (valCastLiteral (type,
1038 operandLitValue (left) /
1039 operandLitValue (right)));
1042 if ((unsigned long) operandLitValue (right) == 0) {
1043 werror (E_DIVIDE_BY_ZERO);
1047 retval = operandFromLit ((SPEC_USIGN(let) ?
1048 (unsigned long) operandLitValue (left) :
1049 (long) operandLitValue (left)) %
1051 (unsigned long) operandLitValue (right) :
1052 (long) operandLitValue (right)));
1056 retval = operandFromLit ((SPEC_USIGN(let) ?
1057 (unsigned long) operandLitValue (left) :
1058 (long) operandLitValue (left)) <<
1060 (unsigned long) operandLitValue (right) :
1061 (long) operandLitValue (right)));
1064 retval = operandFromLit ((SPEC_USIGN(let) ?
1065 (unsigned long) operandLitValue (left) :
1066 (long) operandLitValue (left)) >>
1068 (unsigned long) operandLitValue (right) :
1069 (long) operandLitValue (right)));
1072 retval = operandFromLit (operandLitValue (left) ==
1073 operandLitValue (right));
1076 retval = operandFromLit (operandLitValue (left) <
1077 operandLitValue (right));
1080 retval = operandFromLit (operandLitValue (left) <=
1081 operandLitValue (right));
1084 retval = operandFromLit (operandLitValue (left) !=
1085 operandLitValue (right));
1088 retval = operandFromLit (operandLitValue (left) >
1089 operandLitValue (right));
1092 retval = operandFromLit (operandLitValue (left) >=
1093 operandLitValue (right));
1096 retval = operandFromLit ((long)operandLitValue(left) &
1097 (long)operandLitValue(right));
1100 retval = operandFromLit ((long)operandLitValue (left) |
1101 (long)operandLitValue (right));
1104 retval = operandFromLit ((long)operandLitValue (left) ^
1105 (long)operandLitValue (right));
1108 retval = operandFromLit (operandLitValue (left) &&
1109 operandLitValue (right));
1112 retval = operandFromLit (operandLitValue (left) ||
1113 operandLitValue (right));
1117 long i = (long) operandLitValue (left);
1119 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1125 long i = (long) operandLitValue (left);
1127 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1133 retval = operandFromLit (-1 * operandLitValue (left));
1137 retval = operandFromLit (~((long) operandLitValue (left)));
1141 retval = operandFromLit (!operandLitValue (left));
1145 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1146 " operandOperation invalid operator ");
1154 /*-----------------------------------------------------------------*/
1155 /* isOperandEqual - compares two operand & return 1 if they r = */
1156 /*-----------------------------------------------------------------*/
1158 isOperandEqual (operand * left, operand * right)
1160 /* if the pointers are equal then they are equal */
1164 /* if either of them null then false */
1165 if (!left || !right)
1168 if (left->type != right->type)
1171 if (IS_SYMOP (left) && IS_SYMOP (right))
1172 return left->key == right->key;
1174 /* if types are the same */
1178 return isSymbolEqual (left->operand.symOperand,
1179 right->operand.symOperand);
1181 return (floatFromVal (left->operand.valOperand) ==
1182 floatFromVal (right->operand.valOperand));
1184 if (compareType (left->operand.typeOperand,
1185 right->operand.typeOperand) == 1)
1192 /*-------------------------------------------------------------------*/
1193 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1194 /*-------------------------------------------------------------------*/
1196 isiCodeEqual (iCode * left, iCode * right)
1198 /* if the same pointer */
1202 /* if either of them null */
1203 if (!left || !right)
1206 /* if operand are the same */
1207 if (left->op == right->op)
1210 /* compare all the elements depending on type */
1211 if (left->op != IFX)
1213 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1215 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1221 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1223 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1225 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1234 /*-----------------------------------------------------------------*/
1235 /* newiTempFromOp - create a temp Operand with same attributes */
1236 /*-----------------------------------------------------------------*/
1238 newiTempFromOp (operand * op)
1248 nop = newiTempOperand (operandType (op), TRUE);
1249 nop->isaddr = op->isaddr;
1250 nop->isvolatile = op->isvolatile;
1251 nop->isGlobal = op->isGlobal;
1252 nop->isLiteral = op->isLiteral;
1253 nop->usesDefs = op->usesDefs;
1254 nop->isParm = op->isParm;
1258 /*-----------------------------------------------------------------*/
1259 /* operand from operand - creates an operand holder for the type */
1260 /*-----------------------------------------------------------------*/
1262 operandFromOperand (operand * op)
1268 nop = newOperand ();
1269 nop->type = op->type;
1270 nop->isaddr = op->isaddr;
1272 nop->isvolatile = op->isvolatile;
1273 nop->isGlobal = op->isGlobal;
1274 nop->isLiteral = op->isLiteral;
1275 nop->usesDefs = op->usesDefs;
1276 nop->isParm = op->isParm;
1281 nop->operand.symOperand = op->operand.symOperand;
1284 nop->operand.valOperand = op->operand.valOperand;
1287 nop->operand.typeOperand = op->operand.typeOperand;
1294 /*-----------------------------------------------------------------*/
1295 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1296 /*-----------------------------------------------------------------*/
1298 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1300 operand *nop = operandFromOperand (op);
1302 if (nop->type == SYMBOL)
1304 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1305 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1311 /*-----------------------------------------------------------------*/
1312 /* operandFromSymbol - creates an operand from a symbol */
1313 /*-----------------------------------------------------------------*/
1315 operandFromSymbol (symbol * sym)
1320 /* if the symbol's type is a literal */
1321 /* then it is an enumerator type */
1322 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1323 return operandFromValue (valFromType (sym->etype));
1326 sym->key = ++operandKey;
1328 /* if this an implicit variable, means struct/union */
1329 /* member so just return it */
1330 if (sym->implicit || IS_FUNC (sym->type))
1334 op->operand.symOperand = sym;
1336 op->isvolatile = isOperandVolatile (op, TRUE);
1337 op->isGlobal = isOperandGlobal (op);
1341 /* under the following conditions create a
1342 register equivalent for a local symbol */
1343 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1344 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1345 (!(options.model == MODEL_FLAT24)) ) &&
1346 options.stackAuto == 0)
1349 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1350 !IS_FUNC (sym->type) && /* not a function */
1351 !sym->_isparm && /* not a parameter */
1352 sym->level && /* is a local variable */
1353 !sym->addrtaken && /* whose address has not been taken */
1354 !sym->reqv && /* does not already have a reg equivalence */
1355 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1356 !IS_STATIC (sym->etype) && /* and not declared static */
1357 !sym->islbl && /* not a label */
1358 ok && /* farspace check */
1359 !IS_BITVAR (sym->etype) /* not a bit variable */
1363 /* we will use it after all optimizations
1364 and before liveRange calculation */
1365 sym->reqv = newiTempOperand (sym->type, 0);
1366 sym->reqv->key = sym->key;
1367 OP_SYMBOL (sym->reqv)->key = sym->key;
1368 OP_SYMBOL (sym->reqv)->isreqv = 1;
1369 OP_SYMBOL (sym->reqv)->islocal = 1;
1370 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1371 SPIL_LOC (sym->reqv) = sym;
1374 if (!IS_AGGREGATE (sym->type))
1378 op->operand.symOperand = sym;
1381 op->isvolatile = isOperandVolatile (op, TRUE);
1382 op->isGlobal = isOperandGlobal (op);
1383 op->isPtr = IS_PTR (operandType (op));
1384 op->isParm = sym->_isparm;
1389 /* itemp = &[_symbol] */
1391 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1392 IC_LEFT (ic)->type = SYMBOL;
1393 IC_LEFT (ic)->operand.symOperand = sym;
1394 IC_LEFT (ic)->key = sym->key;
1395 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1396 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1397 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1400 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1401 if (IS_ARRAY (sym->type))
1403 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1404 IC_RESULT (ic)->isaddr = 0;
1407 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1411 return IC_RESULT (ic);
1414 /*-----------------------------------------------------------------*/
1415 /* operandFromValue - creates an operand from value */
1416 /*-----------------------------------------------------------------*/
1418 operandFromValue (value * val)
1422 /* if this is a symbol then do the symbol thing */
1424 return operandFromSymbol (val->sym);
1426 /* this is not a symbol */
1429 op->operand.valOperand = val;
1430 op->isLiteral = isOperandLiteral (op);
1434 /*-----------------------------------------------------------------*/
1435 /* operandFromLink - operand from typeChain */
1436 /*-----------------------------------------------------------------*/
1438 operandFromLink (sym_link * type)
1442 /* operand from sym_link */
1448 op->operand.typeOperand = copyLinkChain (type);
1452 /*-----------------------------------------------------------------*/
1453 /* operandFromLit - makes an operand from a literal value */
1454 /*-----------------------------------------------------------------*/
1456 operandFromLit (double i)
1458 return operandFromValue (valueFromLit (i));
1461 /*-----------------------------------------------------------------*/
1462 /* operandFromAst - creates an operand from an ast */
1463 /*-----------------------------------------------------------------*/
1465 operandFromAst (ast * tree,int lvl)
1471 /* depending on type do */
1475 return ast2iCode (tree,lvl+1);
1479 return operandFromValue (tree->opval.val);
1483 return operandFromLink (tree->opval.lnk);
1487 /* Just to keep the comiler happy */
1488 return (operand *) 0;
1491 /*-----------------------------------------------------------------*/
1492 /* setOperandType - sets the operand's type to the given type */
1493 /*-----------------------------------------------------------------*/
1495 setOperandType (operand * op, sym_link * type)
1497 /* depending on the type of operand */
1502 op->operand.valOperand->etype =
1503 getSpec (op->operand.valOperand->type =
1504 copyLinkChain (type));
1508 if (op->operand.symOperand->isitmp)
1509 op->operand.symOperand->etype =
1510 getSpec (op->operand.symOperand->type =
1511 copyLinkChain (type));
1513 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1514 "attempt to modify type of source");
1518 op->operand.typeOperand = copyLinkChain (type);
1523 /*-----------------------------------------------------------------*/
1524 /* Get size in byte of ptr need to access an array */
1525 /*-----------------------------------------------------------------*/
1527 getArraySizePtr (operand * op)
1529 sym_link *ltype = operandType(op);
1533 int size = getSize(ltype);
1534 return(IS_GENPTR(ltype)?(size-1):size);
1539 sym_link *letype = getSpec(ltype);
1540 switch (PTR_TYPE (SPEC_OCLS (letype)))
1552 return (GPTRSIZE-1);
1561 /*-----------------------------------------------------------------*/
1562 /* perform "usual unary conversions" */
1563 /*-----------------------------------------------------------------*/
1565 usualUnaryConversions (operand * op)
1567 if (IS_INTEGRAL (operandType (op)))
1569 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1572 return geniCodeCast (INTTYPE, op, TRUE);
1578 /*-----------------------------------------------------------------*/
1579 /* perform "usual binary conversions" */
1580 /*-----------------------------------------------------------------*/
1582 usualBinaryConversions (operand ** op1, operand ** op2)
1585 sym_link *rtype = operandType (*op2);
1586 sym_link *ltype = operandType (*op1);
1588 ctype = computeType (ltype, rtype);
1589 *op1 = geniCodeCast (ctype, *op1, TRUE);
1590 *op2 = geniCodeCast (ctype, *op2, TRUE);
1595 /*-----------------------------------------------------------------*/
1596 /* geniCodeValueAtAddress - generate intermeditate code for value */
1598 /*-----------------------------------------------------------------*/
1600 geniCodeRValue (operand * op, bool force)
1603 sym_link *type = operandType (op);
1604 sym_link *etype = getSpec (type);
1606 /* if this is an array & already */
1607 /* an address then return this */
1608 if (IS_AGGREGATE (type) ||
1609 (IS_PTR (type) && !force && !op->isaddr))
1610 return operandFromOperand (op);
1612 /* if this is not an address then must be */
1613 /* rvalue already so return this one */
1617 /* if this is not a temp symbol then */
1618 if (!IS_ITEMP (op) &&
1620 !IN_FARSPACE (SPEC_OCLS (etype)))
1622 op = operandFromOperand (op);
1627 if (IS_SPEC (type) &&
1628 IS_TRUE_SYMOP (op) &&
1629 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1630 /* TARGET_IS_DS390)) */
1631 (options.model == MODEL_FLAT24) ))
1633 op = operandFromOperand (op);
1638 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1639 if (IS_PTR (type) && op->isaddr && force)
1642 type = copyLinkChain (type);
1644 IC_RESULT (ic) = newiTempOperand (type, 1);
1645 IC_RESULT (ic)->isaddr = 0;
1647 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1651 return IC_RESULT (ic);
1654 /*-----------------------------------------------------------------*/
1655 /* geniCodeCast - changes the value from one type to another */
1656 /*-----------------------------------------------------------------*/
1658 geniCodeCast (sym_link * type, operand * op, bool implicit)
1662 sym_link *opetype = getSpec (optype = operandType (op));
1666 /* one of them has size zero then error */
1667 if (IS_VOID (optype))
1669 werror (E_CAST_ZERO);
1673 /* if the operand is already the desired type then do nothing */
1674 if (compareType (type, optype) == 1)
1677 /* if this is a literal then just change the type & return */
1678 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1679 return operandFromValue (valCastLiteral (type,
1680 operandLitValue (op)));
1682 /* if casting to/from pointers, do some checking */
1683 if (IS_PTR(type)) { // to a pointer
1684 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1685 if (IS_INTEGRAL(optype)) {
1686 // maybe this is NULL, than it's ok.
1687 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1688 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1689 // no way to set the storage
1690 if (IS_LITERAL(optype)) {
1691 werror(E_LITERAL_GENERIC);
1694 werror(E_NONPTR2_GENPTR);
1697 } else if (implicit) {
1698 werror(W_INTEGRAL2PTR_NOCAST);
1703 // shouldn't do that with float, array or structure unless to void
1704 if (!IS_VOID(getSpec(type)) &&
1705 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1706 werror(E_INCOMPAT_TYPES);
1710 } else { // from a pointer to a pointer
1711 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1712 // if not a pointer to a function
1713 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1714 if (implicit) { // if not to generic, they have to match
1715 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1716 werror(E_INCOMPAT_PTYPES);
1723 } else { // to a non pointer
1724 if (IS_PTR(optype)) { // from a pointer
1725 if (implicit) { // sneaky
1726 if (IS_INTEGRAL(type)) {
1727 werror(W_PTR2INTEGRAL_NOCAST);
1729 } else { // shouldn't do that with float, array or structure
1730 werror(E_INCOMPAT_TYPES);
1737 printFromToType (optype, type);
1740 /* if they are the same size create an assignment */
1741 if (getSize (type) == getSize (optype) &&
1742 !IS_BITFIELD (type) &&
1744 !IS_FLOAT (optype) &&
1745 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1746 (!IS_SPEC (type) && !IS_SPEC (optype))))
1749 ic = newiCode ('=', NULL, op);
1750 IC_RESULT (ic) = newiTempOperand (type, 0);
1751 SPIL_LOC (IC_RESULT (ic)) =
1752 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1753 IC_RESULT (ic)->isaddr = 0;
1757 ic = newiCode (CAST, operandFromLink (type),
1758 geniCodeRValue (op, FALSE));
1760 IC_RESULT (ic) = newiTempOperand (type, 0);
1763 /* preserve the storage class & output class */
1764 /* of the original variable */
1765 restype = getSpec (operandType (IC_RESULT (ic)));
1766 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1767 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1770 return IC_RESULT (ic);
1773 /*-----------------------------------------------------------------*/
1774 /* geniCodeLabel - will create a Label */
1775 /*-----------------------------------------------------------------*/
1777 geniCodeLabel (symbol * label)
1781 ic = newiCodeLabelGoto (LABEL, label);
1785 /*-----------------------------------------------------------------*/
1786 /* geniCodeGoto - will create a Goto */
1787 /*-----------------------------------------------------------------*/
1789 geniCodeGoto (symbol * label)
1793 ic = newiCodeLabelGoto (GOTO, label);
1797 /*-----------------------------------------------------------------*/
1798 /* geniCodeMultiply - gen intermediate code for multiplication */
1799 /*-----------------------------------------------------------------*/
1801 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1808 /* if they are both literal then we know the result */
1809 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1810 return operandFromValue (valMult (left->operand.valOperand,
1811 right->operand.valOperand));
1813 if (IS_LITERAL(retype)) {
1814 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1817 resType = usualBinaryConversions (&left, &right);
1819 rtype = operandType (right);
1820 retype = getSpec (rtype);
1821 ltype = operandType (left);
1822 letype = getSpec (ltype);
1826 SPEC_NOUN(getSpec(resType))=V_INT;
1829 /* if the right is a literal & power of 2 */
1830 /* then make it a left shift */
1831 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1832 efficient in most cases than 2 bytes result = 2 bytes << literal
1833 if port has 1 byte muldiv */
1834 if (p2 && !IS_FLOAT (letype) &&
1835 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1836 (port->support.muldiv == 1)))
1838 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1840 /* LEFT_OP need same size for left and result, */
1841 left = geniCodeCast (resType, left, TRUE);
1842 ltype = operandType (left);
1844 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1848 ic = newiCode ('*', left, right); /* normal multiplication */
1849 /* if the size left or right > 1 then support routine */
1850 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1854 IC_RESULT (ic) = newiTempOperand (resType, 1);
1857 return IC_RESULT (ic);
1860 /*-----------------------------------------------------------------*/
1861 /* geniCodeDivision - gen intermediate code for division */
1862 /*-----------------------------------------------------------------*/
1864 geniCodeDivision (operand * left, operand * right)
1869 sym_link *rtype = operandType (right);
1870 sym_link *retype = getSpec (rtype);
1871 sym_link *ltype = operandType (left);
1872 sym_link *letype = getSpec (ltype);
1874 resType = usualBinaryConversions (&left, &right);
1876 /* if the right is a literal & power of 2 */
1877 /* then make it a right shift */
1878 if (IS_LITERAL (retype) &&
1879 !IS_FLOAT (letype) &&
1880 (p2 = powof2 ((unsigned long)
1881 floatFromVal (right->operand.valOperand)))) {
1882 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1886 ic = newiCode ('/', left, right); /* normal division */
1887 /* if the size left or right > 1 then support routine */
1888 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1891 IC_RESULT (ic) = newiTempOperand (resType, 0);
1894 return IC_RESULT (ic);
1896 /*-----------------------------------------------------------------*/
1897 /* geniCodeModulus - gen intermediate code for modulus */
1898 /*-----------------------------------------------------------------*/
1900 geniCodeModulus (operand * left, operand * right)
1906 /* if they are both literal then we know the result */
1907 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1908 return operandFromValue (valMod (left->operand.valOperand,
1909 right->operand.valOperand));
1911 resType = usualBinaryConversions (&left, &right);
1913 /* now they are the same size */
1914 ic = newiCode ('%', left, right);
1916 /* if the size left or right > 1 then support routine */
1917 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1919 IC_RESULT (ic) = newiTempOperand (resType, 0);
1922 return IC_RESULT (ic);
1925 /*-----------------------------------------------------------------*/
1926 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1927 /*-----------------------------------------------------------------*/
1929 geniCodePtrPtrSubtract (operand * left, operand * right)
1935 /* if they are both literals then */
1936 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1938 result = operandFromValue (valMinus (left->operand.valOperand,
1939 right->operand.valOperand));
1943 ic = newiCode ('-', left, right);
1945 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1949 return geniCodeDivision (result,
1950 operandFromLit (getSize (ltype->next)));
1953 /*-----------------------------------------------------------------*/
1954 /* geniCodeSubtract - generates code for subtraction */
1955 /*-----------------------------------------------------------------*/
1957 geniCodeSubtract (operand * left, operand * right)
1964 /* if they both pointers then */
1965 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1966 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1967 return geniCodePtrPtrSubtract (left, right);
1969 /* if they are both literal then we know the result */
1970 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1971 && left->isLiteral && right->isLiteral)
1972 return operandFromValue (valMinus (left->operand.valOperand,
1973 right->operand.valOperand));
1975 /* if left is an array or pointer */
1976 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1978 isarray = left->isaddr;
1979 right = geniCodeMultiply (right,
1980 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1981 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1984 { /* make them the same size */
1985 resType = usualBinaryConversions (&left, &right);
1988 ic = newiCode ('-', left, right);
1990 IC_RESULT (ic) = newiTempOperand (resType, 1);
1991 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1993 /* if left or right is a float */
1994 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1998 return IC_RESULT (ic);
2001 /*-----------------------------------------------------------------*/
2002 /* geniCodeAdd - generates iCode for addition */
2003 /*-----------------------------------------------------------------*/
2005 geniCodeAdd (operand * left, operand * right,int lvl)
2013 /* if left is an array then array access */
2014 if (IS_ARRAY (ltype))
2015 return geniCodeArray (left, right,lvl);
2017 /* if the right side is LITERAL zero */
2018 /* return the left side */
2019 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
2022 /* if left is literal zero return right */
2023 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
2026 /* if left is an array or pointer then size */
2029 isarray = left->isaddr;
2030 // there is no need to multiply with 1
2031 if (getSize(ltype->next)!=1) {
2032 size = operandFromLit (getSize (ltype->next));
2033 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2035 resType = copyLinkChain (ltype);
2038 { /* make them the same size */
2039 resType = usualBinaryConversions (&left, &right);
2042 /* if they are both literals then we know */
2043 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2044 && left->isLiteral && right->isLiteral)
2045 return operandFromValue (valPlus (valFromType (letype),
2046 valFromType (retype)));
2048 ic = newiCode ('+', left, right);
2050 IC_RESULT (ic) = newiTempOperand (resType, 1);
2051 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2053 /* if left or right is a float then support
2055 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2060 return IC_RESULT (ic);
2064 /*-----------------------------------------------------------------*/
2065 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2066 /*-----------------------------------------------------------------*/
2068 aggrToPtr (sym_link * type, bool force)
2074 if (IS_PTR (type) && !force)
2077 etype = getSpec (type);
2081 /* if the output class is generic */
2082 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2083 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2085 /* if the variable was declared a constant */
2086 /* then the pointer points to a constant */
2087 if (IS_CONSTANT (etype))
2088 DCL_PTR_CONST (ptype) = 1;
2090 /* the variable was volatile then pointer to volatile */
2091 if (IS_VOLATILE (etype))
2092 DCL_PTR_VOLATILE (ptype) = 1;
2096 /*-----------------------------------------------------------------*/
2097 /* geniCodeArray2Ptr - array to pointer */
2098 /*-----------------------------------------------------------------*/
2100 geniCodeArray2Ptr (operand * op)
2102 sym_link *optype = operandType (op);
2103 sym_link *opetype = getSpec (optype);
2105 /* set the pointer depending on the storage class */
2106 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2107 DCL_PTR_CONST (optype) = port->mem.code_ro;
2110 /* if the variable was declared a constant */
2111 /* then the pointer points to a constant */
2112 if (IS_CONSTANT (opetype))
2113 DCL_PTR_CONST (optype) = 1;
2115 /* the variable was volatile then pointer to volatile */
2116 if (IS_VOLATILE (opetype))
2117 DCL_PTR_VOLATILE (optype) = 1;
2123 /*-----------------------------------------------------------------*/
2124 /* geniCodeArray - array access */
2125 /*-----------------------------------------------------------------*/
2127 geniCodeArray (operand * left, operand * right,int lvl)
2130 sym_link *ltype = operandType (left);
2134 if (IS_PTR (ltype->next) && left->isaddr)
2136 left = geniCodeRValue (left, FALSE);
2138 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
2141 right = geniCodeMultiply (right,
2142 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2144 /* we can check for limits here */
2145 if (isOperandLiteral (right) &&
2148 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2150 werror (E_ARRAY_BOUND);
2151 right = operandFromLit (0);
2154 ic = newiCode ('+', left, right);
2156 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2157 !IS_AGGREGATE (ltype->next) &&
2158 !IS_PTR (ltype->next))
2159 ? ltype : ltype->next), 0);
2161 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2163 return IC_RESULT (ic);
2166 /*-----------------------------------------------------------------*/
2167 /* geniCodeStruct - generates intermediate code for structres */
2168 /*-----------------------------------------------------------------*/
2170 geniCodeStruct (operand * left, operand * right, bool islval)
2173 sym_link *type = operandType (left);
2174 sym_link *etype = getSpec (type);
2176 symbol *element = getStructElement (SPEC_STRUCT (etype),
2177 right->operand.symOperand);
2179 /* add the offset */
2180 ic = newiCode ('+', left, operandFromLit (element->offset));
2182 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2184 /* preserve the storage & output class of the struct */
2185 /* as well as the volatile attribute */
2186 retype = getSpec (operandType (IC_RESULT (ic)));
2187 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2188 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2189 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2191 if (IS_PTR (element->type))
2192 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2194 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2198 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2201 /*-----------------------------------------------------------------*/
2202 /* geniCodePostInc - generate int code for Post increment */
2203 /*-----------------------------------------------------------------*/
2205 geniCodePostInc (operand * op)
2209 sym_link *optype = operandType (op);
2211 operand *rv = (IS_ITEMP (op) ?
2212 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2214 sym_link *rvtype = operandType (rv);
2217 /* if this is not an address we have trouble */
2220 werror (E_LVALUE_REQUIRED, "++");
2224 rOp = newiTempOperand (rvtype, 0);
2225 OP_SYMBOL(rOp)->noSpilLoc = 1;
2228 OP_SYMBOL(rv)->noSpilLoc = 1;
2230 geniCodeAssign (rOp, rv, 0);
2232 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2233 if (IS_FLOAT (rvtype))
2234 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2236 ic = newiCode ('+', rv, operandFromLit (size));
2238 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2241 geniCodeAssign (op, result, 0);
2247 /*-----------------------------------------------------------------*/
2248 /* geniCodePreInc - generate code for preIncrement */
2249 /*-----------------------------------------------------------------*/
2251 geniCodePreInc (operand * op)
2254 sym_link *optype = operandType (op);
2255 operand *rop = (IS_ITEMP (op) ?
2256 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2258 sym_link *roptype = operandType (rop);
2264 werror (E_LVALUE_REQUIRED, "++");
2269 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2270 if (IS_FLOAT (roptype))
2271 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2273 ic = newiCode ('+', rop, operandFromLit (size));
2274 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2278 return geniCodeAssign (op, result, 0);
2281 /*-----------------------------------------------------------------*/
2282 /* geniCodePostDec - generates code for Post decrement */
2283 /*-----------------------------------------------------------------*/
2285 geniCodePostDec (operand * op)
2289 sym_link *optype = operandType (op);
2291 operand *rv = (IS_ITEMP (op) ?
2292 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2294 sym_link *rvtype = operandType (rv);
2297 /* if this is not an address we have trouble */
2300 werror (E_LVALUE_REQUIRED, "--");
2304 rOp = newiTempOperand (rvtype, 0);
2305 OP_SYMBOL(rOp)->noSpilLoc = 1;
2308 OP_SYMBOL(rv)->noSpilLoc = 1;
2310 geniCodeAssign (rOp, rv, 0);
2312 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2313 if (IS_FLOAT (rvtype))
2314 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2316 ic = newiCode ('-', rv, operandFromLit (size));
2318 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2321 geniCodeAssign (op, result, 0);
2327 /*-----------------------------------------------------------------*/
2328 /* geniCodePreDec - generate code for pre decrement */
2329 /*-----------------------------------------------------------------*/
2331 geniCodePreDec (operand * op)
2334 sym_link *optype = operandType (op);
2335 operand *rop = (IS_ITEMP (op) ?
2336 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2338 sym_link *roptype = operandType (rop);
2344 werror (E_LVALUE_REQUIRED, "--");
2349 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2350 if (IS_FLOAT (roptype))
2351 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2353 ic = newiCode ('-', rop, operandFromLit (size));
2354 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2358 return geniCodeAssign (op, result, 0);
2362 /*-----------------------------------------------------------------*/
2363 /* geniCodeBitwise - gen int code for bitWise operators */
2364 /*-----------------------------------------------------------------*/
2366 geniCodeBitwise (operand * left, operand * right,
2367 int oper, sym_link * resType)
2371 left = geniCodeCast (resType, left, TRUE);
2372 right = geniCodeCast (resType, right, TRUE);
2374 ic = newiCode (oper, left, right);
2375 IC_RESULT (ic) = newiTempOperand (resType, 0);
2378 return IC_RESULT (ic);
2381 /*-----------------------------------------------------------------*/
2382 /* geniCodeAddressOf - gens icode for '&' address of operator */
2383 /*-----------------------------------------------------------------*/
2385 geniCodeAddressOf (operand * op)
2389 sym_link *optype = operandType (op);
2390 sym_link *opetype = getSpec (optype);
2392 /* lvalue check already done in decorateType */
2393 /* this must be a lvalue */
2394 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2395 /* werror (E_LVALUE_REQUIRED,"&"); */
2400 p->class = DECLARATOR;
2402 /* set the pointer depending on the storage class */
2403 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2404 DCL_PTR_CONST (p) = port->mem.code_ro;
2406 /* make sure we preserve the const & volatile */
2407 if (IS_CONSTANT (opetype))
2408 DCL_PTR_CONST (p) = 1;
2410 if (IS_VOLATILE (opetype))
2411 DCL_PTR_VOLATILE (p) = 1;
2413 p->next = copyLinkChain (optype);
2415 /* if already a temp */
2418 setOperandType (op, p);
2423 /* other wise make this of the type coming in */
2424 ic = newiCode (ADDRESS_OF, op, NULL);
2425 IC_RESULT (ic) = newiTempOperand (p, 1);
2426 IC_RESULT (ic)->isaddr = 0;
2428 return IC_RESULT (ic);
2430 /*-----------------------------------------------------------------*/
2431 /* setOClass - sets the output class depending on the pointer type */
2432 /*-----------------------------------------------------------------*/
2434 setOClass (sym_link * ptr, sym_link * spec)
2436 switch (DCL_TYPE (ptr))
2439 SPEC_OCLS (spec) = data;
2443 SPEC_OCLS (spec) = generic;
2447 SPEC_OCLS (spec) = xdata;
2451 SPEC_OCLS (spec) = code;
2455 SPEC_OCLS (spec) = idata;
2459 SPEC_OCLS (spec) = xstack;
2463 SPEC_OCLS (spec) = eeprom;
2472 /*-----------------------------------------------------------------*/
2473 /* geniCodeDerefPtr - dereference pointer with '*' */
2474 /*-----------------------------------------------------------------*/
2476 geniCodeDerefPtr (operand * op,int lvl)
2478 sym_link *rtype, *retype;
2479 sym_link *optype = operandType (op);
2481 /* if this is a pointer then generate the rvalue */
2482 if (IS_PTR (optype))
2484 if (IS_TRUE_SYMOP (op))
2487 op = geniCodeRValue (op, TRUE);
2490 op = geniCodeRValue (op, TRUE);
2493 /* now get rid of the pointer part */
2494 if (isLvaluereq(lvl) && IS_ITEMP (op))
2496 retype = getSpec (rtype = copyLinkChain (optype));
2500 retype = getSpec (rtype = copyLinkChain (optype->next));
2503 /* if this is a pointer then outputclass needs 2b updated */
2504 if (IS_PTR (optype))
2505 setOClass (optype, retype);
2507 op->isGptr = IS_GENPTR (optype);
2509 /* if the pointer was declared as a constant */
2510 /* then we cannot allow assignment to the derefed */
2511 if (IS_PTR_CONST (optype))
2512 SPEC_CONST (retype) = 1;
2514 op->isaddr = (IS_PTR (rtype) ||
2515 IS_STRUCT (rtype) ||
2520 if (!isLvaluereq(lvl))
2521 op = geniCodeRValue (op, TRUE);
2523 setOperandType (op, rtype);
2528 /*-----------------------------------------------------------------*/
2529 /* geniCodeUnaryMinus - does a unary minus of the operand */
2530 /*-----------------------------------------------------------------*/
2532 geniCodeUnaryMinus (operand * op)
2535 sym_link *optype = operandType (op);
2537 if (IS_LITERAL (optype))
2538 return operandFromLit (-floatFromVal (op->operand.valOperand));
2540 ic = newiCode (UNARYMINUS, op, NULL);
2541 IC_RESULT (ic) = newiTempOperand (optype, 0);
2543 return IC_RESULT (ic);
2546 /*-----------------------------------------------------------------*/
2547 /* geniCodeLeftShift - gen i code for left shift */
2548 /*-----------------------------------------------------------------*/
2550 geniCodeLeftShift (operand * left, operand * right)
2554 ic = newiCode (LEFT_OP, left, right);
2555 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2557 return IC_RESULT (ic);
2560 /*-----------------------------------------------------------------*/
2561 /* geniCodeRightShift - gen i code for right shift */
2562 /*-----------------------------------------------------------------*/
2564 geniCodeRightShift (operand * left, operand * right)
2568 ic = newiCode (RIGHT_OP, left, right);
2569 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2571 return IC_RESULT (ic);
2574 /*-----------------------------------------------------------------*/
2575 /* geniCodeLogic- logic code */
2576 /*-----------------------------------------------------------------*/
2578 geniCodeLogic (operand * left, operand * right, int op)
2582 sym_link *rtype = operandType (right);
2583 sym_link *ltype = operandType (left);
2585 /* left is integral type and right is literal then
2586 check if the literal value is within bounds */
2587 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2589 checkConstantRange(ltype,
2590 OP_VALUE(right), "compare operation", 1);
2593 ctype = usualBinaryConversions (&left, &right);
2595 ic = newiCode (op, left, right);
2596 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2598 /* if comparing float
2599 and not a '==' || '!=' || '&&' || '||' (these
2601 if (IS_FLOAT(ctype) &&
2609 return IC_RESULT (ic);
2612 /*-----------------------------------------------------------------*/
2613 /* geniCodeUnary - for a a generic unary operation */
2614 /*-----------------------------------------------------------------*/
2616 geniCodeUnary (operand * op, int oper)
2618 iCode *ic = newiCode (oper, op, NULL);
2620 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2622 return IC_RESULT (ic);
2625 /*-----------------------------------------------------------------*/
2626 /* geniCodeConditional - geniCode for '?' ':' operation */
2627 /*-----------------------------------------------------------------*/
2629 geniCodeConditional (ast * tree,int lvl)
2632 symbol *falseLabel = newiTempLabel (NULL);
2633 symbol *exitLabel = newiTempLabel (NULL);
2634 operand *cond = ast2iCode (tree->left,lvl+1);
2635 operand *true, *false, *result;
2637 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2641 true = ast2iCode (tree->right->left,lvl+1);
2643 /* move the value to a new Operand */
2644 result = newiTempOperand (tree->right->ftype, 0);
2645 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2647 /* generate an unconditional goto */
2648 geniCodeGoto (exitLabel);
2650 /* now for the right side */
2651 geniCodeLabel (falseLabel);
2653 false = ast2iCode (tree->right->right,lvl+1);
2654 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2656 /* create the exit label */
2657 geniCodeLabel (exitLabel);
2662 /*-----------------------------------------------------------------*/
2663 /* geniCodeAssign - generate code for assignment */
2664 /*-----------------------------------------------------------------*/
2666 geniCodeAssign (operand * left, operand * right, int nosupdate)
2669 sym_link *ltype = operandType (left);
2670 sym_link *rtype = operandType (right);
2672 if (!left->isaddr && !IS_ITEMP (left))
2674 werror (E_LVALUE_REQUIRED, "assignment");
2678 /* left is integral type and right is literal then
2679 check if the literal value is within bounds */
2680 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2682 checkConstantRange(ltype,
2683 OP_VALUE(right), "= operation", 0);
2686 /* if the left & right type don't exactly match */
2687 /* if pointer set then make sure the check is
2688 done with the type & not the pointer */
2689 /* then cast rights type to left */
2691 /* first check the type for pointer assignement */
2692 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2693 compareType (ltype, rtype) <= 0)
2695 if (compareType (ltype->next, rtype) < 0)
2696 right = geniCodeCast (ltype->next, right, TRUE);
2698 else if (compareType (ltype, rtype) < 0)
2699 right = geniCodeCast (ltype, right, TRUE);
2701 /* if left is a true symbol & ! volatile
2702 create an assignment to temporary for
2703 the right & then assign this temporary
2704 to the symbol this is SSA . isn't it simple
2705 and folks have published mountains of paper on it */
2706 if (IS_TRUE_SYMOP (left) &&
2707 !isOperandVolatile (left, FALSE) &&
2708 isOperandGlobal (left))
2712 if (IS_TRUE_SYMOP (right))
2713 sym = OP_SYMBOL (right);
2714 ic = newiCode ('=', NULL, right);
2715 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2716 SPIL_LOC (right) = sym;
2720 ic = newiCode ('=', NULL, right);
2721 IC_RESULT (ic) = left;
2724 /* if left isgptr flag is set then support
2725 routine will be required */
2729 ic->nosupdate = nosupdate;
2733 /*-----------------------------------------------------------------*/
2734 /* geniCodeSEParms - generate code for side effecting fcalls */
2735 /*-----------------------------------------------------------------*/
2737 geniCodeSEParms (ast * parms,int lvl)
2742 if (parms->type == EX_OP && parms->opval.op == PARAM)
2744 geniCodeSEParms (parms->left,lvl);
2745 geniCodeSEParms (parms->right,lvl);
2749 /* hack don't like this but too lazy to think of
2751 if (IS_ADDRESS_OF_OP (parms))
2752 parms->left->lvalue = 1;
2754 if (IS_CAST_OP (parms) &&
2755 IS_PTR (parms->ftype) &&
2756 IS_ADDRESS_OF_OP (parms->right))
2757 parms->right->left->lvalue = 1;
2759 parms->opval.oprnd =
2760 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2762 parms->type = EX_OPERAND;
2765 /*-----------------------------------------------------------------*/
2766 /* geniCodeParms - generates parameters */
2767 /*-----------------------------------------------------------------*/
2769 geniCodeParms (ast * parms, value *argVals, int *stack,
2770 sym_link * fetype, symbol * func,int lvl)
2778 if (argVals==NULL) {
2780 argVals=FUNC_ARGS(func->type);
2783 /* if this is a param node then do the left & right */
2784 if (parms->type == EX_OP && parms->opval.op == PARAM)
2786 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2787 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2791 /* get the parameter value */
2792 if (parms->type == EX_OPERAND)
2793 pval = parms->opval.oprnd;
2796 /* maybe this else should go away ?? */
2797 /* hack don't like this but too lazy to think of
2799 if (IS_ADDRESS_OF_OP (parms))
2800 parms->left->lvalue = 1;
2802 if (IS_CAST_OP (parms) &&
2803 IS_PTR (parms->ftype) &&
2804 IS_ADDRESS_OF_OP (parms->right))
2805 parms->right->left->lvalue = 1;
2807 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2810 /* if register parm then make it a send */
2811 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
2812 IFFUNC_ISBUILTIN(func->type))
2814 ic = newiCode (SEND, pval, NULL);
2815 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
2820 /* now decide whether to push or assign */
2821 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2825 operand *top = operandFromSymbol (argVals->sym);
2826 /* clear useDef and other bitVectors */
2827 OP_USES (top) = OP_DEFS (top) = OP_SYMBOL(top)->clashes = NULL;
2828 geniCodeAssign (top, pval, 1);
2832 sym_link *p = operandType (pval);
2834 ic = newiCode (IPUSH, pval, NULL);
2836 /* update the stack adjustment */
2837 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2842 argVals=argVals->next;
2846 /*-----------------------------------------------------------------*/
2847 /* geniCodeCall - generates temp code for calling */
2848 /*-----------------------------------------------------------------*/
2850 geniCodeCall (operand * left, ast * parms,int lvl)
2854 sym_link *type, *etype;
2857 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2858 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2859 werror (E_FUNCTION_EXPECTED);
2863 /* take care of parameters with side-effecting
2864 function calls in them, this is required to take care
2865 of overlaying function parameters */
2866 geniCodeSEParms (parms,lvl);
2868 /* first the parameters */
2869 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2871 /* now call : if symbol then pcall */
2872 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2873 ic = newiCode (PCALL, left, NULL);
2875 ic = newiCode (CALL, left, NULL);
2877 type = copyLinkChain (operandType (left)->next);
2878 etype = getSpec (type);
2879 SPEC_EXTR (etype) = 0;
2880 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2884 /* stack adjustment after call */
2885 ic->parmBytes = stack;
2890 /*-----------------------------------------------------------------*/
2891 /* geniCodeReceive - generate intermediate code for "receive" */
2892 /*-----------------------------------------------------------------*/
2894 geniCodeReceive (value * args)
2896 /* for all arguments that are passed in registers */
2900 if (IS_REGPARM (args->etype))
2902 operand *opr = operandFromValue (args);
2904 symbol *sym = OP_SYMBOL (opr);
2907 /* we will use it after all optimizations
2908 and before liveRange calculation */
2909 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2912 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2913 options.stackAuto == 0 &&
2914 /* !TARGET_IS_DS390) */
2915 (!(options.model == MODEL_FLAT24)) )
2920 opl = newiTempOperand (args->type, 0);
2922 sym->reqv->key = sym->key;
2923 OP_SYMBOL (sym->reqv)->key = sym->key;
2924 OP_SYMBOL (sym->reqv)->isreqv = 1;
2925 OP_SYMBOL (sym->reqv)->islocal = 0;
2926 SPIL_LOC (sym->reqv) = sym;
2930 ic = newiCode (RECEIVE, NULL, NULL);
2931 currFunc->recvSize = getSize (sym->etype);
2932 IC_RESULT (ic) = opr;
2940 /*-----------------------------------------------------------------*/
2941 /* geniCodeFunctionBody - create the function body */
2942 /*-----------------------------------------------------------------*/
2944 geniCodeFunctionBody (ast * tree,int lvl)
2951 /* reset the auto generation */
2957 func = ast2iCode (tree->left,lvl+1);
2958 fetype = getSpec (operandType (func));
2960 savelineno = lineno;
2961 lineno = OP_SYMBOL (func)->lineDef;
2962 /* create an entry label */
2963 geniCodeLabel (entryLabel);
2964 lineno = savelineno;
2966 /* create a proc icode */
2967 ic = newiCode (FUNCTION, func, NULL);
2968 ic->lineno = OP_SYMBOL (func)->lineDef;
2972 /* for all parameters that are passed
2973 on registers add a "receive" */
2974 geniCodeReceive (tree->values.args);
2976 /* generate code for the body */
2977 ast2iCode (tree->right,lvl+1);
2979 /* create a label for return */
2980 geniCodeLabel (returnLabel);
2982 /* now generate the end proc */
2983 ic = newiCode (ENDFUNCTION, func, NULL);
2988 /*-----------------------------------------------------------------*/
2989 /* geniCodeReturn - gen icode for 'return' statement */
2990 /*-----------------------------------------------------------------*/
2992 geniCodeReturn (operand * op)
2996 /* if the operand is present force an rvalue */
2998 op = geniCodeRValue (op, FALSE);
3000 ic = newiCode (RETURN, op, NULL);
3004 /*-----------------------------------------------------------------*/
3005 /* geniCodeIfx - generates code for extended if statement */
3006 /*-----------------------------------------------------------------*/
3008 geniCodeIfx (ast * tree,int lvl)
3011 operand *condition = ast2iCode (tree->left,lvl+1);
3014 /* if condition is null then exit */
3018 condition = geniCodeRValue (condition, FALSE);
3020 cetype = getSpec (operandType (condition));
3021 /* if the condition is a literal */
3022 if (IS_LITERAL (cetype))
3024 if (floatFromVal (condition->operand.valOperand))
3026 if (tree->trueLabel)
3027 geniCodeGoto (tree->trueLabel);
3033 if (tree->falseLabel)
3034 geniCodeGoto (tree->falseLabel);
3041 if (tree->trueLabel)
3043 ic = newiCodeCondition (condition,
3048 if (tree->falseLabel)
3049 geniCodeGoto (tree->falseLabel);
3053 ic = newiCodeCondition (condition,
3060 ast2iCode (tree->right,lvl+1);
3063 /*-----------------------------------------------------------------*/
3064 /* geniCodeJumpTable - tries to create a jump table for switch */
3065 /*-----------------------------------------------------------------*/
3067 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3069 int min = 0, max = 0, t, cnt = 0;
3076 if (!tree || !caseVals)
3079 /* the criteria for creating a jump table is */
3080 /* all integer numbers between the maximum & minimum must */
3081 /* be present , the maximum value should not exceed 255 */
3082 min = max = (int) floatFromVal (vch = caseVals);
3083 sprintf (buffer, "_case_%d_%d",
3084 tree->values.switchVals.swNum,
3086 addSet (&labels, newiTempLabel (buffer));
3088 /* if there is only one case value then no need */
3089 if (!(vch = vch->next))
3094 if (((t = (int) floatFromVal (vch)) - max) != 1)
3096 sprintf (buffer, "_case_%d_%d",
3097 tree->values.switchVals.swNum,
3099 addSet (&labels, newiTempLabel (buffer));
3105 /* if the number of case statements <= 2 then */
3106 /* it is not economical to create the jump table */
3107 /* since two compares are needed for boundary conditions */
3108 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3111 if (tree->values.switchVals.swDefault)
3112 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3114 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3116 falseLabel = newiTempLabel (buffer);
3118 /* so we can create a jumptable */
3119 /* first we rule out the boundary conditions */
3120 /* if only optimization says so */
3121 if (!optimize.noJTabBoundary)
3123 sym_link *cetype = getSpec (operandType (cond));
3124 /* no need to check the lower bound if
3125 the condition is unsigned & minimum value is zero */
3126 if (!(min == 0 && SPEC_USIGN (cetype)))
3128 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3129 ic = newiCodeCondition (boundary, falseLabel, NULL);
3133 /* now for upper bounds */
3134 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3135 ic = newiCodeCondition (boundary, falseLabel, NULL);
3139 /* if the min is not zero then we no make it zero */
3142 cond = geniCodeSubtract (cond, operandFromLit (min));
3143 setOperandType (cond, UCHARTYPE);
3146 /* now create the jumptable */
3147 ic = newiCode (JUMPTABLE, NULL, NULL);
3148 IC_JTCOND (ic) = cond;
3149 IC_JTLABELS (ic) = labels;
3154 /*-----------------------------------------------------------------*/
3155 /* geniCodeSwitch - changes a switch to a if statement */
3156 /*-----------------------------------------------------------------*/
3158 geniCodeSwitch (ast * tree,int lvl)
3161 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3162 value *caseVals = tree->values.switchVals.swVals;
3163 symbol *trueLabel, *falseLabel;
3165 /* if we can make this a jump table */
3166 if (geniCodeJumpTable (cond, caseVals, tree))
3167 goto jumpTable; /* no need for the comparison */
3169 /* for the cases defined do */
3173 operand *compare = geniCodeLogic (cond,
3174 operandFromValue (caseVals),
3177 sprintf (buffer, "_case_%d_%d",
3178 tree->values.switchVals.swNum,
3179 (int) floatFromVal (caseVals));
3180 trueLabel = newiTempLabel (buffer);
3182 ic = newiCodeCondition (compare, trueLabel, NULL);
3184 caseVals = caseVals->next;
3189 /* if default is present then goto break else break */
3190 if (tree->values.switchVals.swDefault)
3191 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3193 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3195 falseLabel = newiTempLabel (buffer);
3196 geniCodeGoto (falseLabel);
3199 ast2iCode (tree->right,lvl+1);
3202 /*-----------------------------------------------------------------*/
3203 /* geniCodeInline - intermediate code for inline assembler */
3204 /*-----------------------------------------------------------------*/
3206 geniCodeInline (ast * tree)
3210 ic = newiCode (INLINEASM, NULL, NULL);
3211 IC_INLINE (ic) = tree->values.inlineasm;
3215 /*-----------------------------------------------------------------*/
3216 /* geniCodeArrayInit - intermediate code for array initializer */
3217 /*-----------------------------------------------------------------*/
3219 geniCodeArrayInit (ast * tree, operand *array)
3223 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3224 ic = newiCode (ARRAYINIT, array, NULL);
3225 IC_ARRAYILIST (ic) = tree->values.constlist;
3227 operand *left=newOperand(), *right=newOperand();
3228 left->type=right->type=SYMBOL;
3229 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3230 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3231 ic = newiCode (ARRAYINIT, left, right);
3236 /*-----------------------------------------------------------------*/
3237 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3238 /* particular case. Ie : assigning or dereferencing array or ptr */
3239 /*-----------------------------------------------------------------*/
3240 set * lvaluereqSet = NULL;
3241 typedef struct lvalItem
3248 /*-----------------------------------------------------------------*/
3249 /* addLvaluereq - add a flag for lvalreq for current ast level */
3250 /*-----------------------------------------------------------------*/
3251 void addLvaluereq(int lvl)
3253 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3256 addSetHead(&lvaluereqSet,lpItem);
3259 /*-----------------------------------------------------------------*/
3260 /* delLvaluereq - del a flag for lvalreq for current ast level */
3261 /*-----------------------------------------------------------------*/
3265 lpItem = getSet(&lvaluereqSet);
3266 if(lpItem) Safe_free(lpItem);
3268 /*-----------------------------------------------------------------*/
3269 /* clearLvaluereq - clear lvalreq flag */
3270 /*-----------------------------------------------------------------*/
3271 void clearLvaluereq()
3274 lpItem = peekSet(lvaluereqSet);
3275 if(lpItem) lpItem->req = 0;
3277 /*-----------------------------------------------------------------*/
3278 /* getLvaluereq - get the last lvalreq level */
3279 /*-----------------------------------------------------------------*/
3280 int getLvaluereqLvl()
3283 lpItem = peekSet(lvaluereqSet);
3284 if(lpItem) return lpItem->lvl;
3287 /*-----------------------------------------------------------------*/
3288 /* isLvaluereq - is lvalreq valid for this level ? */
3289 /*-----------------------------------------------------------------*/
3290 int isLvaluereq(int lvl)
3293 lpItem = peekSet(lvaluereqSet);
3294 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3298 /*-----------------------------------------------------------------*/
3299 /* ast2iCode - creates an icodeList from an ast */
3300 /*-----------------------------------------------------------------*/
3302 ast2iCode (ast * tree,int lvl)
3304 operand *left = NULL;
3305 operand *right = NULL;
3308 /* set the global variables for filename & line number */
3310 filename = tree->filename;
3312 lineno = tree->lineno;
3314 block = tree->block;
3316 scopeLevel = tree->level;
3318 if (tree->type == EX_VALUE)
3319 return operandFromValue (tree->opval.val);
3321 if (tree->type == EX_LINK)
3322 return operandFromLink (tree->opval.lnk);
3324 /* if we find a nullop */
3325 if (tree->type == EX_OP &&
3326 (tree->opval.op == NULLOP ||
3327 tree->opval.op == BLOCK))
3329 ast2iCode (tree->left,lvl+1);
3330 ast2iCode (tree->right,lvl+1);
3334 /* special cases for not evaluating */
3335 if (tree->opval.op != ':' &&
3336 tree->opval.op != '?' &&
3337 tree->opval.op != CALL &&
3338 tree->opval.op != IFX &&
3339 tree->opval.op != LABEL &&
3340 tree->opval.op != GOTO &&
3341 tree->opval.op != SWITCH &&
3342 tree->opval.op != FUNCTION &&
3343 tree->opval.op != INLINEASM)
3346 if (IS_ASSIGN_OP (tree->opval.op) ||
3347 IS_DEREF_OP (tree) ||
3348 (tree->opval.op == '&' && !tree->right) ||
3349 tree->opval.op == PTR_OP)
3352 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3353 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3356 left = operandFromAst (tree->left,lvl);
3358 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3359 left = geniCodeRValue (left, TRUE);
3363 left = operandFromAst (tree->left,lvl);
3365 if (tree->opval.op == INC_OP ||
3366 tree->opval.op == DEC_OP)
3369 right = operandFromAst (tree->right,lvl);
3374 right = operandFromAst (tree->right,lvl);
3378 /* now depending on the type of operand */
3379 /* this will be a biggy */
3380 switch (tree->opval.op)
3383 case '[': /* array operation */
3385 //sym_link *ltype = operandType (left);
3386 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3387 left = geniCodeRValue (left, FALSE);
3388 right = geniCodeRValue (right, TRUE);
3391 return geniCodeArray (left, right,lvl);
3393 case '.': /* structure dereference */
3394 if (IS_PTR (operandType (left)))
3395 left = geniCodeRValue (left, TRUE);
3397 left = geniCodeRValue (left, FALSE);
3399 return geniCodeStruct (left, right, tree->lvalue);
3401 case PTR_OP: /* structure pointer dereference */
3404 pType = operandType (left);
3405 left = geniCodeRValue (left, TRUE);
3407 setOClass (pType, getSpec (operandType (left)));
3410 return geniCodeStruct (left, right, tree->lvalue);
3412 case INC_OP: /* increment operator */
3414 return geniCodePostInc (left);
3416 return geniCodePreInc (right);
3418 case DEC_OP: /* decrement operator */
3420 return geniCodePostDec (left);
3422 return geniCodePreDec (right);
3424 case '&': /* bitwise and or address of operator */
3426 { /* this is a bitwise operator */
3427 left = geniCodeRValue (left, FALSE);
3428 right = geniCodeRValue (right, FALSE);
3429 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3432 return geniCodeAddressOf (left);
3434 case '|': /* bitwise or & xor */
3436 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3437 geniCodeRValue (right, FALSE),
3442 return geniCodeDivision (geniCodeRValue (left, FALSE),
3443 geniCodeRValue (right, FALSE));
3446 return geniCodeModulus (geniCodeRValue (left, FALSE),
3447 geniCodeRValue (right, FALSE));
3450 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3451 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3453 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3457 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3458 geniCodeRValue (right, FALSE));
3460 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3464 return geniCodeAdd (geniCodeRValue (left, FALSE),
3465 geniCodeRValue (right, FALSE),lvl);
3467 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3470 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3471 geniCodeRValue (right, FALSE));
3474 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3475 geniCodeRValue (right, FALSE));
3477 return geniCodeCast (operandType (left),
3478 geniCodeRValue (right, FALSE), FALSE);
3484 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3488 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3489 setOperandType (op, UCHARTYPE);
3500 return geniCodeLogic (geniCodeRValue (left, FALSE),
3501 geniCodeRValue (right, FALSE),
3504 return geniCodeConditional (tree,lvl);
3507 return operandFromLit (getSize (tree->right->ftype));
3511 sym_link *rtype = operandType (right);
3512 sym_link *ltype = operandType (left);
3513 if (IS_PTR (rtype) && IS_ITEMP (right)
3514 && right->isaddr && compareType (rtype->next, ltype) == 1)
3515 right = geniCodeRValue (right, TRUE);
3517 right = geniCodeRValue (right, FALSE);
3519 geniCodeAssign (left, right, 0);
3524 geniCodeAssign (left,
3525 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3527 geniCodeRValue (right, FALSE),FALSE), 0);
3531 geniCodeAssign (left,
3532 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3534 geniCodeRValue (right, FALSE)), 0);
3537 geniCodeAssign (left,
3538 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3540 geniCodeRValue (right, FALSE)), 0);
3543 sym_link *rtype = operandType (right);
3544 sym_link *ltype = operandType (left);
3545 if (IS_PTR (rtype) && IS_ITEMP (right)
3546 && right->isaddr && compareType (rtype->next, ltype) == 1)
3547 right = geniCodeRValue (right, TRUE);
3549 right = geniCodeRValue (right, FALSE);
3552 return geniCodeAssign (left,
3553 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3559 sym_link *rtype = operandType (right);
3560 sym_link *ltype = operandType (left);
3561 if (IS_PTR (rtype) && IS_ITEMP (right)
3562 && right->isaddr && compareType (rtype->next, ltype) == 1)
3564 right = geniCodeRValue (right, TRUE);
3568 right = geniCodeRValue (right, FALSE);
3571 geniCodeAssign (left,
3572 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3578 geniCodeAssign (left,
3579 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3581 geniCodeRValue (right, FALSE)), 0);
3584 geniCodeAssign (left,
3585 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3587 geniCodeRValue (right, FALSE)), 0);
3590 geniCodeAssign (left,
3591 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3593 geniCodeRValue (right, FALSE),
3595 operandType (left)), 0);
3598 geniCodeAssign (left,
3599 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3601 geniCodeRValue (right, FALSE),
3603 operandType (left)), 0);
3606 geniCodeAssign (left,
3607 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3609 geniCodeRValue (right, FALSE),
3611 operandType (left)), 0);
3613 return geniCodeRValue (right, FALSE);
3616 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3619 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3620 return ast2iCode (tree->right,lvl+1);
3623 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3624 return ast2iCode (tree->right,lvl+1);
3627 geniCodeFunctionBody (tree,lvl);
3631 geniCodeReturn (right);
3635 geniCodeIfx (tree,lvl);
3639 geniCodeSwitch (tree,lvl);
3643 geniCodeInline (tree);
3647 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3654 /*-----------------------------------------------------------------*/
3655 /* reverseICChain - gets from the list and creates a linkedlist */
3656 /*-----------------------------------------------------------------*/
3663 while ((loop = getSet (&iCodeChain)))
3675 /*-----------------------------------------------------------------*/
3676 /* iCodeFromAst - given an ast will convert it to iCode */
3677 /*-----------------------------------------------------------------*/
3679 iCodeFromAst (ast * tree)
3681 returnLabel = newiTempLabel ("_return");
3682 entryLabel = newiTempLabel ("_entry");
3684 return reverseiCChain ();