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 -------------------------------------------------------------------------*/
28 /*-----------------------------------------------------------------*/
29 /* global variables */
31 set *iCodeChain = NULL;
41 symbol *returnLabel; /* function return label */
42 symbol *entryLabel; /* function entry label */
44 #if defined(__BORLANDC__) || defined(_MSC_VER)
45 #define LONG_LONG __int64
47 #define LONG_LONG long long
50 /*-----------------------------------------------------------------*/
51 /* forward definition of some functions */
52 operand *geniCodeDivision (operand *, operand *);
53 operand *geniCodeAssign (operand *, operand *, int);
54 operand *geniCodeArray (operand *, operand *,int);
55 operand *geniCodeArray2Ptr (operand *);
56 operand *geniCodeRValue (operand *, bool);
57 operand *geniCodeDerefPtr (operand *,int);
58 int isLvaluereq(int lvl);
60 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
61 /* forward definition of ic print functions */
62 PRINTFUNC (picGetValueAtAddr);
63 PRINTFUNC (picSetValueAtAddr);
64 PRINTFUNC (picAddrOf);
65 PRINTFUNC (picGeneric);
66 PRINTFUNC (picGenericOne);
68 PRINTFUNC (picAssign);
72 PRINTFUNC (picJumpTable);
73 PRINTFUNC (picInline);
74 PRINTFUNC (picReceive);
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},
123 /*-----------------------------------------------------------------*/
124 /* checkConstantRange: check a constant against the type */
125 /*-----------------------------------------------------------------*/
127 /* pedantic=0: allmost anything is allowed as long as the absolute
128 value is within the bit range of the type, and -1 is treated as
129 0xf..f for unsigned types (e.g. in assign)
130 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
131 pedantic>1: "char c=200" is not allowed (evaluates to -56)
134 void checkConstantRange(sym_link *ltype, value *val, char *msg, int pedantic) {
135 LONG_LONG max = (LONG_LONG) 1 << bitsForType(ltype);
136 char message[132]="";
139 long v=SPEC_CVAL(val->type).v_long;
142 // this could be a good idea
143 if (options.pedantic)
147 if (SPEC_NOUN(ltype)==FLOAT) {
152 if (!SPEC_USIGN(val->type) && v<0) {
154 if (SPEC_USIGN(ltype) && (pedantic>1)) {
160 // if very pedantic: "char c=200" is not allowed
161 if (pedantic>1 && !SPEC_USIGN(ltype)) {
162 max = max/2 + negative;
170 sprintf (message, "for %s %s in %s",
171 SPEC_USIGN(ltype) ? "unsigned" : "signed",
172 nounName(ltype), msg);
173 werror (W_CONST_RANGE, message);
180 /*-----------------------------------------------------------------*/
181 /* operandName - returns the name of the operand */
182 /*-----------------------------------------------------------------*/
184 printOperand (operand * op, FILE * file)
201 opetype = getSpec (operandType (op));
202 if (SPEC_NOUN (opetype) == V_FLOAT)
203 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
205 fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
206 printTypeChain (operandType (op), file);
213 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
214 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
216 OP_LIVEFROM (op), OP_LIVETO (op),
217 OP_SYMBOL (op)->stack,
218 op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc
222 printTypeChain (operandType (op), file);
223 if (SPIL_LOC (op) && IS_ITEMP (op))
224 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
229 /* if assigned to registers */
230 if (OP_SYMBOL (op)->nRegs)
232 if (OP_SYMBOL (op)->isspilt)
234 if (!OP_SYMBOL (op)->remat)
235 if (OP_SYMBOL (op)->usl.spillLoc)
236 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
237 OP_SYMBOL (op)->usl.spillLoc->rname :
238 OP_SYMBOL (op)->usl.spillLoc->name));
240 fprintf (file, "[err]");
242 fprintf (file, "[remat]");
248 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
249 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
254 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
255 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
256 /* if assigned to registers */
257 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
261 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
262 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
263 OP_SYMBOL (op)->regs[i]->name :
272 printTypeChain (op->operand.typeOperand, file);
278 fprintf (file, "\n");
283 /*-----------------------------------------------------------------*/
284 /* print functions */
285 /*-----------------------------------------------------------------*/
286 PRINTFUNC (picGetValueAtAddr)
289 printOperand (IC_RESULT (ic), of);
292 printOperand (IC_LEFT (ic), of);
298 PRINTFUNC (picSetValueAtAddr)
302 printOperand (IC_LEFT (ic), of);
303 fprintf (of, "] = ");
304 printOperand (IC_RIGHT (ic), of);
308 PRINTFUNC (picAddrOf)
311 printOperand (IC_RESULT (ic), of);
312 if (IS_ITEMP (IC_LEFT (ic)))
315 fprintf (of, " = &[");
316 printOperand (IC_LEFT (ic), of);
319 if (IS_ITEMP (IC_LEFT (ic)))
320 fprintf (of, " offsetAdd ");
323 printOperand (IC_RIGHT (ic), of);
325 if (IS_ITEMP (IC_LEFT (ic)))
331 PRINTFUNC (picJumpTable)
336 fprintf (of, "%s\t", s);
337 printOperand (IC_JTCOND (ic), of);
339 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
340 sym = setNextItem (IC_JTLABELS (ic)))
341 fprintf (of, "\t\t\t%s\n", sym->name);
344 PRINTFUNC (picGeneric)
347 printOperand (IC_RESULT (ic), of);
349 printOperand (IC_LEFT (ic), of);
350 fprintf (of, " %s ", s);
351 printOperand (IC_RIGHT (ic), of);
355 PRINTFUNC (picGenericOne)
360 printOperand (IC_RESULT (ic), of);
366 fprintf (of, "%s ", s);
367 printOperand (IC_LEFT (ic), of);
370 if (!IC_RESULT (ic) && !IC_LEFT (ic))
379 printOperand (IC_RESULT (ic), of);
381 printOperand (IC_LEFT (ic), of);
382 printOperand (IC_RIGHT (ic), of);
387 PRINTFUNC (picAssign)
391 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
394 printOperand (IC_RESULT (ic), of);
396 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
399 fprintf (of, " %s ", s);
400 printOperand (IC_RIGHT (ic), of);
407 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
413 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
420 printOperand (IC_COND (ic), of);
423 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
426 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
428 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
432 PRINTFUNC (picInline)
434 fprintf (of, "%s", IC_INLINE (ic));
437 PRINTFUNC (picReceive)
439 printOperand (IC_RESULT (ic), of);
440 fprintf (of, " = %s ", s);
441 printOperand (IC_LEFT (ic), of);
445 /*-----------------------------------------------------------------*/
446 /* piCode - prints one iCode */
447 /*-----------------------------------------------------------------*/
449 piCode (void *item, FILE * of)
457 icTab = getTableEntry (ic->op);
458 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
459 ic->filename, ic->lineno,
460 ic->seq, ic->key, ic->depth, ic->supportRtn);
461 icTab->iCodePrint (of, ic, icTab->printName);
467 printiCChain(ic,stdout);
469 /*-----------------------------------------------------------------*/
470 /* printiCChain - prints intermediate code for humans */
471 /*-----------------------------------------------------------------*/
473 printiCChain (iCode * icChain, FILE * of)
480 for (loop = icChain; loop; loop = loop->next)
482 if ((icTab = getTableEntry (loop->op)))
484 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
485 loop->filename, loop->lineno,
486 loop->seq, loop->key, loop->depth, loop->supportRtn);
488 icTab->iCodePrint (of, loop, icTab->printName);
494 /*-----------------------------------------------------------------*/
495 /* newOperand - allocate, init & return a new iCode */
496 /*-----------------------------------------------------------------*/
502 op = Safe_alloc ( sizeof (operand));
508 /*-----------------------------------------------------------------*/
509 /* newiCode - create and return a new iCode entry initialised */
510 /*-----------------------------------------------------------------*/
512 newiCode (int op, operand * left, operand * right)
516 ic = Safe_alloc ( sizeof (iCode));
519 ic->filename = filename;
521 ic->level = scopeLevel;
523 ic->key = iCodeKey++;
525 IC_RIGHT (ic) = right;
530 /*-----------------------------------------------------------------*/
531 /* newiCode for conditional statements */
532 /*-----------------------------------------------------------------*/
534 newiCodeCondition (operand * condition,
540 if (IS_VOID(OP_SYMBOL(condition)->type)) {
541 werror(E_VOID_VALUE_USED);
544 ic = newiCode (IFX, NULL, NULL);
545 IC_COND (ic) = condition;
546 IC_TRUE (ic) = trueLabel;
547 IC_FALSE (ic) = falseLabel;
551 /*-----------------------------------------------------------------*/
552 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
553 /*-----------------------------------------------------------------*/
555 newiCodeLabelGoto (int op, symbol * label)
559 ic = newiCode (op, NULL, NULL);
561 ic->argLabel.label = label;
563 IC_RIGHT (ic) = NULL;
564 IC_RESULT (ic) = NULL;
568 /*-----------------------------------------------------------------*/
569 /* newiTemp - allocate & return a newItemp Variable */
570 /*-----------------------------------------------------------------*/
577 sprintf (buffer, "%s", s);
579 sprintf (buffer, "iTemp%d", iTempNum++);
580 itmp = newSymbol (buffer, 1);
581 strcpy (itmp->rname, itmp->name);
587 /*-----------------------------------------------------------------*/
588 /* newiTempLabel - creates a temp variable label */
589 /*-----------------------------------------------------------------*/
591 newiTempLabel (char *s)
595 /* check if this alredy exists */
596 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
600 itmplbl = newSymbol (s, 1);
603 sprintf (buffer, "iTempLbl%d", iTempLblNum++);
604 itmplbl = newSymbol (buffer, 1);
609 itmplbl->key = labelKey++;
610 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
614 /*-----------------------------------------------------------------*/
615 /* newiTempPreheaderLabel - creates a new preheader label */
616 /*-----------------------------------------------------------------*/
618 newiTempPreheaderLabel ()
622 sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
623 itmplbl = newSymbol (buffer, 1);
627 itmplbl->key = labelKey++;
628 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
633 /*-----------------------------------------------------------------*/
634 /* initiCode - initialises some iCode related stuff */
635 /*-----------------------------------------------------------------*/
642 /*-----------------------------------------------------------------*/
643 /* copyiCode - make a copy of the iCode given */
644 /*-----------------------------------------------------------------*/
646 copyiCode (iCode * ic)
648 iCode *nic = newiCode (ic->op, NULL, NULL);
650 nic->lineno = ic->lineno;
651 nic->filename = ic->filename;
652 nic->block = ic->block;
653 nic->level = ic->level;
654 nic->parmBytes = ic->parmBytes;
656 /* deal with the special cases first */
660 IC_COND (nic) = operandFromOperand (IC_COND (ic));
661 IC_TRUE (nic) = IC_TRUE (ic);
662 IC_FALSE (nic) = IC_FALSE (ic);
666 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
667 IC_JTLABELS (nic) = IC_JTLABELS (ic);
672 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
673 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
674 IC_ARGS (nic) = IC_ARGS (ic);
678 IC_INLINE (nic) = IC_INLINE (ic);
682 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
686 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
687 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
688 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
694 /*-----------------------------------------------------------------*/
695 /* getTableEntry - gets the table entry for the given operator */
696 /*-----------------------------------------------------------------*/
698 getTableEntry (int oper)
702 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
703 if (oper == codeTable[i].icode)
704 return &codeTable[i];
709 /*-----------------------------------------------------------------*/
710 /* newiTempOperand - new intermediate temp operand */
711 /*-----------------------------------------------------------------*/
713 newiTempOperand (sym_link * type, char throwType)
716 operand *op = newOperand ();
720 itmp = newiTemp (NULL);
722 etype = getSpec (type);
724 if (IS_LITERAL (etype))
727 /* copy the type information */
729 itmp->etype = getSpec (itmp->type = (throwType ? type :
730 copyLinkChain (type)));
731 if (IS_LITERAL (itmp->etype))
733 SPEC_SCLS (itmp->etype) = S_REGISTER;
734 SPEC_OCLS (itmp->etype) = reg;
737 op->operand.symOperand = itmp;
738 op->key = itmp->key = ++operandKey;
742 /*-----------------------------------------------------------------*/
743 /* operandType - returns the type chain for an operand */
744 /*-----------------------------------------------------------------*/
746 operandType (operand * op)
748 /* depending on type of operand */
753 return op->operand.valOperand->type;
756 return op->operand.symOperand->type;
759 return op->operand.typeOperand;
761 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
762 " operand type not known ");
763 assert (0); /* should never come here */
764 /* Just to keep the compiler happy */
765 return (sym_link *) 0;
769 /*-----------------------------------------------------------------*/
770 /* isParamterToCall - will return 1 if op is a parameter to args */
771 /*-----------------------------------------------------------------*/
773 isParameterToCall (value * args, operand * op)
780 isSymbolEqual (op->operand.symOperand, tval->sym))
787 /*-----------------------------------------------------------------*/
788 /* isOperandGlobal - return 1 if operand is a global variable */
789 /*-----------------------------------------------------------------*/
791 isOperandGlobal (operand * op)
799 if (op->type == SYMBOL &&
800 (op->operand.symOperand->level == 0 ||
801 IS_STATIC (op->operand.symOperand->etype) ||
802 IS_EXTERN (op->operand.symOperand->etype))
809 /*-----------------------------------------------------------------*/
810 /* isOperandVolatile - return 1 if the operand is volatile */
811 /*-----------------------------------------------------------------*/
813 isOperandVolatile (operand * op, bool chkTemp)
818 if (IS_ITEMP (op) && !chkTemp)
821 opetype = getSpec (optype = operandType (op));
823 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
826 if (IS_VOLATILE (opetype))
831 /*-----------------------------------------------------------------*/
832 /* isOperandLiteral - returns 1 if an operand contains a literal */
833 /*-----------------------------------------------------------------*/
835 isOperandLiteral (operand * op)
842 opetype = getSpec (operandType (op));
844 if (IS_LITERAL (opetype))
849 /*-----------------------------------------------------------------*/
850 /* isOperandInFarSpace - will return true if operand is in farSpace */
851 /*-----------------------------------------------------------------*/
853 isOperandInFarSpace (operand * op)
863 if (!IS_TRUE_SYMOP (op))
866 etype = SPIL_LOC (op)->etype;
872 etype = getSpec (operandType (op));
874 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
877 /*-----------------------------------------------------------------*/
878 /* isOperandOnStack - will return true if operand is on stack */
879 /*-----------------------------------------------------------------*/
881 isOperandOnStack (operand * op)
891 etype = getSpec (operandType (op));
893 return ((IN_STACK (etype)) ? TRUE : FALSE);
896 /*-----------------------------------------------------------------*/
897 /* operandLitValue - literal value of an operand */
898 /*-----------------------------------------------------------------*/
900 operandLitValue (operand * op)
902 assert (isOperandLiteral (op));
904 return floatFromVal (op->operand.valOperand);
907 /*-----------------------------------------------------------------*/
908 /* operandOperation - perforoms operations on operands */
909 /*-----------------------------------------------------------------*/
911 operandOperation (operand * left, operand * right,
912 int op, sym_link * type)
914 sym_link *let , *ret=NULL;
915 operand *retval = (operand *) 0;
917 assert (isOperandLiteral (left));
918 let = getSpec(operandType(left));
920 assert (isOperandLiteral (right));
921 ret = getSpec(operandType(left));
927 retval = operandFromValue (valCastLiteral (type,
928 operandLitValue (left) +
929 operandLitValue (right)));
932 retval = operandFromValue (valCastLiteral (type,
933 operandLitValue (left) -
934 operandLitValue (right)));
937 retval = operandFromValue (valCastLiteral (type,
938 operandLitValue (left) *
939 operandLitValue (right)));
942 if ((unsigned long) operandLitValue (right) == 0)
944 werror (E_DIVIDE_BY_ZERO);
949 retval = operandFromValue (valCastLiteral (type,
950 operandLitValue (left) /
951 operandLitValue (right)));
954 if ((unsigned long) operandLitValue (right) == 0) {
955 werror (E_DIVIDE_BY_ZERO);
959 retval = operandFromLit ((SPEC_USIGN(let) ?
960 (unsigned long) operandLitValue (left) :
961 (long) operandLitValue (left)) %
963 (unsigned long) operandLitValue (right) :
964 (long) operandLitValue (right)));
968 retval = operandFromLit ((SPEC_USIGN(let) ?
969 (unsigned long) operandLitValue (left) :
970 (long) operandLitValue (left)) <<
972 (unsigned long) operandLitValue (right) :
973 (long) operandLitValue (right)));
976 retval = operandFromLit ((SPEC_USIGN(let) ?
977 (unsigned long) operandLitValue (left) :
978 (long) operandLitValue (left)) >>
980 (unsigned long) operandLitValue (right) :
981 (long) operandLitValue (right)));
984 retval = operandFromLit (operandLitValue (left) ==
985 operandLitValue (right));
988 retval = operandFromLit (operandLitValue (left) <
989 operandLitValue (right));
992 retval = operandFromLit (operandLitValue (left) <=
993 operandLitValue (right));
996 retval = operandFromLit (operandLitValue (left) !=
997 operandLitValue (right));
1000 retval = operandFromLit (operandLitValue (left) >
1001 operandLitValue (right));
1004 retval = operandFromLit (operandLitValue (left) >=
1005 operandLitValue (right));
1008 retval = operandFromLit ((SPEC_USIGN(let) ?
1009 (unsigned long) operandLitValue (left) :
1010 (long) operandLitValue (left)) &
1012 (unsigned long) operandLitValue (right) :
1013 (long) operandLitValue (right)));
1016 retval = operandFromLit ((SPEC_USIGN(let) ?
1017 (unsigned long) operandLitValue (left) :
1018 (long) operandLitValue (left)) |
1020 (unsigned long) operandLitValue (right) :
1021 (long) operandLitValue (right)));
1024 retval = operandFromLit ((SPEC_USIGN(let) ?
1025 (unsigned long) operandLitValue (left) :
1026 (long) operandLitValue (left)) ^
1028 (unsigned long) operandLitValue (right) :
1029 (long) operandLitValue (right)));
1032 retval = operandFromLit (operandLitValue (left) &&
1033 operandLitValue (right));
1036 retval = operandFromLit (operandLitValue (left) ||
1037 operandLitValue (right));
1041 long i = (long) operandLitValue (left);
1043 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1049 long i = (long) operandLitValue (left);
1051 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1057 retval = operandFromLit (-1 * operandLitValue (left));
1061 retval = operandFromLit (~((long) operandLitValue (left)));
1065 retval = operandFromLit (!operandLitValue (left));
1069 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1070 " operandOperation invalid operator ");
1078 /*-----------------------------------------------------------------*/
1079 /* isOperandEqual - compares two operand & return 1 if they r = */
1080 /*-----------------------------------------------------------------*/
1082 isOperandEqual (operand * left, operand * right)
1084 /* if the pointers are equal then they are equal */
1088 /* if either of them null then false */
1089 if (!left || !right)
1092 if (left->type != right->type)
1095 if (IS_SYMOP (left) && IS_SYMOP (right))
1096 return left->key == right->key;
1098 /* if types are the same */
1102 return isSymbolEqual (left->operand.symOperand,
1103 right->operand.symOperand);
1105 return (floatFromVal (left->operand.valOperand) ==
1106 floatFromVal (right->operand.valOperand));
1108 if (compareType (left->operand.typeOperand,
1109 right->operand.typeOperand) == 1)
1116 /*-------------------------------------------------------------------*/
1117 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1118 /*-------------------------------------------------------------------*/
1120 isiCodeEqual (iCode * left, iCode * right)
1122 /* if the same pointer */
1126 /* if either of them null */
1127 if (!left || !right)
1130 /* if operand are the same */
1131 if (left->op == right->op)
1134 /* compare all the elements depending on type */
1135 if (left->op != IFX)
1137 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1139 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1145 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1147 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1149 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1158 /*-----------------------------------------------------------------*/
1159 /* newiTempFromOp - create a temp Operand with same attributes */
1160 /*-----------------------------------------------------------------*/
1162 newiTempFromOp (operand * op)
1172 nop = newiTempOperand (operandType (op), TRUE);
1173 nop->isaddr = op->isaddr;
1174 nop->isvolatile = op->isvolatile;
1175 nop->isGlobal = op->isGlobal;
1176 nop->isLiteral = op->isLiteral;
1177 nop->usesDefs = op->usesDefs;
1178 nop->isParm = op->isParm;
1182 /*-----------------------------------------------------------------*/
1183 /* operand from operand - creates an operand holder for the type */
1184 /*-----------------------------------------------------------------*/
1186 operandFromOperand (operand * op)
1192 nop = newOperand ();
1193 nop->type = op->type;
1194 nop->isaddr = op->isaddr;
1196 nop->isvolatile = op->isvolatile;
1197 nop->isGlobal = op->isGlobal;
1198 nop->isLiteral = op->isLiteral;
1199 nop->usesDefs = op->usesDefs;
1200 nop->isParm = op->isParm;
1205 nop->operand.symOperand = op->operand.symOperand;
1208 nop->operand.valOperand = op->operand.valOperand;
1211 nop->operand.typeOperand = op->operand.typeOperand;
1218 /*-----------------------------------------------------------------*/
1219 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1220 /*-----------------------------------------------------------------*/
1222 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1224 operand *nop = operandFromOperand (op);
1226 if (nop->type == SYMBOL)
1228 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1229 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1235 /*-----------------------------------------------------------------*/
1236 /* operandFromSymbol - creates an operand from a symbol */
1237 /*-----------------------------------------------------------------*/
1239 operandFromSymbol (symbol * sym)
1244 /* if the symbol's type is a literal */
1245 /* then it is an enumerator type */
1246 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1247 return operandFromValue (valFromType (sym->etype));
1250 sym->key = ++operandKey;
1252 /* if this an implicit variable, means struct/union */
1253 /* member so just return it */
1254 if (sym->implicit || IS_FUNC (sym->type))
1258 op->operand.symOperand = sym;
1260 op->isvolatile = isOperandVolatile (op, TRUE);
1261 op->isGlobal = isOperandGlobal (op);
1265 /* under the following conditions create a
1266 register equivalent for a local symbol */
1267 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1268 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1269 /* (!TARGET_IS_DS390)) && */
1270 (!(options.model == MODEL_FLAT24)) ) &&
1271 options.stackAuto == 0)
1274 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1275 !IS_FUNC (sym->type) && /* not a function */
1276 !sym->_isparm && /* not a parameter */
1277 sym->level && /* is a local variable */
1278 !sym->addrtaken && /* whose address has not been taken */
1279 !sym->reqv && /* does not already have a register euivalence */
1280 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1281 !IS_STATIC (sym->etype) && /* and not declared static */
1282 !sym->islbl && /* not a label */
1283 ok && /* farspace check */
1284 !IS_BITVAR (sym->etype) /* not a bit variable */
1288 /* we will use it after all optimizations
1289 and before liveRange calculation */
1290 sym->reqv = newiTempOperand (sym->type, 0);
1291 sym->reqv->key = sym->key;
1292 OP_SYMBOL (sym->reqv)->key = sym->key;
1293 OP_SYMBOL (sym->reqv)->isreqv = 1;
1294 OP_SYMBOL (sym->reqv)->islocal = 1;
1295 SPIL_LOC (sym->reqv) = sym;
1298 if (!IS_AGGREGATE (sym->type))
1302 op->operand.symOperand = sym;
1305 op->isvolatile = isOperandVolatile (op, TRUE);
1306 op->isGlobal = isOperandGlobal (op);
1307 op->isPtr = IS_PTR (operandType (op));
1308 op->isParm = sym->_isparm;
1313 /* itemp = &[_symbol] */
1315 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1316 IC_LEFT (ic)->type = SYMBOL;
1317 IC_LEFT (ic)->operand.symOperand = sym;
1318 IC_LEFT (ic)->key = sym->key;
1319 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1320 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1321 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1324 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1325 if (IS_ARRAY (sym->type))
1327 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1328 IC_RESULT (ic)->isaddr = 0;
1331 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1333 IC_RESULT (ic)->operand.symOperand->args = sym->args;
1337 return IC_RESULT (ic);
1340 /*-----------------------------------------------------------------*/
1341 /* operandFromValue - creates an operand from value */
1342 /*-----------------------------------------------------------------*/
1344 operandFromValue (value * val)
1348 /* if this is a symbol then do the symbol thing */
1350 return operandFromSymbol (val->sym);
1352 /* this is not a symbol */
1355 op->operand.valOperand = val;
1356 op->isLiteral = isOperandLiteral (op);
1360 /*-----------------------------------------------------------------*/
1361 /* operandFromLink - operand from typeChain */
1362 /*-----------------------------------------------------------------*/
1364 operandFromLink (sym_link * type)
1368 /* operand from sym_link */
1374 op->operand.typeOperand = copyLinkChain (type);
1378 /*-----------------------------------------------------------------*/
1379 /* operandFromLit - makes an operand from a literal value */
1380 /*-----------------------------------------------------------------*/
1382 operandFromLit (double i)
1384 return operandFromValue (valueFromLit (i));
1387 /*-----------------------------------------------------------------*/
1388 /* operandFromAst - creates an operand from an ast */
1389 /*-----------------------------------------------------------------*/
1391 operandFromAst (ast * tree,int lvl)
1397 /* depending on type do */
1401 return ast2iCode (tree,lvl+1);
1405 return operandFromValue (tree->opval.val);
1409 return operandFromLink (tree->opval.lnk);
1413 /* Just to keep the comiler happy */
1414 return (operand *) 0;
1417 /*-----------------------------------------------------------------*/
1418 /* setOperandType - sets the operand's type to the given type */
1419 /*-----------------------------------------------------------------*/
1421 setOperandType (operand * op, sym_link * type)
1423 /* depending on the type of operand */
1428 op->operand.valOperand->etype =
1429 getSpec (op->operand.valOperand->type =
1430 copyLinkChain (type));
1434 if (op->operand.symOperand->isitmp)
1435 op->operand.symOperand->etype =
1436 getSpec (op->operand.symOperand->type =
1437 copyLinkChain (type));
1439 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1440 "attempt to modify type of source");
1444 op->operand.typeOperand = copyLinkChain (type);
1449 /*-----------------------------------------------------------------*/
1450 /* Get size in byte of ptr need to access an array */
1451 /*-----------------------------------------------------------------*/
1453 getArraySizePtr (operand * op)
1455 sym_link *ltype = operandType(op);
1459 int size = getSize(ltype);
1460 return(IS_GENPTR(ltype)?(size-1):size);
1465 sym_link *letype = getSpec(ltype);
1466 switch (PTR_TYPE (SPEC_OCLS (letype)))
1478 return (GPTRSIZE-1);
1487 /*-----------------------------------------------------------------*/
1488 /* perform "usual unary conversions" */
1489 /*-----------------------------------------------------------------*/
1491 usualUnaryConversions (operand * op)
1493 if (IS_INTEGRAL (operandType (op)))
1495 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1498 return geniCodeCast (INTTYPE, op, TRUE);
1504 /*-----------------------------------------------------------------*/
1505 /* perform "usual binary conversions" */
1506 /*-----------------------------------------------------------------*/
1508 usualBinaryConversions (operand ** op1, operand ** op2)
1511 sym_link *rtype = operandType (*op2);
1512 sym_link *ltype = operandType (*op1);
1514 ctype = computeType (ltype, rtype);
1515 *op1 = geniCodeCast (ctype, *op1, TRUE);
1516 *op2 = geniCodeCast (ctype, *op2, TRUE);
1521 /*-----------------------------------------------------------------*/
1522 /* geniCodeValueAtAddress - generate intermeditate code for value */
1524 /*-----------------------------------------------------------------*/
1526 geniCodeRValue (operand * op, bool force)
1529 sym_link *type = operandType (op);
1530 sym_link *etype = getSpec (type);
1532 /* if this is an array & already */
1533 /* an address then return this */
1534 if (IS_AGGREGATE (type) ||
1535 (IS_PTR (type) && !force && !op->isaddr))
1536 return operandFromOperand (op);
1538 /* if this is not an address then must be */
1539 /* rvalue already so return this one */
1543 /* if this is not a temp symbol then */
1544 if (!IS_ITEMP (op) &&
1546 !IN_FARSPACE (SPEC_OCLS (etype)))
1548 op = operandFromOperand (op);
1553 if (IS_SPEC (type) &&
1554 IS_TRUE_SYMOP (op) &&
1555 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1556 /* TARGET_IS_DS390)) */
1557 (options.model == MODEL_FLAT24) ))
1559 op = operandFromOperand (op);
1564 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1565 if (IS_PTR (type) && op->isaddr && force)
1568 type = copyLinkChain (type);
1570 IC_RESULT (ic) = newiTempOperand (type, 1);
1571 IC_RESULT (ic)->isaddr = 0;
1573 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1575 /* if the right is a symbol */
1576 if (op->type == SYMBOL)
1577 IC_RESULT (ic)->operand.symOperand->args =
1578 op->operand.symOperand->args;
1581 return IC_RESULT (ic);
1584 /*-----------------------------------------------------------------*/
1585 /* geniCodeCast - changes the value from one type to another */
1586 /*-----------------------------------------------------------------*/
1588 geniCodeCast (sym_link * type, operand * op, bool implicit)
1592 sym_link *opetype = getSpec (optype = operandType (op));
1596 /* one of them has size zero then error */
1597 if (IS_VOID (optype))
1599 werror (E_CAST_ZERO);
1603 /* if the operand is already the desired type then do nothing */
1604 if (compareType (type, optype) == 1)
1607 /* if this is a literal then just change the type & return */
1608 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1609 return operandFromValue (valCastLiteral (type,
1610 operandLitValue (op)));
1612 /* if casting to/from pointers, do some checking */
1613 if (IS_PTR(type)) { // to a pointer
1614 if (!IS_PTR(optype) && !IS_FUNC(optype)) { // from a non pointer
1615 if (IS_INTEGRAL(optype)) {
1616 // maybe this is NULL, than it's ok.
1617 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1618 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1619 // no way to set the storage
1620 if (IS_LITERAL(optype)) {
1621 werror(E_LITERAL_GENERIC);
1624 werror(E_NONPTR2_GENPTR);
1627 } else if (implicit) {
1628 werror(W_INTEGRAL2PTR_NOCAST);
1633 // shouldn't do that with float, array or structure unless to void
1634 if (!IS_VOID(getSpec(type)) &&
1635 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1636 werror(E_INCOMPAT_TYPES);
1640 } else { // from a pointer to a pointer
1641 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1642 // if not a pointer to a function
1643 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1644 if (implicit) { // if not to generic, they have to match
1645 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1646 werror(E_INCOMPAT_PTYPES);
1653 } else { // to a non pointer
1654 if (IS_PTR(optype)) { // from a pointer
1655 if (implicit) { // sneaky
1656 if (IS_INTEGRAL(type)) {
1657 werror(W_PTR2INTEGRAL_NOCAST);
1659 } else { // shouldn't do that with float, array or structure
1660 werror(E_INCOMPAT_TYPES);
1667 /* fprintf (stderr, "%s%s %d: ", op->operand.symOperand->name,
1668 implicit?"(implicit)":"", errors); */
1669 fprintf (stderr, "from type '");
1670 printTypeChain (optype, stderr);
1671 fprintf (stderr, "' to type '");
1672 printTypeChain (type, stderr);
1673 fprintf (stderr, "'\n");
1676 /* if they are the same size create an assignment */
1677 if (getSize (type) == getSize (optype) &&
1678 !IS_BITFIELD (type) &&
1680 !IS_FLOAT (optype) &&
1681 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1682 (!IS_SPEC (type) && !IS_SPEC (optype))))
1685 ic = newiCode ('=', NULL, op);
1686 IC_RESULT (ic) = newiTempOperand (type, 0);
1687 SPIL_LOC (IC_RESULT (ic)) =
1688 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1689 IC_RESULT (ic)->isaddr = 0;
1693 ic = newiCode (CAST, operandFromLink (type),
1694 geniCodeRValue (op, FALSE));
1696 IC_RESULT (ic) = newiTempOperand (type, 0);
1699 /* preserve the storage class & output class */
1700 /* of the original variable */
1701 restype = getSpec (operandType (IC_RESULT (ic)));
1702 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1703 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1706 return IC_RESULT (ic);
1709 /*-----------------------------------------------------------------*/
1710 /* geniCodeLabel - will create a Label */
1711 /*-----------------------------------------------------------------*/
1713 geniCodeLabel (symbol * label)
1717 ic = newiCodeLabelGoto (LABEL, label);
1721 /*-----------------------------------------------------------------*/
1722 /* geniCodeGoto - will create a Goto */
1723 /*-----------------------------------------------------------------*/
1725 geniCodeGoto (symbol * label)
1729 ic = newiCodeLabelGoto (GOTO, label);
1733 /*-----------------------------------------------------------------*/
1734 /* geniCodeMultiply - gen intermediate code for multiplication */
1735 /*-----------------------------------------------------------------*/
1737 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1744 /* if they are both literal then we know the result */
1745 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1746 return operandFromValue (valMult (left->operand.valOperand,
1747 right->operand.valOperand));
1749 if (IS_LITERAL(retype)) {
1750 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1753 resType = usualBinaryConversions (&left, &right);
1755 rtype = operandType (right);
1756 retype = getSpec (rtype);
1757 ltype = operandType (left);
1758 letype = getSpec (ltype);
1762 SPEC_NOUN(getSpec(resType))=V_INT;
1765 /* if the right is a literal & power of 2 */
1766 /* then make it a left shift */
1767 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1768 efficient in most cases than 2 bytes result = 2 bytes << literal
1769 if port has 1 byte muldiv */
1770 if (p2 && !IS_FLOAT (letype) &&
1771 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1772 (port->support.muldiv == 1)))
1774 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1776 /* LEFT_OP need same size for left and result, */
1777 left = geniCodeCast (resType, left, TRUE);
1778 ltype = operandType (left);
1780 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1784 ic = newiCode ('*', left, right); /* normal multiplication */
1785 /* if the size left or right > 1 then support routine */
1786 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1790 IC_RESULT (ic) = newiTempOperand (resType, 1);
1793 return IC_RESULT (ic);
1796 /*-----------------------------------------------------------------*/
1797 /* geniCodeDivision - gen intermediate code for division */
1798 /*-----------------------------------------------------------------*/
1800 geniCodeDivision (operand * left, operand * right)
1805 sym_link *rtype = operandType (right);
1806 sym_link *retype = getSpec (rtype);
1807 sym_link *ltype = operandType (left);
1808 sym_link *letype = getSpec (ltype);
1810 resType = usualBinaryConversions (&left, &right);
1812 /* if the right is a literal & power of 2 */
1813 /* then make it a right shift */
1814 if (IS_LITERAL (retype) &&
1815 !IS_FLOAT (letype) &&
1816 (p2 = powof2 ((unsigned long)
1817 floatFromVal (right->operand.valOperand)))) {
1818 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1822 ic = newiCode ('/', left, right); /* normal division */
1823 /* if the size left or right > 1 then support routine */
1824 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1827 IC_RESULT (ic) = newiTempOperand (resType, 0);
1830 return IC_RESULT (ic);
1832 /*-----------------------------------------------------------------*/
1833 /* geniCodeModulus - gen intermediate code for modulus */
1834 /*-----------------------------------------------------------------*/
1836 geniCodeModulus (operand * left, operand * right)
1842 /* if they are both literal then we know the result */
1843 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1844 return operandFromValue (valMod (left->operand.valOperand,
1845 right->operand.valOperand));
1847 resType = usualBinaryConversions (&left, &right);
1849 /* now they are the same size */
1850 ic = newiCode ('%', left, right);
1852 /* if the size left or right > 1 then support routine */
1853 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1855 IC_RESULT (ic) = newiTempOperand (resType, 0);
1858 return IC_RESULT (ic);
1861 /*-----------------------------------------------------------------*/
1862 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1863 /*-----------------------------------------------------------------*/
1865 geniCodePtrPtrSubtract (operand * left, operand * right)
1871 /* if they are both literals then */
1872 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1874 result = operandFromValue (valMinus (left->operand.valOperand,
1875 right->operand.valOperand));
1879 ic = newiCode ('-', left, right);
1881 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1885 return geniCodeDivision (result,
1886 operandFromLit (getSize (ltype->next)));
1889 /*-----------------------------------------------------------------*/
1890 /* geniCodeSubtract - generates code for subtraction */
1891 /*-----------------------------------------------------------------*/
1893 geniCodeSubtract (operand * left, operand * right)
1900 /* if they both pointers then */
1901 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1902 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1903 return geniCodePtrPtrSubtract (left, right);
1905 /* if they are both literal then we know the result */
1906 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1907 && left->isLiteral && right->isLiteral)
1908 return operandFromValue (valMinus (left->operand.valOperand,
1909 right->operand.valOperand));
1911 /* if left is an array or pointer */
1912 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1914 isarray = left->isaddr;
1915 right = geniCodeMultiply (right,
1916 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1917 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1920 { /* make them the same size */
1921 resType = usualBinaryConversions (&left, &right);
1924 ic = newiCode ('-', left, right);
1926 IC_RESULT (ic) = newiTempOperand (resType, 1);
1927 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1929 /* if left or right is a float */
1930 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1934 return IC_RESULT (ic);
1937 /*-----------------------------------------------------------------*/
1938 /* geniCodeAdd - generates iCode for addition */
1939 /*-----------------------------------------------------------------*/
1941 geniCodeAdd (operand * left, operand * right,int lvl)
1949 /* if left is an array then array access */
1950 if (IS_ARRAY (ltype))
1951 return geniCodeArray (left, right,lvl);
1953 /* if the right side is LITERAL zero */
1954 /* return the left side */
1955 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1958 /* if left is literal zero return right */
1959 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1962 /* if left is an array or pointer then size */
1965 isarray = left->isaddr;
1966 // there is no need to multiply with 1
1967 if (getSize(ltype->next)!=1) {
1968 size = operandFromLit (getSize (ltype->next));
1969 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1971 resType = copyLinkChain (ltype);
1974 { /* make them the same size */
1975 resType = usualBinaryConversions (&left, &right);
1978 /* if they are both literals then we know */
1979 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1980 && left->isLiteral && right->isLiteral)
1981 return operandFromValue (valPlus (valFromType (letype),
1982 valFromType (retype)));
1984 ic = newiCode ('+', left, right);
1986 IC_RESULT (ic) = newiTempOperand (resType, 1);
1987 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1989 /* if left or right is a float then support
1991 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1996 return IC_RESULT (ic);
2000 /*-----------------------------------------------------------------*/
2001 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2002 /*-----------------------------------------------------------------*/
2004 aggrToPtr (sym_link * type, bool force)
2010 if (IS_PTR (type) && !force)
2013 etype = getSpec (type);
2017 /* if the output class is generic */
2018 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2019 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2021 /* if the variable was declared a constant */
2022 /* then the pointer points to a constant */
2023 if (IS_CONSTANT (etype))
2024 DCL_PTR_CONST (ptype) = 1;
2026 /* the variable was volatile then pointer to volatile */
2027 if (IS_VOLATILE (etype))
2028 DCL_PTR_VOLATILE (ptype) = 1;
2032 /*-----------------------------------------------------------------*/
2033 /* geniCodeArray2Ptr - array to pointer */
2034 /*-----------------------------------------------------------------*/
2036 geniCodeArray2Ptr (operand * op)
2038 sym_link *optype = operandType (op);
2039 sym_link *opetype = getSpec (optype);
2041 /* set the pointer depending on the storage class */
2042 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2043 DCL_PTR_CONST (optype) = port->mem.code_ro;
2046 /* if the variable was declared a constant */
2047 /* then the pointer points to a constant */
2048 if (IS_CONSTANT (opetype))
2049 DCL_PTR_CONST (optype) = 1;
2051 /* the variable was volatile then pointer to volatile */
2052 if (IS_VOLATILE (opetype))
2053 DCL_PTR_VOLATILE (optype) = 1;
2059 /*-----------------------------------------------------------------*/
2060 /* geniCodeArray - array access */
2061 /*-----------------------------------------------------------------*/
2063 geniCodeArray (operand * left, operand * right,int lvl)
2066 sym_link *ltype = operandType (left);
2070 if (IS_PTR (ltype->next) && left->isaddr)
2072 left = geniCodeRValue (left, FALSE);
2074 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
2077 right = geniCodeMultiply (right,
2078 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2080 /* we can check for limits here */
2081 if (isOperandLiteral (right) &&
2084 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2086 werror (E_ARRAY_BOUND);
2087 right = operandFromLit (0);
2090 ic = newiCode ('+', left, right);
2092 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2093 !IS_AGGREGATE (ltype->next) &&
2094 !IS_PTR (ltype->next))
2095 ? ltype : ltype->next), 0);
2097 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2099 return IC_RESULT (ic);
2102 /*-----------------------------------------------------------------*/
2103 /* geniCodeStruct - generates intermediate code for structres */
2104 /*-----------------------------------------------------------------*/
2106 geniCodeStruct (operand * left, operand * right, bool islval)
2109 sym_link *type = operandType (left);
2110 sym_link *etype = getSpec (type);
2112 symbol *element = getStructElement (SPEC_STRUCT (etype),
2113 right->operand.symOperand);
2115 /* add the offset */
2116 ic = newiCode ('+', left, operandFromLit (element->offset));
2118 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2120 /* preserve the storage & output class of the struct */
2121 /* as well as the volatile attribute */
2122 retype = getSpec (operandType (IC_RESULT (ic)));
2123 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2124 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2125 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2127 if (IS_PTR (element->type))
2128 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2130 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2134 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2137 /*-----------------------------------------------------------------*/
2138 /* geniCodePostInc - generate int code for Post increment */
2139 /*-----------------------------------------------------------------*/
2141 geniCodePostInc (operand * op)
2145 sym_link *optype = operandType (op);
2147 operand *rv = (IS_ITEMP (op) ?
2148 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2150 sym_link *rvtype = operandType (rv);
2153 /* if this is not an address we have trouble */
2156 werror (E_LVALUE_REQUIRED, "++");
2160 rOp = newiTempOperand (rvtype, 0);
2161 OP_SYMBOL(rOp)->noSpilLoc = 1;
2164 OP_SYMBOL(rv)->noSpilLoc = 1;
2166 geniCodeAssign (rOp, rv, 0);
2168 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2169 if (IS_FLOAT (rvtype))
2170 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2172 ic = newiCode ('+', rv, operandFromLit (size));
2174 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2177 geniCodeAssign (op, result, 0);
2183 /*-----------------------------------------------------------------*/
2184 /* geniCodePreInc - generate code for preIncrement */
2185 /*-----------------------------------------------------------------*/
2187 geniCodePreInc (operand * op)
2190 sym_link *optype = operandType (op);
2191 operand *rop = (IS_ITEMP (op) ?
2192 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2194 sym_link *roptype = operandType (rop);
2200 werror (E_LVALUE_REQUIRED, "++");
2205 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2206 if (IS_FLOAT (roptype))
2207 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2209 ic = newiCode ('+', rop, operandFromLit (size));
2210 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2214 return geniCodeAssign (op, result, 0);
2217 /*-----------------------------------------------------------------*/
2218 /* geniCodePostDec - generates code for Post decrement */
2219 /*-----------------------------------------------------------------*/
2221 geniCodePostDec (operand * op)
2225 sym_link *optype = operandType (op);
2227 operand *rv = (IS_ITEMP (op) ?
2228 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2230 sym_link *rvtype = operandType (rv);
2233 /* if this is not an address we have trouble */
2236 werror (E_LVALUE_REQUIRED, "--");
2240 rOp = newiTempOperand (rvtype, 0);
2241 OP_SYMBOL(rOp)->noSpilLoc = 1;
2244 OP_SYMBOL(rv)->noSpilLoc = 1;
2246 geniCodeAssign (rOp, rv, 0);
2248 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2249 if (IS_FLOAT (rvtype))
2250 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2252 ic = newiCode ('-', rv, operandFromLit (size));
2254 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2257 geniCodeAssign (op, result, 0);
2263 /*-----------------------------------------------------------------*/
2264 /* geniCodePreDec - generate code for pre decrement */
2265 /*-----------------------------------------------------------------*/
2267 geniCodePreDec (operand * op)
2270 sym_link *optype = operandType (op);
2271 operand *rop = (IS_ITEMP (op) ?
2272 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2274 sym_link *roptype = operandType (rop);
2280 werror (E_LVALUE_REQUIRED, "--");
2285 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2286 if (IS_FLOAT (roptype))
2287 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2289 ic = newiCode ('-', rop, operandFromLit (size));
2290 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2294 return geniCodeAssign (op, result, 0);
2298 /*-----------------------------------------------------------------*/
2299 /* geniCodeBitwise - gen int code for bitWise operators */
2300 /*-----------------------------------------------------------------*/
2302 geniCodeBitwise (operand * left, operand * right,
2303 int oper, sym_link * resType)
2307 left = geniCodeCast (resType, left, TRUE);
2308 right = geniCodeCast (resType, right, TRUE);
2310 ic = newiCode (oper, left, right);
2311 IC_RESULT (ic) = newiTempOperand (resType, 0);
2314 return IC_RESULT (ic);
2317 /*-----------------------------------------------------------------*/
2318 /* geniCodeAddressOf - gens icode for '&' address of operator */
2319 /*-----------------------------------------------------------------*/
2321 geniCodeAddressOf (operand * op)
2325 sym_link *optype = operandType (op);
2326 sym_link *opetype = getSpec (optype);
2328 /* lvalue check already done in decorateType */
2329 /* this must be a lvalue */
2330 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2331 /* werror (E_LVALUE_REQUIRED,"&"); */
2336 p->class = DECLARATOR;
2338 /* set the pointer depending on the storage class */
2339 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2340 DCL_PTR_CONST (p) = port->mem.code_ro;
2342 /* make sure we preserve the const & volatile */
2343 if (IS_CONSTANT (opetype))
2344 DCL_PTR_CONST (p) = 1;
2346 if (IS_VOLATILE (opetype))
2347 DCL_PTR_VOLATILE (p) = 1;
2349 p->next = copyLinkChain (optype);
2351 /* if already a temp */
2354 setOperandType (op, p);
2359 /* other wise make this of the type coming in */
2360 ic = newiCode (ADDRESS_OF, op, NULL);
2361 IC_RESULT (ic) = newiTempOperand (p, 1);
2362 IC_RESULT (ic)->isaddr = 0;
2364 return IC_RESULT (ic);
2366 /*-----------------------------------------------------------------*/
2367 /* setOClass - sets the output class depending on the pointer type */
2368 /*-----------------------------------------------------------------*/
2370 setOClass (sym_link * ptr, sym_link * spec)
2372 switch (DCL_TYPE (ptr))
2375 SPEC_OCLS (spec) = data;
2379 SPEC_OCLS (spec) = generic;
2383 SPEC_OCLS (spec) = xdata;
2387 SPEC_OCLS (spec) = code;
2391 SPEC_OCLS (spec) = idata;
2395 SPEC_OCLS (spec) = xstack;
2399 SPEC_OCLS (spec) = eeprom;
2408 /*-----------------------------------------------------------------*/
2409 /* geniCodeDerefPtr - dereference pointer with '*' */
2410 /*-----------------------------------------------------------------*/
2412 geniCodeDerefPtr (operand * op,int lvl)
2414 sym_link *rtype, *retype;
2415 sym_link *optype = operandType (op);
2417 /* if this is a pointer then generate the rvalue */
2418 if (IS_PTR (optype))
2420 if (IS_TRUE_SYMOP (op))
2423 op = geniCodeRValue (op, TRUE);
2426 op = geniCodeRValue (op, TRUE);
2429 /* now get rid of the pointer part */
2430 if (isLvaluereq(lvl) && IS_ITEMP (op))
2432 retype = getSpec (rtype = copyLinkChain (optype));
2436 retype = getSpec (rtype = copyLinkChain (optype->next));
2439 /* if this is a pointer then outputclass needs 2b updated */
2440 if (IS_PTR (optype))
2441 setOClass (optype, retype);
2443 op->isGptr = IS_GENPTR (optype);
2445 /* if the pointer was declared as a constant */
2446 /* then we cannot allow assignment to the derefed */
2447 if (IS_PTR_CONST (optype))
2448 SPEC_CONST (retype) = 1;
2450 op->isaddr = (IS_PTR (rtype) ||
2451 IS_STRUCT (rtype) ||
2456 if (!isLvaluereq(lvl))
2457 op = geniCodeRValue (op, TRUE);
2459 setOperandType (op, rtype);
2464 /*-----------------------------------------------------------------*/
2465 /* geniCodeUnaryMinus - does a unary minus of the operand */
2466 /*-----------------------------------------------------------------*/
2468 geniCodeUnaryMinus (operand * op)
2471 sym_link *optype = operandType (op);
2473 if (IS_LITERAL (optype))
2474 return operandFromLit (-floatFromVal (op->operand.valOperand));
2476 ic = newiCode (UNARYMINUS, op, NULL);
2477 IC_RESULT (ic) = newiTempOperand (optype, 0);
2479 return IC_RESULT (ic);
2482 /*-----------------------------------------------------------------*/
2483 /* geniCodeLeftShift - gen i code for left shift */
2484 /*-----------------------------------------------------------------*/
2486 geniCodeLeftShift (operand * left, operand * right)
2490 ic = newiCode (LEFT_OP, left, right);
2491 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2493 return IC_RESULT (ic);
2496 /*-----------------------------------------------------------------*/
2497 /* geniCodeRightShift - gen i code for right shift */
2498 /*-----------------------------------------------------------------*/
2500 geniCodeRightShift (operand * left, operand * right)
2504 ic = newiCode (RIGHT_OP, left, right);
2505 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2507 return IC_RESULT (ic);
2510 /*-----------------------------------------------------------------*/
2511 /* geniCodeLogic- logic code */
2512 /*-----------------------------------------------------------------*/
2514 geniCodeLogic (operand * left, operand * right, int op)
2518 sym_link *rtype = operandType (right);
2519 sym_link *ltype = operandType (left);
2521 /* left is integral type and right is literal then
2522 check if the literal value is within bounds */
2523 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2525 checkConstantRange(ltype,
2526 OP_VALUE(right), "compare operation", 1);
2529 ctype = usualBinaryConversions (&left, &right);
2531 ic = newiCode (op, left, right);
2532 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2534 /* if comparing float
2535 and not a '==' || '!=' || '&&' || '||' (these
2537 if (IS_FLOAT(ctype) &&
2545 return IC_RESULT (ic);
2548 /*-----------------------------------------------------------------*/
2549 /* geniCodeUnary - for a a generic unary operation */
2550 /*-----------------------------------------------------------------*/
2552 geniCodeUnary (operand * op, int oper)
2554 iCode *ic = newiCode (oper, op, NULL);
2556 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2558 return IC_RESULT (ic);
2561 /*-----------------------------------------------------------------*/
2562 /* geniCodeConditional - geniCode for '?' ':' operation */
2563 /*-----------------------------------------------------------------*/
2565 geniCodeConditional (ast * tree,int lvl)
2568 symbol *falseLabel = newiTempLabel (NULL);
2569 symbol *exitLabel = newiTempLabel (NULL);
2570 operand *cond = ast2iCode (tree->left,lvl+1);
2571 operand *true, *false, *result;
2573 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2577 true = ast2iCode (tree->right->left,lvl+1);
2579 /* move the value to a new Operand */
2580 result = newiTempOperand (operandType (true), 0);
2581 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2583 /* generate an unconditional goto */
2584 geniCodeGoto (exitLabel);
2586 /* now for the right side */
2587 geniCodeLabel (falseLabel);
2589 false = ast2iCode (tree->right->right,lvl+1);
2590 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2592 /* create the exit label */
2593 geniCodeLabel (exitLabel);
2598 /*-----------------------------------------------------------------*/
2599 /* geniCodeAssign - generate code for assignment */
2600 /*-----------------------------------------------------------------*/
2602 geniCodeAssign (operand * left, operand * right, int nosupdate)
2605 sym_link *ltype = operandType (left);
2606 sym_link *rtype = operandType (right);
2608 if (!left->isaddr && !IS_ITEMP (left))
2610 werror (E_LVALUE_REQUIRED, "assignment");
2614 /* left is integral type and right is literal then
2615 check if the literal value is within bounds */
2616 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2618 checkConstantRange(ltype,
2619 OP_VALUE(right), "= operation", 0);
2622 /* if the left & right type don't exactly match */
2623 /* if pointer set then make sure the check is
2624 done with the type & not the pointer */
2625 /* then cast rights type to left */
2627 /* first check the type for pointer assignement */
2628 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2629 compareType (ltype, rtype) < 0)
2631 if (compareType (ltype->next, rtype) < 0)
2632 right = geniCodeCast (ltype->next, right, TRUE);
2634 else if (compareType (ltype, rtype) < 0)
2635 right = geniCodeCast (ltype, right, TRUE);
2637 /* if left is a true symbol & ! volatile
2638 create an assignment to temporary for
2639 the right & then assign this temporary
2640 to the symbol this is SSA . isn't it simple
2641 and folks have published mountains of paper on it */
2642 if (IS_TRUE_SYMOP (left) &&
2643 !isOperandVolatile (left, FALSE) &&
2644 isOperandGlobal (left))
2648 if (IS_TRUE_SYMOP (right))
2649 sym = OP_SYMBOL (right);
2650 ic = newiCode ('=', NULL, right);
2651 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2652 SPIL_LOC (right) = sym;
2656 ic = newiCode ('=', NULL, right);
2657 IC_RESULT (ic) = left;
2660 /* if left isgptr flag is set then support
2661 routine will be required */
2665 ic->nosupdate = nosupdate;
2669 /*-----------------------------------------------------------------*/
2670 /* geniCodeSEParms - generate code for side effecting fcalls */
2671 /*-----------------------------------------------------------------*/
2673 geniCodeSEParms (ast * parms,int lvl)
2678 if (parms->type == EX_OP && parms->opval.op == PARAM)
2680 geniCodeSEParms (parms->left,lvl);
2681 geniCodeSEParms (parms->right,lvl);
2685 /* hack don't like this but too lazy to think of
2687 if (IS_ADDRESS_OF_OP (parms))
2688 parms->left->lvalue = 1;
2690 if (IS_CAST_OP (parms) &&
2691 IS_PTR (parms->ftype) &&
2692 IS_ADDRESS_OF_OP (parms->right))
2693 parms->right->left->lvalue = 1;
2695 parms->opval.oprnd =
2696 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2698 parms->type = EX_OPERAND;
2701 /*-----------------------------------------------------------------*/
2702 /* geniCodeParms - generates parameters */
2703 /*-----------------------------------------------------------------*/
2705 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl)
2713 /* if this is a param node then do the left & right */
2714 if (parms->type == EX_OP && parms->opval.op == PARAM)
2716 geniCodeParms (parms->left, stack, fetype, func,lvl);
2717 geniCodeParms (parms->right, stack, fetype, func,lvl);
2721 /* get the parameter value */
2722 if (parms->type == EX_OPERAND)
2723 pval = parms->opval.oprnd;
2726 /* maybe this else should go away ?? */
2727 /* hack don't like this but too lazy to think of
2729 if (IS_ADDRESS_OF_OP (parms))
2730 parms->left->lvalue = 1;
2732 if (IS_CAST_OP (parms) &&
2733 IS_PTR (parms->ftype) &&
2734 IS_ADDRESS_OF_OP (parms->right))
2735 parms->right->left->lvalue = 1;
2737 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2740 /* if register parm then make it a send */
2741 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2742 IS_REGPARM (parms->etype)) && !func->hasVargs)
2744 ic = newiCode (SEND, pval, NULL);
2749 /* now decide whether to push or assign */
2750 if (!(options.stackAuto || IS_RENT (fetype)))
2754 operand *top = operandFromSymbol (parms->argSym);
2755 geniCodeAssign (top, pval, 1);
2759 sym_link *p = operandType (pval);
2761 ic = newiCode (IPUSH, pval, NULL);
2763 /* update the stack adjustment */
2764 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2771 /*-----------------------------------------------------------------*/
2772 /* geniCodeCall - generates temp code for calling */
2773 /*-----------------------------------------------------------------*/
2775 geniCodeCall (operand * left, ast * parms,int lvl)
2779 sym_link *type, *etype;
2782 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2783 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2784 werror (E_FUNCTION_EXPECTED);
2788 /* take care of parameters with side-effecting
2789 function calls in them, this is required to take care
2790 of overlaying function parameters */
2791 geniCodeSEParms (parms,lvl);
2793 /* first the parameters */
2794 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2796 /* now call : if symbol then pcall */
2797 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2798 ic = newiCode (PCALL, left, NULL);
2800 ic = newiCode (CALL, left, NULL);
2802 IC_ARGS (ic) = left->operand.symOperand->args;
2803 type = copyLinkChain (operandType (left)->next);
2804 etype = getSpec (type);
2805 SPEC_EXTR (etype) = 0;
2806 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2810 /* stack adjustment after call */
2811 ic->parmBytes = stack;
2816 /*-----------------------------------------------------------------*/
2817 /* geniCodeReceive - generate intermediate code for "receive" */
2818 /*-----------------------------------------------------------------*/
2820 geniCodeReceive (value * args)
2822 /* for all arguments that are passed in registers */
2826 if (IS_REGPARM (args->etype))
2828 operand *opr = operandFromValue (args);
2830 symbol *sym = OP_SYMBOL (opr);
2833 /* we will use it after all optimizations
2834 and before liveRange calculation */
2835 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2838 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2839 options.stackAuto == 0 &&
2840 /* !TARGET_IS_DS390) */
2841 (!(options.model == MODEL_FLAT24)) )
2846 opl = newiTempOperand (args->type, 0);
2848 sym->reqv->key = sym->key;
2849 OP_SYMBOL (sym->reqv)->key = sym->key;
2850 OP_SYMBOL (sym->reqv)->isreqv = 1;
2851 OP_SYMBOL (sym->reqv)->islocal = 0;
2852 SPIL_LOC (sym->reqv) = sym;
2856 ic = newiCode (RECEIVE, NULL, NULL);
2857 currFunc->recvSize = getSize (sym->etype);
2858 IC_RESULT (ic) = opr;
2866 /*-----------------------------------------------------------------*/
2867 /* geniCodeFunctionBody - create the function body */
2868 /*-----------------------------------------------------------------*/
2870 geniCodeFunctionBody (ast * tree,int lvl)
2877 /* reset the auto generation */
2883 func = ast2iCode (tree->left,lvl+1);
2884 fetype = getSpec (operandType (func));
2886 savelineno = lineno;
2887 lineno = OP_SYMBOL (func)->lineDef;
2888 /* create an entry label */
2889 geniCodeLabel (entryLabel);
2890 lineno = savelineno;
2892 /* create a proc icode */
2893 ic = newiCode (FUNCTION, func, NULL);
2894 /* if the function has parmas then */
2895 /* save the parameters information */
2896 ic->argLabel.args = tree->values.args;
2897 ic->lineno = OP_SYMBOL (func)->lineDef;
2901 /* for all parameters that are passed
2902 on registers add a "receive" */
2903 geniCodeReceive (tree->values.args);
2905 /* generate code for the body */
2906 ast2iCode (tree->right,lvl+1);
2908 /* create a label for return */
2909 geniCodeLabel (returnLabel);
2911 /* now generate the end proc */
2912 ic = newiCode (ENDFUNCTION, func, NULL);
2917 /*-----------------------------------------------------------------*/
2918 /* geniCodeReturn - gen icode for 'return' statement */
2919 /*-----------------------------------------------------------------*/
2921 geniCodeReturn (operand * op)
2925 /* if the operand is present force an rvalue */
2927 op = geniCodeRValue (op, FALSE);
2929 ic = newiCode (RETURN, op, NULL);
2933 /*-----------------------------------------------------------------*/
2934 /* geniCodeIfx - generates code for extended if statement */
2935 /*-----------------------------------------------------------------*/
2937 geniCodeIfx (ast * tree,int lvl)
2940 operand *condition = ast2iCode (tree->left,lvl+1);
2943 /* if condition is null then exit */
2947 condition = geniCodeRValue (condition, FALSE);
2949 cetype = getSpec (operandType (condition));
2950 /* if the condition is a literal */
2951 if (IS_LITERAL (cetype))
2953 if (floatFromVal (condition->operand.valOperand))
2955 if (tree->trueLabel)
2956 geniCodeGoto (tree->trueLabel);
2962 if (tree->falseLabel)
2963 geniCodeGoto (tree->falseLabel);
2970 if (tree->trueLabel)
2972 ic = newiCodeCondition (condition,
2977 if (tree->falseLabel)
2978 geniCodeGoto (tree->falseLabel);
2982 ic = newiCodeCondition (condition,
2989 ast2iCode (tree->right,lvl+1);
2992 /*-----------------------------------------------------------------*/
2993 /* geniCodeJumpTable - tries to create a jump table for switch */
2994 /*-----------------------------------------------------------------*/
2996 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2998 int min = 0, max = 0, t, cnt = 0;
3005 if (!tree || !caseVals)
3008 /* the criteria for creating a jump table is */
3009 /* all integer numbers between the maximum & minimum must */
3010 /* be present , the maximum value should not exceed 255 */
3011 min = max = (int) floatFromVal (vch = caseVals);
3012 sprintf (buffer, "_case_%d_%d",
3013 tree->values.switchVals.swNum,
3015 addSet (&labels, newiTempLabel (buffer));
3017 /* if there is only one case value then no need */
3018 if (!(vch = vch->next))
3023 if (((t = (int) floatFromVal (vch)) - max) != 1)
3025 sprintf (buffer, "_case_%d_%d",
3026 tree->values.switchVals.swNum,
3028 addSet (&labels, newiTempLabel (buffer));
3034 /* if the number of case statements <= 2 then */
3035 /* it is not economical to create the jump table */
3036 /* since two compares are needed for boundary conditions */
3037 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3040 if (tree->values.switchVals.swDefault)
3041 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3043 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3045 falseLabel = newiTempLabel (buffer);
3047 /* so we can create a jumptable */
3048 /* first we rule out the boundary conditions */
3049 /* if only optimization says so */
3050 if (!optimize.noJTabBoundary)
3052 sym_link *cetype = getSpec (operandType (cond));
3053 /* no need to check the lower bound if
3054 the condition is unsigned & minimum value is zero */
3055 if (!(min == 0 && SPEC_USIGN (cetype)))
3057 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3058 ic = newiCodeCondition (boundary, falseLabel, NULL);
3062 /* now for upper bounds */
3063 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3064 ic = newiCodeCondition (boundary, falseLabel, NULL);
3068 /* if the min is not zero then we no make it zero */
3071 cond = geniCodeSubtract (cond, operandFromLit (min));
3072 setOperandType (cond, UCHARTYPE);
3075 /* now create the jumptable */
3076 ic = newiCode (JUMPTABLE, NULL, NULL);
3077 IC_JTCOND (ic) = cond;
3078 IC_JTLABELS (ic) = labels;
3083 /*-----------------------------------------------------------------*/
3084 /* geniCodeSwitch - changes a switch to a if statement */
3085 /*-----------------------------------------------------------------*/
3087 geniCodeSwitch (ast * tree,int lvl)
3090 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3091 value *caseVals = tree->values.switchVals.swVals;
3092 symbol *trueLabel, *falseLabel;
3094 /* if we can make this a jump table */
3095 if (geniCodeJumpTable (cond, caseVals, tree))
3096 goto jumpTable; /* no need for the comparison */
3098 /* for the cases defined do */
3102 operand *compare = geniCodeLogic (cond,
3103 operandFromValue (caseVals),
3106 sprintf (buffer, "_case_%d_%d",
3107 tree->values.switchVals.swNum,
3108 (int) floatFromVal (caseVals));
3109 trueLabel = newiTempLabel (buffer);
3111 ic = newiCodeCondition (compare, trueLabel, NULL);
3113 caseVals = caseVals->next;
3118 /* if default is present then goto break else break */
3119 if (tree->values.switchVals.swDefault)
3120 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3122 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3124 falseLabel = newiTempLabel (buffer);
3125 geniCodeGoto (falseLabel);
3128 ast2iCode (tree->right,lvl+1);
3131 /*-----------------------------------------------------------------*/
3132 /* geniCodeInline - intermediate code for inline assembler */
3133 /*-----------------------------------------------------------------*/
3135 geniCodeInline (ast * tree)
3139 ic = newiCode (INLINEASM, NULL, NULL);
3140 IC_INLINE (ic) = tree->values.inlineasm;
3144 /*-----------------------------------------------------------------*/
3145 /* geniCodeArrayInit - intermediate code for array initializer */
3146 /*-----------------------------------------------------------------*/
3148 geniCodeArrayInit (ast * tree, operand *array)
3152 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3153 ic = newiCode (ARRAYINIT, array, NULL);
3154 IC_ARRAYILIST (ic) = tree->values.constlist;
3156 operand *left=newOperand(), *right=newOperand();
3157 left->type=right->type=SYMBOL;
3158 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3159 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3160 ic = newiCode (ARRAYINIT, left, right);
3165 /*-----------------------------------------------------------------*/
3166 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3167 /* particular case. Ie : assigning or dereferencing array or ptr */
3168 /*-----------------------------------------------------------------*/
3169 set * lvaluereqSet = NULL;
3170 typedef struct lvalItem
3177 /*-----------------------------------------------------------------*/
3178 /* addLvaluereq - add a flag for lvalreq for current ast level */
3179 /*-----------------------------------------------------------------*/
3180 void addLvaluereq(int lvl)
3182 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3185 addSetHead(&lvaluereqSet,lpItem);
3188 /*-----------------------------------------------------------------*/
3189 /* delLvaluereq - del a flag for lvalreq for current ast level */
3190 /*-----------------------------------------------------------------*/
3194 lpItem = getSet(&lvaluereqSet);
3195 if(lpItem) Safe_free(lpItem);
3197 /*-----------------------------------------------------------------*/
3198 /* clearLvaluereq - clear lvalreq flag */
3199 /*-----------------------------------------------------------------*/
3200 void clearLvaluereq()
3203 lpItem = peekSet(lvaluereqSet);
3204 if(lpItem) lpItem->req = 0;
3206 /*-----------------------------------------------------------------*/
3207 /* getLvaluereq - get the last lvalreq level */
3208 /*-----------------------------------------------------------------*/
3209 int getLvaluereqLvl()
3212 lpItem = peekSet(lvaluereqSet);
3213 if(lpItem) return lpItem->lvl;
3216 /*-----------------------------------------------------------------*/
3217 /* isLvaluereq - is lvalreq valid for this level ? */
3218 /*-----------------------------------------------------------------*/
3219 int isLvaluereq(int lvl)
3222 lpItem = peekSet(lvaluereqSet);
3223 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3227 /*-----------------------------------------------------------------*/
3228 /* ast2iCode - creates an icodeList from an ast */
3229 /*-----------------------------------------------------------------*/
3231 ast2iCode (ast * tree,int lvl)
3233 operand *left = NULL;
3234 operand *right = NULL;
3237 /* set the global variables for filename & line number */
3239 filename = tree->filename;
3241 lineno = tree->lineno;
3243 block = tree->block;
3245 scopeLevel = tree->level;
3247 if (tree->type == EX_VALUE)
3248 return operandFromValue (tree->opval.val);
3250 if (tree->type == EX_LINK)
3251 return operandFromLink (tree->opval.lnk);
3253 /* if we find a nullop */
3254 if (tree->type == EX_OP &&
3255 (tree->opval.op == NULLOP ||
3256 tree->opval.op == BLOCK))
3258 ast2iCode (tree->left,lvl+1);
3259 ast2iCode (tree->right,lvl+1);
3263 /* special cases for not evaluating */
3264 if (tree->opval.op != ':' &&
3265 tree->opval.op != '?' &&
3266 tree->opval.op != CALL &&
3267 tree->opval.op != IFX &&
3268 tree->opval.op != LABEL &&
3269 tree->opval.op != GOTO &&
3270 tree->opval.op != SWITCH &&
3271 tree->opval.op != FUNCTION &&
3272 tree->opval.op != INLINEASM)
3275 if (IS_ASSIGN_OP (tree->opval.op) ||
3276 IS_DEREF_OP (tree) ||
3277 (tree->opval.op == '&' && !tree->right) ||
3278 tree->opval.op == PTR_OP)
3281 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3282 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3285 left = operandFromAst (tree->left,lvl);
3287 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3288 left = geniCodeRValue (left, TRUE);
3292 left = operandFromAst (tree->left,lvl);
3294 if (tree->opval.op == INC_OP ||
3295 tree->opval.op == DEC_OP)
3298 right = operandFromAst (tree->right,lvl);
3303 right = operandFromAst (tree->right,lvl);
3307 /* now depending on the type of operand */
3308 /* this will be a biggy */
3309 switch (tree->opval.op)
3312 case '[': /* array operation */
3314 //sym_link *ltype = operandType (left);
3315 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3316 left = geniCodeRValue (left, FALSE);
3317 right = geniCodeRValue (right, TRUE);
3320 return geniCodeArray (left, right,lvl);
3322 case '.': /* structure dereference */
3323 if (IS_PTR (operandType (left)))
3324 left = geniCodeRValue (left, TRUE);
3326 left = geniCodeRValue (left, FALSE);
3328 return geniCodeStruct (left, right, tree->lvalue);
3330 case PTR_OP: /* structure pointer dereference */
3333 pType = operandType (left);
3334 left = geniCodeRValue (left, TRUE);
3336 setOClass (pType, getSpec (operandType (left)));
3339 return geniCodeStruct (left, right, tree->lvalue);
3341 case INC_OP: /* increment operator */
3343 return geniCodePostInc (left);
3345 return geniCodePreInc (right);
3347 case DEC_OP: /* decrement operator */
3349 return geniCodePostDec (left);
3351 return geniCodePreDec (right);
3353 case '&': /* bitwise and or address of operator */
3355 { /* this is a bitwise operator */
3356 left = geniCodeRValue (left, FALSE);
3357 right = geniCodeRValue (right, FALSE);
3358 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3361 return geniCodeAddressOf (left);
3363 case '|': /* bitwise or & xor */
3365 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3366 geniCodeRValue (right, FALSE),
3371 return geniCodeDivision (geniCodeRValue (left, FALSE),
3372 geniCodeRValue (right, FALSE));
3375 return geniCodeModulus (geniCodeRValue (left, FALSE),
3376 geniCodeRValue (right, FALSE));
3379 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3380 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3382 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3386 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3387 geniCodeRValue (right, FALSE));
3389 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3393 return geniCodeAdd (geniCodeRValue (left, FALSE),
3394 geniCodeRValue (right, FALSE),lvl);
3396 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3399 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3400 geniCodeRValue (right, FALSE));
3403 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3404 geniCodeRValue (right, FALSE));
3406 return geniCodeCast (operandType (left),
3407 geniCodeRValue (right, FALSE), FALSE);
3413 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3417 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3418 setOperandType (op, UCHARTYPE);
3429 return geniCodeLogic (geniCodeRValue (left, FALSE),
3430 geniCodeRValue (right, FALSE),
3433 return geniCodeConditional (tree,lvl);
3436 return operandFromLit (getSize (tree->right->ftype));
3440 sym_link *rtype = operandType (right);
3441 sym_link *ltype = operandType (left);
3442 if (IS_PTR (rtype) && IS_ITEMP (right)
3443 && right->isaddr && compareType (rtype->next, ltype) == 1)
3444 right = geniCodeRValue (right, TRUE);
3446 right = geniCodeRValue (right, FALSE);
3448 geniCodeAssign (left, right, 0);
3453 geniCodeAssign (left,
3454 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3456 geniCodeRValue (right, FALSE),FALSE), 0);
3460 geniCodeAssign (left,
3461 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3463 geniCodeRValue (right, FALSE)), 0);
3466 geniCodeAssign (left,
3467 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3469 geniCodeRValue (right, FALSE)), 0);
3472 sym_link *rtype = operandType (right);
3473 sym_link *ltype = operandType (left);
3474 if (IS_PTR (rtype) && IS_ITEMP (right)
3475 && right->isaddr && compareType (rtype->next, ltype) == 1)
3476 right = geniCodeRValue (right, TRUE);
3478 right = geniCodeRValue (right, FALSE);
3481 return geniCodeAssign (left,
3482 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3488 sym_link *rtype = operandType (right);
3489 sym_link *ltype = operandType (left);
3490 if (IS_PTR (rtype) && IS_ITEMP (right)
3491 && right->isaddr && compareType (rtype->next, ltype) == 1)
3493 right = geniCodeRValue (right, TRUE);
3497 right = geniCodeRValue (right, FALSE);
3500 geniCodeAssign (left,
3501 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3507 geniCodeAssign (left,
3508 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3510 geniCodeRValue (right, FALSE)), 0);
3513 geniCodeAssign (left,
3514 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3516 geniCodeRValue (right, FALSE)), 0);
3519 geniCodeAssign (left,
3520 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3522 geniCodeRValue (right, FALSE),
3524 operandType (left)), 0);
3527 geniCodeAssign (left,
3528 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3530 geniCodeRValue (right, FALSE),
3532 operandType (left)), 0);
3535 geniCodeAssign (left,
3536 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3538 geniCodeRValue (right, FALSE),
3540 operandType (left)), 0);
3542 return geniCodeRValue (right, FALSE);
3545 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3548 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3549 return ast2iCode (tree->right,lvl+1);
3552 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3553 return ast2iCode (tree->right,lvl+1);
3556 geniCodeFunctionBody (tree,lvl);
3560 geniCodeReturn (right);
3564 geniCodeIfx (tree,lvl);
3568 geniCodeSwitch (tree,lvl);
3572 geniCodeInline (tree);
3576 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3583 /*-----------------------------------------------------------------*/
3584 /* reverseICChain - gets from the list and creates a linkedlist */
3585 /*-----------------------------------------------------------------*/
3592 while ((loop = getSet (&iCodeChain)))
3604 /*-----------------------------------------------------------------*/
3605 /* iCodeFromAst - given an ast will convert it to iCode */
3606 /*-----------------------------------------------------------------*/
3608 iCodeFromAst (ast * tree)
3610 returnLabel = newiTempLabel ("_return");
3611 entryLabel = newiTempLabel ("_entry");
3613 return reverseiCChain ();