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}", /*{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
234 printTypeChain (operandType (op), file);
235 if (SPIL_LOC (op) && IS_ITEMP (op))
236 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
241 /* if assigned to registers */
242 if (OP_SYMBOL (op)->nRegs)
244 if (OP_SYMBOL (op)->isspilt)
246 if (!OP_SYMBOL (op)->remat)
247 if (OP_SYMBOL (op)->usl.spillLoc)
248 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
249 OP_SYMBOL (op)->usl.spillLoc->rname :
250 OP_SYMBOL (op)->usl.spillLoc->name));
252 fprintf (file, "[err]");
254 fprintf (file, "[remat]");
260 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
261 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
266 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
267 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
268 /* if assigned to registers */
269 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
273 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
274 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
275 OP_SYMBOL (op)->regs[i]->name :
284 printTypeChain (op->operand.typeOperand, file);
290 fprintf (file, "\n");
295 /*-----------------------------------------------------------------*/
296 /* print functions */
297 /*-----------------------------------------------------------------*/
298 PRINTFUNC (picGetValueAtAddr)
301 printOperand (IC_RESULT (ic), of);
304 printOperand (IC_LEFT (ic), of);
310 PRINTFUNC (picSetValueAtAddr)
314 printOperand (IC_LEFT (ic), of);
315 fprintf (of, "] = ");
316 printOperand (IC_RIGHT (ic), of);
320 PRINTFUNC (picAddrOf)
323 printOperand (IC_RESULT (ic), of);
324 if (IS_ITEMP (IC_LEFT (ic)))
327 fprintf (of, " = &[");
328 printOperand (IC_LEFT (ic), of);
331 if (IS_ITEMP (IC_LEFT (ic)))
332 fprintf (of, " offsetAdd ");
335 printOperand (IC_RIGHT (ic), of);
337 if (IS_ITEMP (IC_LEFT (ic)))
343 PRINTFUNC (picJumpTable)
348 fprintf (of, "%s\t", s);
349 printOperand (IC_JTCOND (ic), of);
351 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
352 sym = setNextItem (IC_JTLABELS (ic)))
353 fprintf (of, "\t\t\t%s\n", sym->name);
356 PRINTFUNC (picGeneric)
359 printOperand (IC_RESULT (ic), of);
361 printOperand (IC_LEFT (ic), of);
362 fprintf (of, " %s ", s);
363 printOperand (IC_RIGHT (ic), of);
367 PRINTFUNC (picGenericOne)
372 printOperand (IC_RESULT (ic), of);
378 fprintf (of, "%s ", s);
379 printOperand (IC_LEFT (ic), of);
382 if (!IC_RESULT (ic) && !IC_LEFT (ic))
391 printOperand (IC_RESULT (ic), of);
393 printOperand (IC_LEFT (ic), of);
394 printOperand (IC_RIGHT (ic), of);
399 PRINTFUNC (picAssign)
403 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
406 printOperand (IC_RESULT (ic), of);
408 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
411 fprintf (of, " %s ", s);
412 printOperand (IC_RIGHT (ic), of);
419 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
425 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
432 printOperand (IC_COND (ic), of);
435 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
438 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
440 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
444 PRINTFUNC (picInline)
446 fprintf (of, "%s", IC_INLINE (ic));
449 PRINTFUNC (picReceive)
451 printOperand (IC_RESULT (ic), of);
452 fprintf (of, " = %s ", s);
453 printOperand (IC_LEFT (ic), of);
457 /*-----------------------------------------------------------------*/
458 /* piCode - prints one iCode */
459 /*-----------------------------------------------------------------*/
461 piCode (void *item, FILE * of)
469 icTab = getTableEntry (ic->op);
470 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
471 ic->filename, ic->lineno,
472 ic->seq, ic->key, ic->depth, ic->supportRtn);
473 icTab->iCodePrint (of, ic, icTab->printName);
479 printiCChain(ic,stdout);
481 /*-----------------------------------------------------------------*/
482 /* printiCChain - prints intermediate code for humans */
483 /*-----------------------------------------------------------------*/
485 printiCChain (iCode * icChain, FILE * of)
492 for (loop = icChain; loop; loop = loop->next)
494 if ((icTab = getTableEntry (loop->op)))
496 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
497 loop->filename, loop->lineno,
498 loop->seq, loop->key, loop->depth, loop->supportRtn);
500 icTab->iCodePrint (of, loop, icTab->printName);
506 /*-----------------------------------------------------------------*/
507 /* newOperand - allocate, init & return a new iCode */
508 /*-----------------------------------------------------------------*/
514 op = Safe_alloc ( sizeof (operand));
520 /*-----------------------------------------------------------------*/
521 /* newiCode - create and return a new iCode entry initialised */
522 /*-----------------------------------------------------------------*/
524 newiCode (int op, operand * left, operand * right)
528 ic = Safe_alloc ( sizeof (iCode));
531 ic->filename = filename;
533 ic->level = scopeLevel;
535 ic->key = iCodeKey++;
537 IC_RIGHT (ic) = right;
542 /*-----------------------------------------------------------------*/
543 /* newiCode for conditional statements */
544 /*-----------------------------------------------------------------*/
546 newiCodeCondition (operand * condition,
552 if (IS_VOID(operandType(condition))) {
553 werror(E_VOID_VALUE_USED);
556 ic = newiCode (IFX, NULL, NULL);
557 IC_COND (ic) = condition;
558 IC_TRUE (ic) = trueLabel;
559 IC_FALSE (ic) = falseLabel;
563 /*-----------------------------------------------------------------*/
564 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
565 /*-----------------------------------------------------------------*/
567 newiCodeLabelGoto (int op, symbol * label)
571 ic = newiCode (op, NULL, NULL);
573 ic->argLabel.label = label;
575 IC_RIGHT (ic) = NULL;
576 IC_RESULT (ic) = NULL;
580 /*-----------------------------------------------------------------*/
581 /* newiTemp - allocate & return a newItemp Variable */
582 /*-----------------------------------------------------------------*/
589 sprintf (buffer, "%s", s);
591 sprintf (buffer, "iTemp%d", iTempNum++);
592 itmp = newSymbol (buffer, 1);
593 strcpy (itmp->rname, itmp->name);
599 /*-----------------------------------------------------------------*/
600 /* newiTempLabel - creates a temp variable label */
601 /*-----------------------------------------------------------------*/
603 newiTempLabel (char *s)
607 /* check if this alredy exists */
608 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
612 itmplbl = newSymbol (s, 1);
615 sprintf (buffer, "iTempLbl%d", iTempLblNum++);
616 itmplbl = newSymbol (buffer, 1);
621 itmplbl->key = labelKey++;
622 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
626 /*-----------------------------------------------------------------*/
627 /* newiTempPreheaderLabel - creates a new preheader label */
628 /*-----------------------------------------------------------------*/
630 newiTempPreheaderLabel ()
634 sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
635 itmplbl = newSymbol (buffer, 1);
639 itmplbl->key = labelKey++;
640 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
645 /*-----------------------------------------------------------------*/
646 /* initiCode - initialises some iCode related stuff */
647 /*-----------------------------------------------------------------*/
654 /*-----------------------------------------------------------------*/
655 /* copyiCode - make a copy of the iCode given */
656 /*-----------------------------------------------------------------*/
658 copyiCode (iCode * ic)
660 iCode *nic = newiCode (ic->op, NULL, NULL);
662 nic->lineno = ic->lineno;
663 nic->filename = ic->filename;
664 nic->block = ic->block;
665 nic->level = ic->level;
666 nic->parmBytes = ic->parmBytes;
668 /* deal with the special cases first */
672 IC_COND (nic) = operandFromOperand (IC_COND (ic));
673 IC_TRUE (nic) = IC_TRUE (ic);
674 IC_FALSE (nic) = IC_FALSE (ic);
678 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
679 IC_JTLABELS (nic) = IC_JTLABELS (ic);
684 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
685 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
686 IC_ARGS (nic) = IC_ARGS (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))
861 /*-----------------------------------------------------------------*/
862 /* isOperandInFarSpace - will return true if operand is in farSpace */
863 /*-----------------------------------------------------------------*/
865 isOperandInFarSpace (operand * op)
875 if (!IS_TRUE_SYMOP (op))
878 etype = SPIL_LOC (op)->etype;
884 etype = getSpec (operandType (op));
886 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
889 /*-----------------------------------------------------------------*/
890 /* isOperandOnStack - will return true if operand is on stack */
891 /*-----------------------------------------------------------------*/
893 isOperandOnStack (operand * op)
903 etype = getSpec (operandType (op));
905 return ((IN_STACK (etype)) ? TRUE : FALSE);
908 /*-----------------------------------------------------------------*/
909 /* operandLitValue - literal value of an operand */
910 /*-----------------------------------------------------------------*/
912 operandLitValue (operand * op)
914 assert (isOperandLiteral (op));
916 return floatFromVal (op->operand.valOperand);
919 /*-----------------------------------------------------------------*/
920 /* operandOperation - perforoms operations on operands */
921 /*-----------------------------------------------------------------*/
923 operandOperation (operand * left, operand * right,
924 int op, sym_link * type)
926 sym_link *let , *ret=NULL;
927 operand *retval = (operand *) 0;
929 assert (isOperandLiteral (left));
930 let = getSpec(operandType(left));
932 assert (isOperandLiteral (right));
933 ret = getSpec(operandType(left));
939 retval = operandFromValue (valCastLiteral (type,
940 operandLitValue (left) +
941 operandLitValue (right)));
944 retval = operandFromValue (valCastLiteral (type,
945 operandLitValue (left) -
946 operandLitValue (right)));
949 retval = operandFromValue (valCastLiteral (type,
950 operandLitValue (left) *
951 operandLitValue (right)));
954 if ((unsigned long) operandLitValue (right) == 0)
956 werror (E_DIVIDE_BY_ZERO);
961 retval = operandFromValue (valCastLiteral (type,
962 operandLitValue (left) /
963 operandLitValue (right)));
966 if ((unsigned long) operandLitValue (right) == 0) {
967 werror (E_DIVIDE_BY_ZERO);
971 retval = operandFromLit ((SPEC_USIGN(let) ?
972 (unsigned long) operandLitValue (left) :
973 (long) operandLitValue (left)) %
975 (unsigned long) operandLitValue (right) :
976 (long) operandLitValue (right)));
980 retval = operandFromLit ((SPEC_USIGN(let) ?
981 (unsigned long) operandLitValue (left) :
982 (long) operandLitValue (left)) <<
984 (unsigned long) operandLitValue (right) :
985 (long) operandLitValue (right)));
988 retval = operandFromLit ((SPEC_USIGN(let) ?
989 (unsigned long) operandLitValue (left) :
990 (long) operandLitValue (left)) >>
992 (unsigned long) operandLitValue (right) :
993 (long) 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 (operandLitValue (left) !=
1009 operandLitValue (right));
1012 retval = operandFromLit (operandLitValue (left) >
1013 operandLitValue (right));
1016 retval = operandFromLit (operandLitValue (left) >=
1017 operandLitValue (right));
1020 retval = operandFromLit ((long)operandLitValue(left) &
1021 (long)operandLitValue(right));
1024 retval = operandFromLit ((long)operandLitValue (left) |
1025 (long)operandLitValue (right));
1028 retval = operandFromLit ((long)operandLitValue (left) ^
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 (!(options.model == MODEL_FLAT24)) ) &&
1270 options.stackAuto == 0)
1273 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1274 !IS_FUNC (sym->type) && /* not a function */
1275 !sym->_isparm && /* not a parameter */
1276 sym->level && /* is a local variable */
1277 !sym->addrtaken && /* whose address has not been taken */
1278 !sym->reqv && /* does not already have a register euivalence */
1279 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1280 !IS_STATIC (sym->etype) && /* and not declared static */
1281 !sym->islbl && /* not a label */
1282 ok && /* farspace check */
1283 !IS_BITVAR (sym->etype) /* not a bit variable */
1287 /* we will use it after all optimizations
1288 and before liveRange calculation */
1289 sym->reqv = newiTempOperand (sym->type, 0);
1290 sym->reqv->key = sym->key;
1291 OP_SYMBOL (sym->reqv)->key = sym->key;
1292 OP_SYMBOL (sym->reqv)->isreqv = 1;
1293 OP_SYMBOL (sym->reqv)->islocal = 1;
1294 SPIL_LOC (sym->reqv) = sym;
1297 if (!IS_AGGREGATE (sym->type))
1301 op->operand.symOperand = sym;
1304 op->isvolatile = isOperandVolatile (op, TRUE);
1305 op->isGlobal = isOperandGlobal (op);
1306 op->isPtr = IS_PTR (operandType (op));
1307 op->isParm = sym->_isparm;
1312 /* itemp = &[_symbol] */
1314 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1315 IC_LEFT (ic)->type = SYMBOL;
1316 IC_LEFT (ic)->operand.symOperand = sym;
1317 IC_LEFT (ic)->key = sym->key;
1318 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1319 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1320 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1323 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1324 if (IS_ARRAY (sym->type))
1326 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1327 IC_RESULT (ic)->isaddr = 0;
1330 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1334 return IC_RESULT (ic);
1337 /*-----------------------------------------------------------------*/
1338 /* operandFromValue - creates an operand from value */
1339 /*-----------------------------------------------------------------*/
1341 operandFromValue (value * val)
1345 /* if this is a symbol then do the symbol thing */
1347 return operandFromSymbol (val->sym);
1349 /* this is not a symbol */
1352 op->operand.valOperand = val;
1353 op->isLiteral = isOperandLiteral (op);
1357 /*-----------------------------------------------------------------*/
1358 /* operandFromLink - operand from typeChain */
1359 /*-----------------------------------------------------------------*/
1361 operandFromLink (sym_link * type)
1365 /* operand from sym_link */
1371 op->operand.typeOperand = copyLinkChain (type);
1375 /*-----------------------------------------------------------------*/
1376 /* operandFromLit - makes an operand from a literal value */
1377 /*-----------------------------------------------------------------*/
1379 operandFromLit (double i)
1381 return operandFromValue (valueFromLit (i));
1384 /*-----------------------------------------------------------------*/
1385 /* operandFromAst - creates an operand from an ast */
1386 /*-----------------------------------------------------------------*/
1388 operandFromAst (ast * tree,int lvl)
1394 /* depending on type do */
1398 return ast2iCode (tree,lvl+1);
1402 return operandFromValue (tree->opval.val);
1406 return operandFromLink (tree->opval.lnk);
1410 /* Just to keep the comiler happy */
1411 return (operand *) 0;
1414 /*-----------------------------------------------------------------*/
1415 /* setOperandType - sets the operand's type to the given type */
1416 /*-----------------------------------------------------------------*/
1418 setOperandType (operand * op, sym_link * type)
1420 /* depending on the type of operand */
1425 op->operand.valOperand->etype =
1426 getSpec (op->operand.valOperand->type =
1427 copyLinkChain (type));
1431 if (op->operand.symOperand->isitmp)
1432 op->operand.symOperand->etype =
1433 getSpec (op->operand.symOperand->type =
1434 copyLinkChain (type));
1436 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1437 "attempt to modify type of source");
1441 op->operand.typeOperand = copyLinkChain (type);
1446 /*-----------------------------------------------------------------*/
1447 /* Get size in byte of ptr need to access an array */
1448 /*-----------------------------------------------------------------*/
1450 getArraySizePtr (operand * op)
1452 sym_link *ltype = operandType(op);
1456 int size = getSize(ltype);
1457 return(IS_GENPTR(ltype)?(size-1):size);
1462 sym_link *letype = getSpec(ltype);
1463 switch (PTR_TYPE (SPEC_OCLS (letype)))
1475 return (GPTRSIZE-1);
1484 /*-----------------------------------------------------------------*/
1485 /* perform "usual unary conversions" */
1486 /*-----------------------------------------------------------------*/
1488 usualUnaryConversions (operand * op)
1490 if (IS_INTEGRAL (operandType (op)))
1492 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1495 return geniCodeCast (INTTYPE, op, TRUE);
1501 /*-----------------------------------------------------------------*/
1502 /* perform "usual binary conversions" */
1503 /*-----------------------------------------------------------------*/
1505 usualBinaryConversions (operand ** op1, operand ** op2)
1508 sym_link *rtype = operandType (*op2);
1509 sym_link *ltype = operandType (*op1);
1511 ctype = computeType (ltype, rtype);
1512 *op1 = geniCodeCast (ctype, *op1, TRUE);
1513 *op2 = geniCodeCast (ctype, *op2, TRUE);
1518 /*-----------------------------------------------------------------*/
1519 /* geniCodeValueAtAddress - generate intermeditate code for value */
1521 /*-----------------------------------------------------------------*/
1523 geniCodeRValue (operand * op, bool force)
1526 sym_link *type = operandType (op);
1527 sym_link *etype = getSpec (type);
1529 /* if this is an array & already */
1530 /* an address then return this */
1531 if (IS_AGGREGATE (type) ||
1532 (IS_PTR (type) && !force && !op->isaddr))
1533 return operandFromOperand (op);
1535 /* if this is not an address then must be */
1536 /* rvalue already so return this one */
1540 /* if this is not a temp symbol then */
1541 if (!IS_ITEMP (op) &&
1543 !IN_FARSPACE (SPEC_OCLS (etype)))
1545 op = operandFromOperand (op);
1550 if (IS_SPEC (type) &&
1551 IS_TRUE_SYMOP (op) &&
1552 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1553 /* TARGET_IS_DS390)) */
1554 (options.model == MODEL_FLAT24) ))
1556 op = operandFromOperand (op);
1561 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1562 if (IS_PTR (type) && op->isaddr && force)
1565 type = copyLinkChain (type);
1567 IC_RESULT (ic) = newiTempOperand (type, 1);
1568 IC_RESULT (ic)->isaddr = 0;
1570 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1574 return IC_RESULT (ic);
1577 /*-----------------------------------------------------------------*/
1578 /* geniCodeCast - changes the value from one type to another */
1579 /*-----------------------------------------------------------------*/
1581 geniCodeCast (sym_link * type, operand * op, bool implicit)
1585 sym_link *opetype = getSpec (optype = operandType (op));
1589 /* one of them has size zero then error */
1590 if (IS_VOID (optype))
1592 werror (E_CAST_ZERO);
1596 /* if the operand is already the desired type then do nothing */
1597 if (compareType (type, optype) == 1)
1600 /* if this is a literal then just change the type & return */
1601 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1602 return operandFromValue (valCastLiteral (type,
1603 operandLitValue (op)));
1605 /* if casting to/from pointers, do some checking */
1606 if (IS_PTR(type)) { // to a pointer
1607 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1608 if (IS_INTEGRAL(optype)) {
1609 // maybe this is NULL, than it's ok.
1610 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1611 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1612 // no way to set the storage
1613 if (IS_LITERAL(optype)) {
1614 werror(E_LITERAL_GENERIC);
1617 werror(E_NONPTR2_GENPTR);
1620 } else if (implicit) {
1621 werror(W_INTEGRAL2PTR_NOCAST);
1626 // shouldn't do that with float, array or structure unless to void
1627 if (!IS_VOID(getSpec(type)) &&
1628 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1629 werror(E_INCOMPAT_TYPES);
1633 } else { // from a pointer to a pointer
1634 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1635 // if not a pointer to a function
1636 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1637 if (implicit) { // if not to generic, they have to match
1638 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1639 werror(E_INCOMPAT_PTYPES);
1646 } else { // to a non pointer
1647 if (IS_PTR(optype)) { // from a pointer
1648 if (implicit) { // sneaky
1649 if (IS_INTEGRAL(type)) {
1650 werror(W_PTR2INTEGRAL_NOCAST);
1652 } else { // shouldn't do that with float, array or structure
1653 werror(E_INCOMPAT_TYPES);
1660 /* fprintf (stderr, "%s%s %d: ", op->operand.symOperand->name,
1661 implicit?"(implicit)":"", errors); */
1662 fprintf (stderr, "from type '");
1663 printTypeChain (optype, stderr);
1664 fprintf (stderr, "' to type '");
1665 printTypeChain (type, stderr);
1666 fprintf (stderr, "'\n");
1669 /* if they are the same size create an assignment */
1670 if (getSize (type) == getSize (optype) &&
1671 !IS_BITFIELD (type) &&
1673 !IS_FLOAT (optype) &&
1674 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1675 (!IS_SPEC (type) && !IS_SPEC (optype))))
1678 ic = newiCode ('=', NULL, op);
1679 IC_RESULT (ic) = newiTempOperand (type, 0);
1680 SPIL_LOC (IC_RESULT (ic)) =
1681 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1682 IC_RESULT (ic)->isaddr = 0;
1686 ic = newiCode (CAST, operandFromLink (type),
1687 geniCodeRValue (op, FALSE));
1689 IC_RESULT (ic) = newiTempOperand (type, 0);
1692 /* preserve the storage class & output class */
1693 /* of the original variable */
1694 restype = getSpec (operandType (IC_RESULT (ic)));
1695 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1696 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1699 return IC_RESULT (ic);
1702 /*-----------------------------------------------------------------*/
1703 /* geniCodeLabel - will create a Label */
1704 /*-----------------------------------------------------------------*/
1706 geniCodeLabel (symbol * label)
1710 ic = newiCodeLabelGoto (LABEL, label);
1714 /*-----------------------------------------------------------------*/
1715 /* geniCodeGoto - will create a Goto */
1716 /*-----------------------------------------------------------------*/
1718 geniCodeGoto (symbol * label)
1722 ic = newiCodeLabelGoto (GOTO, label);
1726 /*-----------------------------------------------------------------*/
1727 /* geniCodeMultiply - gen intermediate code for multiplication */
1728 /*-----------------------------------------------------------------*/
1730 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1737 /* if they are both literal then we know the result */
1738 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1739 return operandFromValue (valMult (left->operand.valOperand,
1740 right->operand.valOperand));
1742 if (IS_LITERAL(retype)) {
1743 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1746 resType = usualBinaryConversions (&left, &right);
1748 rtype = operandType (right);
1749 retype = getSpec (rtype);
1750 ltype = operandType (left);
1751 letype = getSpec (ltype);
1755 SPEC_NOUN(getSpec(resType))=V_INT;
1758 /* if the right is a literal & power of 2 */
1759 /* then make it a left shift */
1760 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1761 efficient in most cases than 2 bytes result = 2 bytes << literal
1762 if port has 1 byte muldiv */
1763 if (p2 && !IS_FLOAT (letype) &&
1764 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1765 (port->support.muldiv == 1)))
1767 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1769 /* LEFT_OP need same size for left and result, */
1770 left = geniCodeCast (resType, left, TRUE);
1771 ltype = operandType (left);
1773 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1777 ic = newiCode ('*', left, right); /* normal multiplication */
1778 /* if the size left or right > 1 then support routine */
1779 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1783 IC_RESULT (ic) = newiTempOperand (resType, 1);
1786 return IC_RESULT (ic);
1789 /*-----------------------------------------------------------------*/
1790 /* geniCodeDivision - gen intermediate code for division */
1791 /*-----------------------------------------------------------------*/
1793 geniCodeDivision (operand * left, operand * right)
1798 sym_link *rtype = operandType (right);
1799 sym_link *retype = getSpec (rtype);
1800 sym_link *ltype = operandType (left);
1801 sym_link *letype = getSpec (ltype);
1803 resType = usualBinaryConversions (&left, &right);
1805 /* if the right is a literal & power of 2 */
1806 /* then make it a right shift */
1807 if (IS_LITERAL (retype) &&
1808 !IS_FLOAT (letype) &&
1809 (p2 = powof2 ((unsigned long)
1810 floatFromVal (right->operand.valOperand)))) {
1811 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1815 ic = newiCode ('/', left, right); /* normal division */
1816 /* if the size left or right > 1 then support routine */
1817 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1820 IC_RESULT (ic) = newiTempOperand (resType, 0);
1823 return IC_RESULT (ic);
1825 /*-----------------------------------------------------------------*/
1826 /* geniCodeModulus - gen intermediate code for modulus */
1827 /*-----------------------------------------------------------------*/
1829 geniCodeModulus (operand * left, operand * right)
1835 /* if they are both literal then we know the result */
1836 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1837 return operandFromValue (valMod (left->operand.valOperand,
1838 right->operand.valOperand));
1840 resType = usualBinaryConversions (&left, &right);
1842 /* now they are the same size */
1843 ic = newiCode ('%', left, right);
1845 /* if the size left or right > 1 then support routine */
1846 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1848 IC_RESULT (ic) = newiTempOperand (resType, 0);
1851 return IC_RESULT (ic);
1854 /*-----------------------------------------------------------------*/
1855 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1856 /*-----------------------------------------------------------------*/
1858 geniCodePtrPtrSubtract (operand * left, operand * right)
1864 /* if they are both literals then */
1865 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1867 result = operandFromValue (valMinus (left->operand.valOperand,
1868 right->operand.valOperand));
1872 ic = newiCode ('-', left, right);
1874 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1878 return geniCodeDivision (result,
1879 operandFromLit (getSize (ltype->next)));
1882 /*-----------------------------------------------------------------*/
1883 /* geniCodeSubtract - generates code for subtraction */
1884 /*-----------------------------------------------------------------*/
1886 geniCodeSubtract (operand * left, operand * right)
1893 /* if they both pointers then */
1894 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1895 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1896 return geniCodePtrPtrSubtract (left, right);
1898 /* if they are both literal then we know the result */
1899 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1900 && left->isLiteral && right->isLiteral)
1901 return operandFromValue (valMinus (left->operand.valOperand,
1902 right->operand.valOperand));
1904 /* if left is an array or pointer */
1905 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1907 isarray = left->isaddr;
1908 right = geniCodeMultiply (right,
1909 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1910 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1913 { /* make them the same size */
1914 resType = usualBinaryConversions (&left, &right);
1917 ic = newiCode ('-', left, right);
1919 IC_RESULT (ic) = newiTempOperand (resType, 1);
1920 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1922 /* if left or right is a float */
1923 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1927 return IC_RESULT (ic);
1930 /*-----------------------------------------------------------------*/
1931 /* geniCodeAdd - generates iCode for addition */
1932 /*-----------------------------------------------------------------*/
1934 geniCodeAdd (operand * left, operand * right,int lvl)
1942 /* if left is an array then array access */
1943 if (IS_ARRAY (ltype))
1944 return geniCodeArray (left, right,lvl);
1946 /* if the right side is LITERAL zero */
1947 /* return the left side */
1948 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1951 /* if left is literal zero return right */
1952 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1955 /* if left is an array or pointer then size */
1958 isarray = left->isaddr;
1959 // there is no need to multiply with 1
1960 if (getSize(ltype->next)!=1) {
1961 size = operandFromLit (getSize (ltype->next));
1962 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1964 resType = copyLinkChain (ltype);
1967 { /* make them the same size */
1968 resType = usualBinaryConversions (&left, &right);
1971 /* if they are both literals then we know */
1972 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1973 && left->isLiteral && right->isLiteral)
1974 return operandFromValue (valPlus (valFromType (letype),
1975 valFromType (retype)));
1977 ic = newiCode ('+', left, right);
1979 IC_RESULT (ic) = newiTempOperand (resType, 1);
1980 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1982 /* if left or right is a float then support
1984 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1989 return IC_RESULT (ic);
1993 /*-----------------------------------------------------------------*/
1994 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1995 /*-----------------------------------------------------------------*/
1997 aggrToPtr (sym_link * type, bool force)
2003 if (IS_PTR (type) && !force)
2006 etype = getSpec (type);
2010 /* if the output class is generic */
2011 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2012 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2014 /* if the variable was declared a constant */
2015 /* then the pointer points to a constant */
2016 if (IS_CONSTANT (etype))
2017 DCL_PTR_CONST (ptype) = 1;
2019 /* the variable was volatile then pointer to volatile */
2020 if (IS_VOLATILE (etype))
2021 DCL_PTR_VOLATILE (ptype) = 1;
2025 /*-----------------------------------------------------------------*/
2026 /* geniCodeArray2Ptr - array to pointer */
2027 /*-----------------------------------------------------------------*/
2029 geniCodeArray2Ptr (operand * op)
2031 sym_link *optype = operandType (op);
2032 sym_link *opetype = getSpec (optype);
2034 /* set the pointer depending on the storage class */
2035 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2036 DCL_PTR_CONST (optype) = port->mem.code_ro;
2039 /* if the variable was declared a constant */
2040 /* then the pointer points to a constant */
2041 if (IS_CONSTANT (opetype))
2042 DCL_PTR_CONST (optype) = 1;
2044 /* the variable was volatile then pointer to volatile */
2045 if (IS_VOLATILE (opetype))
2046 DCL_PTR_VOLATILE (optype) = 1;
2052 /*-----------------------------------------------------------------*/
2053 /* geniCodeArray - array access */
2054 /*-----------------------------------------------------------------*/
2056 geniCodeArray (operand * left, operand * right,int lvl)
2059 sym_link *ltype = operandType (left);
2063 if (IS_PTR (ltype->next) && left->isaddr)
2065 left = geniCodeRValue (left, FALSE);
2067 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
2070 right = geniCodeMultiply (right,
2071 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2073 /* we can check for limits here */
2074 if (isOperandLiteral (right) &&
2077 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2079 werror (E_ARRAY_BOUND);
2080 right = operandFromLit (0);
2083 ic = newiCode ('+', left, right);
2085 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2086 !IS_AGGREGATE (ltype->next) &&
2087 !IS_PTR (ltype->next))
2088 ? ltype : ltype->next), 0);
2090 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2092 return IC_RESULT (ic);
2095 /*-----------------------------------------------------------------*/
2096 /* geniCodeStruct - generates intermediate code for structres */
2097 /*-----------------------------------------------------------------*/
2099 geniCodeStruct (operand * left, operand * right, bool islval)
2102 sym_link *type = operandType (left);
2103 sym_link *etype = getSpec (type);
2105 symbol *element = getStructElement (SPEC_STRUCT (etype),
2106 right->operand.symOperand);
2108 /* add the offset */
2109 ic = newiCode ('+', left, operandFromLit (element->offset));
2111 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2113 /* preserve the storage & output class of the struct */
2114 /* as well as the volatile attribute */
2115 retype = getSpec (operandType (IC_RESULT (ic)));
2116 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2117 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2118 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2120 if (IS_PTR (element->type))
2121 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2123 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2127 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2130 /*-----------------------------------------------------------------*/
2131 /* geniCodePostInc - generate int code for Post increment */
2132 /*-----------------------------------------------------------------*/
2134 geniCodePostInc (operand * op)
2138 sym_link *optype = operandType (op);
2140 operand *rv = (IS_ITEMP (op) ?
2141 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2143 sym_link *rvtype = operandType (rv);
2146 /* if this is not an address we have trouble */
2149 werror (E_LVALUE_REQUIRED, "++");
2153 rOp = newiTempOperand (rvtype, 0);
2154 OP_SYMBOL(rOp)->noSpilLoc = 1;
2157 OP_SYMBOL(rv)->noSpilLoc = 1;
2159 geniCodeAssign (rOp, rv, 0);
2161 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2162 if (IS_FLOAT (rvtype))
2163 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2165 ic = newiCode ('+', rv, operandFromLit (size));
2167 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2170 geniCodeAssign (op, result, 0);
2176 /*-----------------------------------------------------------------*/
2177 /* geniCodePreInc - generate code for preIncrement */
2178 /*-----------------------------------------------------------------*/
2180 geniCodePreInc (operand * op)
2183 sym_link *optype = operandType (op);
2184 operand *rop = (IS_ITEMP (op) ?
2185 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2187 sym_link *roptype = operandType (rop);
2193 werror (E_LVALUE_REQUIRED, "++");
2198 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2199 if (IS_FLOAT (roptype))
2200 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2202 ic = newiCode ('+', rop, operandFromLit (size));
2203 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2207 return geniCodeAssign (op, result, 0);
2210 /*-----------------------------------------------------------------*/
2211 /* geniCodePostDec - generates code for Post decrement */
2212 /*-----------------------------------------------------------------*/
2214 geniCodePostDec (operand * op)
2218 sym_link *optype = operandType (op);
2220 operand *rv = (IS_ITEMP (op) ?
2221 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2223 sym_link *rvtype = operandType (rv);
2226 /* if this is not an address we have trouble */
2229 werror (E_LVALUE_REQUIRED, "--");
2233 rOp = newiTempOperand (rvtype, 0);
2234 OP_SYMBOL(rOp)->noSpilLoc = 1;
2237 OP_SYMBOL(rv)->noSpilLoc = 1;
2239 geniCodeAssign (rOp, rv, 0);
2241 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2242 if (IS_FLOAT (rvtype))
2243 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2245 ic = newiCode ('-', rv, operandFromLit (size));
2247 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2250 geniCodeAssign (op, result, 0);
2256 /*-----------------------------------------------------------------*/
2257 /* geniCodePreDec - generate code for pre decrement */
2258 /*-----------------------------------------------------------------*/
2260 geniCodePreDec (operand * op)
2263 sym_link *optype = operandType (op);
2264 operand *rop = (IS_ITEMP (op) ?
2265 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2267 sym_link *roptype = operandType (rop);
2273 werror (E_LVALUE_REQUIRED, "--");
2278 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2279 if (IS_FLOAT (roptype))
2280 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2282 ic = newiCode ('-', rop, operandFromLit (size));
2283 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2287 return geniCodeAssign (op, result, 0);
2291 /*-----------------------------------------------------------------*/
2292 /* geniCodeBitwise - gen int code for bitWise operators */
2293 /*-----------------------------------------------------------------*/
2295 geniCodeBitwise (operand * left, operand * right,
2296 int oper, sym_link * resType)
2300 left = geniCodeCast (resType, left, TRUE);
2301 right = geniCodeCast (resType, right, TRUE);
2303 ic = newiCode (oper, left, right);
2304 IC_RESULT (ic) = newiTempOperand (resType, 0);
2307 return IC_RESULT (ic);
2310 /*-----------------------------------------------------------------*/
2311 /* geniCodeAddressOf - gens icode for '&' address of operator */
2312 /*-----------------------------------------------------------------*/
2314 geniCodeAddressOf (operand * op)
2318 sym_link *optype = operandType (op);
2319 sym_link *opetype = getSpec (optype);
2321 /* lvalue check already done in decorateType */
2322 /* this must be a lvalue */
2323 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2324 /* werror (E_LVALUE_REQUIRED,"&"); */
2329 p->class = DECLARATOR;
2331 /* set the pointer depending on the storage class */
2332 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2333 DCL_PTR_CONST (p) = port->mem.code_ro;
2335 /* make sure we preserve the const & volatile */
2336 if (IS_CONSTANT (opetype))
2337 DCL_PTR_CONST (p) = 1;
2339 if (IS_VOLATILE (opetype))
2340 DCL_PTR_VOLATILE (p) = 1;
2342 p->next = copyLinkChain (optype);
2344 /* if already a temp */
2347 setOperandType (op, p);
2352 /* other wise make this of the type coming in */
2353 ic = newiCode (ADDRESS_OF, op, NULL);
2354 IC_RESULT (ic) = newiTempOperand (p, 1);
2355 IC_RESULT (ic)->isaddr = 0;
2357 return IC_RESULT (ic);
2359 /*-----------------------------------------------------------------*/
2360 /* setOClass - sets the output class depending on the pointer type */
2361 /*-----------------------------------------------------------------*/
2363 setOClass (sym_link * ptr, sym_link * spec)
2365 switch (DCL_TYPE (ptr))
2368 SPEC_OCLS (spec) = data;
2372 SPEC_OCLS (spec) = generic;
2376 SPEC_OCLS (spec) = xdata;
2380 SPEC_OCLS (spec) = code;
2384 SPEC_OCLS (spec) = idata;
2388 SPEC_OCLS (spec) = xstack;
2392 SPEC_OCLS (spec) = eeprom;
2401 /*-----------------------------------------------------------------*/
2402 /* geniCodeDerefPtr - dereference pointer with '*' */
2403 /*-----------------------------------------------------------------*/
2405 geniCodeDerefPtr (operand * op,int lvl)
2407 sym_link *rtype, *retype;
2408 sym_link *optype = operandType (op);
2410 /* if this is a pointer then generate the rvalue */
2411 if (IS_PTR (optype))
2413 if (IS_TRUE_SYMOP (op))
2416 op = geniCodeRValue (op, TRUE);
2419 op = geniCodeRValue (op, TRUE);
2422 /* now get rid of the pointer part */
2423 if (isLvaluereq(lvl) && IS_ITEMP (op))
2425 retype = getSpec (rtype = copyLinkChain (optype));
2429 retype = getSpec (rtype = copyLinkChain (optype->next));
2432 /* if this is a pointer then outputclass needs 2b updated */
2433 if (IS_PTR (optype))
2434 setOClass (optype, retype);
2436 op->isGptr = IS_GENPTR (optype);
2438 /* if the pointer was declared as a constant */
2439 /* then we cannot allow assignment to the derefed */
2440 if (IS_PTR_CONST (optype))
2441 SPEC_CONST (retype) = 1;
2443 op->isaddr = (IS_PTR (rtype) ||
2444 IS_STRUCT (rtype) ||
2449 if (!isLvaluereq(lvl))
2450 op = geniCodeRValue (op, TRUE);
2452 setOperandType (op, rtype);
2457 /*-----------------------------------------------------------------*/
2458 /* geniCodeUnaryMinus - does a unary minus of the operand */
2459 /*-----------------------------------------------------------------*/
2461 geniCodeUnaryMinus (operand * op)
2464 sym_link *optype = operandType (op);
2466 if (IS_LITERAL (optype))
2467 return operandFromLit (-floatFromVal (op->operand.valOperand));
2469 ic = newiCode (UNARYMINUS, op, NULL);
2470 IC_RESULT (ic) = newiTempOperand (optype, 0);
2472 return IC_RESULT (ic);
2475 /*-----------------------------------------------------------------*/
2476 /* geniCodeLeftShift - gen i code for left shift */
2477 /*-----------------------------------------------------------------*/
2479 geniCodeLeftShift (operand * left, operand * right)
2483 ic = newiCode (LEFT_OP, left, right);
2484 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2486 return IC_RESULT (ic);
2489 /*-----------------------------------------------------------------*/
2490 /* geniCodeRightShift - gen i code for right shift */
2491 /*-----------------------------------------------------------------*/
2493 geniCodeRightShift (operand * left, operand * right)
2497 ic = newiCode (RIGHT_OP, left, right);
2498 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2500 return IC_RESULT (ic);
2503 /*-----------------------------------------------------------------*/
2504 /* geniCodeLogic- logic code */
2505 /*-----------------------------------------------------------------*/
2507 geniCodeLogic (operand * left, operand * right, int op)
2511 sym_link *rtype = operandType (right);
2512 sym_link *ltype = operandType (left);
2514 /* left is integral type and right is literal then
2515 check if the literal value is within bounds */
2516 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2518 checkConstantRange(ltype,
2519 OP_VALUE(right), "compare operation", 1);
2522 ctype = usualBinaryConversions (&left, &right);
2524 ic = newiCode (op, left, right);
2525 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2527 /* if comparing float
2528 and not a '==' || '!=' || '&&' || '||' (these
2530 if (IS_FLOAT(ctype) &&
2538 return IC_RESULT (ic);
2541 /*-----------------------------------------------------------------*/
2542 /* geniCodeUnary - for a a generic unary operation */
2543 /*-----------------------------------------------------------------*/
2545 geniCodeUnary (operand * op, int oper)
2547 iCode *ic = newiCode (oper, op, NULL);
2549 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2551 return IC_RESULT (ic);
2554 /*-----------------------------------------------------------------*/
2555 /* geniCodeConditional - geniCode for '?' ':' operation */
2556 /*-----------------------------------------------------------------*/
2558 geniCodeConditional (ast * tree,int lvl)
2561 symbol *falseLabel = newiTempLabel (NULL);
2562 symbol *exitLabel = newiTempLabel (NULL);
2563 operand *cond = ast2iCode (tree->left,lvl+1);
2564 operand *true, *false, *result;
2566 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2570 true = ast2iCode (tree->right->left,lvl+1);
2572 /* move the value to a new Operand */
2573 result = newiTempOperand (operandType (true), 0);
2574 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2576 /* generate an unconditional goto */
2577 geniCodeGoto (exitLabel);
2579 /* now for the right side */
2580 geniCodeLabel (falseLabel);
2582 false = ast2iCode (tree->right->right,lvl+1);
2583 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2585 /* create the exit label */
2586 geniCodeLabel (exitLabel);
2591 /*-----------------------------------------------------------------*/
2592 /* geniCodeAssign - generate code for assignment */
2593 /*-----------------------------------------------------------------*/
2595 geniCodeAssign (operand * left, operand * right, int nosupdate)
2598 sym_link *ltype = operandType (left);
2599 sym_link *rtype = operandType (right);
2601 if (!left->isaddr && !IS_ITEMP (left))
2603 werror (E_LVALUE_REQUIRED, "assignment");
2607 /* left is integral type and right is literal then
2608 check if the literal value is within bounds */
2609 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2611 checkConstantRange(ltype,
2612 OP_VALUE(right), "= operation", 0);
2615 /* if the left & right type don't exactly match */
2616 /* if pointer set then make sure the check is
2617 done with the type & not the pointer */
2618 /* then cast rights type to left */
2620 /* first check the type for pointer assignement */
2621 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2622 compareType (ltype, rtype) < 0)
2624 if (compareType (ltype->next, rtype) < 0)
2625 right = geniCodeCast (ltype->next, right, TRUE);
2627 else if (compareType (ltype, rtype) < 0)
2628 right = geniCodeCast (ltype, right, TRUE);
2630 /* if left is a true symbol & ! volatile
2631 create an assignment to temporary for
2632 the right & then assign this temporary
2633 to the symbol this is SSA . isn't it simple
2634 and folks have published mountains of paper on it */
2635 if (IS_TRUE_SYMOP (left) &&
2636 !isOperandVolatile (left, FALSE) &&
2637 isOperandGlobal (left))
2641 if (IS_TRUE_SYMOP (right))
2642 sym = OP_SYMBOL (right);
2643 ic = newiCode ('=', NULL, right);
2644 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2645 SPIL_LOC (right) = sym;
2649 ic = newiCode ('=', NULL, right);
2650 IC_RESULT (ic) = left;
2653 /* if left isgptr flag is set then support
2654 routine will be required */
2658 ic->nosupdate = nosupdate;
2662 /*-----------------------------------------------------------------*/
2663 /* geniCodeSEParms - generate code for side effecting fcalls */
2664 /*-----------------------------------------------------------------*/
2666 geniCodeSEParms (ast * parms,int lvl)
2671 if (parms->type == EX_OP && parms->opval.op == PARAM)
2673 geniCodeSEParms (parms->left,lvl);
2674 geniCodeSEParms (parms->right,lvl);
2678 /* hack don't like this but too lazy to think of
2680 if (IS_ADDRESS_OF_OP (parms))
2681 parms->left->lvalue = 1;
2683 if (IS_CAST_OP (parms) &&
2684 IS_PTR (parms->ftype) &&
2685 IS_ADDRESS_OF_OP (parms->right))
2686 parms->right->left->lvalue = 1;
2688 parms->opval.oprnd =
2689 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2691 parms->type = EX_OPERAND;
2694 /*-----------------------------------------------------------------*/
2695 /* geniCodeParms - generates parameters */
2696 /*-----------------------------------------------------------------*/
2698 geniCodeParms (ast * parms, value *argVals, int *stack,
2699 sym_link * fetype, symbol * func,int lvl)
2707 if (argVals==NULL) {
2709 argVals=FUNC_ARGS(func->type);
2712 if (parms->argSym ||
2713 (parms->type!=EX_OP && parms->type!=EX_OPERAND)) {
2714 fprintf (stderr, "What the fuck??\n");
2717 /* if this is a param node then do the left & right */
2718 if (parms->type == EX_OP && parms->opval.op == PARAM)
2720 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2721 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2725 /* get the parameter value */
2726 if (parms->type == EX_OPERAND)
2727 pval = parms->opval.oprnd;
2730 /* maybe this else should go away ?? */
2731 /* hack don't like this but too lazy to think of
2733 if (IS_ADDRESS_OF_OP (parms))
2734 parms->left->lvalue = 1;
2736 if (IS_CAST_OP (parms) &&
2737 IS_PTR (parms->ftype) &&
2738 IS_ADDRESS_OF_OP (parms->right))
2739 parms->right->left->lvalue = 1;
2741 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2744 /* if register arg then make it a send */
2745 if (((argVals->sym && IS_REGPARM (argVals->sym->etype)) ||
2746 IS_REGPARM (parms->etype)) && !IFFUNC_HASVARARGS(func->type))
2747 //!DECL_HASVARARGS(func->type) &&
2748 //!options.stackAuto &&
2749 //!IS_RENT(func->etype) &&
2750 //IS_REGPARM (argVals->sym->etype))
2752 ic = newiCode (SEND, pval, NULL);
2757 /* now decide whether to push or assign */
2758 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2762 operand *top = operandFromSymbol (argVals->sym);
2763 geniCodeAssign (top, pval, 1);
2767 sym_link *p = operandType (pval);
2769 ic = newiCode (IPUSH, pval, NULL);
2771 /* update the stack adjustment */
2772 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2777 argVals=argVals->next;
2781 /*-----------------------------------------------------------------*/
2782 /* geniCodeCall - generates temp code for calling */
2783 /*-----------------------------------------------------------------*/
2785 geniCodeCall (operand * left, ast * parms,int lvl)
2789 sym_link *type, *etype;
2792 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2793 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2794 werror (E_FUNCTION_EXPECTED);
2798 /* take care of parameters with side-effecting
2799 function calls in them, this is required to take care
2800 of overlaying function parameters */
2801 geniCodeSEParms (parms,lvl);
2803 /* first the parameters */
2804 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2806 /* now call : if symbol then pcall */
2807 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2808 ic = newiCode (PCALL, left, NULL);
2810 ic = newiCode (CALL, left, NULL);
2812 IC_ARGS (ic) = FUNC_ARGS(left->operand.symOperand->type);
2813 type = copyLinkChain (operandType (left)->next);
2814 etype = getSpec (type);
2815 SPEC_EXTR (etype) = 0;
2816 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2820 /* stack adjustment after call */
2821 ic->parmBytes = stack;
2826 /*-----------------------------------------------------------------*/
2827 /* geniCodeReceive - generate intermediate code for "receive" */
2828 /*-----------------------------------------------------------------*/
2830 geniCodeReceive (value * args)
2832 /* for all arguments that are passed in registers */
2836 if (IS_REGPARM (args->etype))
2838 operand *opr = operandFromValue (args);
2840 symbol *sym = OP_SYMBOL (opr);
2843 /* we will use it after all optimizations
2844 and before liveRange calculation */
2845 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2848 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2849 options.stackAuto == 0 &&
2850 /* !TARGET_IS_DS390) */
2851 (!(options.model == MODEL_FLAT24)) )
2856 opl = newiTempOperand (args->type, 0);
2858 sym->reqv->key = sym->key;
2859 OP_SYMBOL (sym->reqv)->key = sym->key;
2860 OP_SYMBOL (sym->reqv)->isreqv = 1;
2861 OP_SYMBOL (sym->reqv)->islocal = 0;
2862 SPIL_LOC (sym->reqv) = sym;
2866 ic = newiCode (RECEIVE, NULL, NULL);
2867 currFunc->recvSize = getSize (sym->etype);
2868 IC_RESULT (ic) = opr;
2876 /*-----------------------------------------------------------------*/
2877 /* geniCodeFunctionBody - create the function body */
2878 /*-----------------------------------------------------------------*/
2880 geniCodeFunctionBody (ast * tree,int lvl)
2887 /* reset the auto generation */
2893 func = ast2iCode (tree->left,lvl+1);
2894 fetype = getSpec (operandType (func));
2896 savelineno = lineno;
2897 lineno = OP_SYMBOL (func)->lineDef;
2898 /* create an entry label */
2899 geniCodeLabel (entryLabel);
2900 lineno = savelineno;
2902 /* create a proc icode */
2903 ic = newiCode (FUNCTION, func, NULL);
2904 /* if the function has parmas then */
2905 /* save the parameters information */
2906 ic->argLabel.args = tree->values.args;
2907 ic->lineno = OP_SYMBOL (func)->lineDef;
2911 /* for all parameters that are passed
2912 on registers add a "receive" */
2913 geniCodeReceive (tree->values.args);
2915 /* generate code for the body */
2916 ast2iCode (tree->right,lvl+1);
2918 /* create a label for return */
2919 geniCodeLabel (returnLabel);
2921 /* now generate the end proc */
2922 ic = newiCode (ENDFUNCTION, func, NULL);
2927 /*-----------------------------------------------------------------*/
2928 /* geniCodeReturn - gen icode for 'return' statement */
2929 /*-----------------------------------------------------------------*/
2931 geniCodeReturn (operand * op)
2935 /* if the operand is present force an rvalue */
2937 op = geniCodeRValue (op, FALSE);
2939 ic = newiCode (RETURN, op, NULL);
2943 /*-----------------------------------------------------------------*/
2944 /* geniCodeIfx - generates code for extended if statement */
2945 /*-----------------------------------------------------------------*/
2947 geniCodeIfx (ast * tree,int lvl)
2950 operand *condition = ast2iCode (tree->left,lvl+1);
2953 /* if condition is null then exit */
2957 condition = geniCodeRValue (condition, FALSE);
2959 cetype = getSpec (operandType (condition));
2960 /* if the condition is a literal */
2961 if (IS_LITERAL (cetype))
2963 if (floatFromVal (condition->operand.valOperand))
2965 if (tree->trueLabel)
2966 geniCodeGoto (tree->trueLabel);
2972 if (tree->falseLabel)
2973 geniCodeGoto (tree->falseLabel);
2980 if (tree->trueLabel)
2982 ic = newiCodeCondition (condition,
2987 if (tree->falseLabel)
2988 geniCodeGoto (tree->falseLabel);
2992 ic = newiCodeCondition (condition,
2999 ast2iCode (tree->right,lvl+1);
3002 /*-----------------------------------------------------------------*/
3003 /* geniCodeJumpTable - tries to create a jump table for switch */
3004 /*-----------------------------------------------------------------*/
3006 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3008 int min = 0, max = 0, t, cnt = 0;
3015 if (!tree || !caseVals)
3018 /* the criteria for creating a jump table is */
3019 /* all integer numbers between the maximum & minimum must */
3020 /* be present , the maximum value should not exceed 255 */
3021 min = max = (int) floatFromVal (vch = caseVals);
3022 sprintf (buffer, "_case_%d_%d",
3023 tree->values.switchVals.swNum,
3025 addSet (&labels, newiTempLabel (buffer));
3027 /* if there is only one case value then no need */
3028 if (!(vch = vch->next))
3033 if (((t = (int) floatFromVal (vch)) - max) != 1)
3035 sprintf (buffer, "_case_%d_%d",
3036 tree->values.switchVals.swNum,
3038 addSet (&labels, newiTempLabel (buffer));
3044 /* if the number of case statements <= 2 then */
3045 /* it is not economical to create the jump table */
3046 /* since two compares are needed for boundary conditions */
3047 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3050 if (tree->values.switchVals.swDefault)
3051 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3053 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3055 falseLabel = newiTempLabel (buffer);
3057 /* so we can create a jumptable */
3058 /* first we rule out the boundary conditions */
3059 /* if only optimization says so */
3060 if (!optimize.noJTabBoundary)
3062 sym_link *cetype = getSpec (operandType (cond));
3063 /* no need to check the lower bound if
3064 the condition is unsigned & minimum value is zero */
3065 if (!(min == 0 && SPEC_USIGN (cetype)))
3067 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3068 ic = newiCodeCondition (boundary, falseLabel, NULL);
3072 /* now for upper bounds */
3073 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3074 ic = newiCodeCondition (boundary, falseLabel, NULL);
3078 /* if the min is not zero then we no make it zero */
3081 cond = geniCodeSubtract (cond, operandFromLit (min));
3082 setOperandType (cond, UCHARTYPE);
3085 /* now create the jumptable */
3086 ic = newiCode (JUMPTABLE, NULL, NULL);
3087 IC_JTCOND (ic) = cond;
3088 IC_JTLABELS (ic) = labels;
3093 /*-----------------------------------------------------------------*/
3094 /* geniCodeSwitch - changes a switch to a if statement */
3095 /*-----------------------------------------------------------------*/
3097 geniCodeSwitch (ast * tree,int lvl)
3100 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3101 value *caseVals = tree->values.switchVals.swVals;
3102 symbol *trueLabel, *falseLabel;
3104 /* if we can make this a jump table */
3105 if (geniCodeJumpTable (cond, caseVals, tree))
3106 goto jumpTable; /* no need for the comparison */
3108 /* for the cases defined do */
3112 operand *compare = geniCodeLogic (cond,
3113 operandFromValue (caseVals),
3116 sprintf (buffer, "_case_%d_%d",
3117 tree->values.switchVals.swNum,
3118 (int) floatFromVal (caseVals));
3119 trueLabel = newiTempLabel (buffer);
3121 ic = newiCodeCondition (compare, trueLabel, NULL);
3123 caseVals = caseVals->next;
3128 /* if default is present then goto break else break */
3129 if (tree->values.switchVals.swDefault)
3130 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3132 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3134 falseLabel = newiTempLabel (buffer);
3135 geniCodeGoto (falseLabel);
3138 ast2iCode (tree->right,lvl+1);
3141 /*-----------------------------------------------------------------*/
3142 /* geniCodeInline - intermediate code for inline assembler */
3143 /*-----------------------------------------------------------------*/
3145 geniCodeInline (ast * tree)
3149 ic = newiCode (INLINEASM, NULL, NULL);
3150 IC_INLINE (ic) = tree->values.inlineasm;
3154 /*-----------------------------------------------------------------*/
3155 /* geniCodeArrayInit - intermediate code for array initializer */
3156 /*-----------------------------------------------------------------*/
3158 geniCodeArrayInit (ast * tree, operand *array)
3162 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3163 ic = newiCode (ARRAYINIT, array, NULL);
3164 IC_ARRAYILIST (ic) = tree->values.constlist;
3166 operand *left=newOperand(), *right=newOperand();
3167 left->type=right->type=SYMBOL;
3168 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3169 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3170 ic = newiCode (ARRAYINIT, left, right);
3175 /*-----------------------------------------------------------------*/
3176 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3177 /* particular case. Ie : assigning or dereferencing array or ptr */
3178 /*-----------------------------------------------------------------*/
3179 set * lvaluereqSet = NULL;
3180 typedef struct lvalItem
3187 /*-----------------------------------------------------------------*/
3188 /* addLvaluereq - add a flag for lvalreq for current ast level */
3189 /*-----------------------------------------------------------------*/
3190 void addLvaluereq(int lvl)
3192 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3195 addSetHead(&lvaluereqSet,lpItem);
3198 /*-----------------------------------------------------------------*/
3199 /* delLvaluereq - del a flag for lvalreq for current ast level */
3200 /*-----------------------------------------------------------------*/
3204 lpItem = getSet(&lvaluereqSet);
3205 if(lpItem) Safe_free(lpItem);
3207 /*-----------------------------------------------------------------*/
3208 /* clearLvaluereq - clear lvalreq flag */
3209 /*-----------------------------------------------------------------*/
3210 void clearLvaluereq()
3213 lpItem = peekSet(lvaluereqSet);
3214 if(lpItem) lpItem->req = 0;
3216 /*-----------------------------------------------------------------*/
3217 /* getLvaluereq - get the last lvalreq level */
3218 /*-----------------------------------------------------------------*/
3219 int getLvaluereqLvl()
3222 lpItem = peekSet(lvaluereqSet);
3223 if(lpItem) return lpItem->lvl;
3226 /*-----------------------------------------------------------------*/
3227 /* isLvaluereq - is lvalreq valid for this level ? */
3228 /*-----------------------------------------------------------------*/
3229 int isLvaluereq(int lvl)
3232 lpItem = peekSet(lvaluereqSet);
3233 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3237 /*-----------------------------------------------------------------*/
3238 /* ast2iCode - creates an icodeList from an ast */
3239 /*-----------------------------------------------------------------*/
3241 ast2iCode (ast * tree,int lvl)
3243 operand *left = NULL;
3244 operand *right = NULL;
3247 /* set the global variables for filename & line number */
3249 filename = tree->filename;
3251 lineno = tree->lineno;
3253 block = tree->block;
3255 scopeLevel = tree->level;
3257 if (tree->type == EX_VALUE)
3258 return operandFromValue (tree->opval.val);
3260 if (tree->type == EX_LINK)
3261 return operandFromLink (tree->opval.lnk);
3263 /* if we find a nullop */
3264 if (tree->type == EX_OP &&
3265 (tree->opval.op == NULLOP ||
3266 tree->opval.op == BLOCK))
3268 ast2iCode (tree->left,lvl+1);
3269 ast2iCode (tree->right,lvl+1);
3273 /* special cases for not evaluating */
3274 if (tree->opval.op != ':' &&
3275 tree->opval.op != '?' &&
3276 tree->opval.op != CALL &&
3277 tree->opval.op != IFX &&
3278 tree->opval.op != LABEL &&
3279 tree->opval.op != GOTO &&
3280 tree->opval.op != SWITCH &&
3281 tree->opval.op != FUNCTION &&
3282 tree->opval.op != INLINEASM)
3285 if (IS_ASSIGN_OP (tree->opval.op) ||
3286 IS_DEREF_OP (tree) ||
3287 (tree->opval.op == '&' && !tree->right) ||
3288 tree->opval.op == PTR_OP)
3291 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3292 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3295 left = operandFromAst (tree->left,lvl);
3297 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3298 left = geniCodeRValue (left, TRUE);
3302 left = operandFromAst (tree->left,lvl);
3304 if (tree->opval.op == INC_OP ||
3305 tree->opval.op == DEC_OP)
3308 right = operandFromAst (tree->right,lvl);
3313 right = operandFromAst (tree->right,lvl);
3317 /* now depending on the type of operand */
3318 /* this will be a biggy */
3319 switch (tree->opval.op)
3322 case '[': /* array operation */
3324 //sym_link *ltype = operandType (left);
3325 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3326 left = geniCodeRValue (left, FALSE);
3327 right = geniCodeRValue (right, TRUE);
3330 return geniCodeArray (left, right,lvl);
3332 case '.': /* structure dereference */
3333 if (IS_PTR (operandType (left)))
3334 left = geniCodeRValue (left, TRUE);
3336 left = geniCodeRValue (left, FALSE);
3338 return geniCodeStruct (left, right, tree->lvalue);
3340 case PTR_OP: /* structure pointer dereference */
3343 pType = operandType (left);
3344 left = geniCodeRValue (left, TRUE);
3346 setOClass (pType, getSpec (operandType (left)));
3349 return geniCodeStruct (left, right, tree->lvalue);
3351 case INC_OP: /* increment operator */
3353 return geniCodePostInc (left);
3355 return geniCodePreInc (right);
3357 case DEC_OP: /* decrement operator */
3359 return geniCodePostDec (left);
3361 return geniCodePreDec (right);
3363 case '&': /* bitwise and or address of operator */
3365 { /* this is a bitwise operator */
3366 left = geniCodeRValue (left, FALSE);
3367 right = geniCodeRValue (right, FALSE);
3368 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3371 return geniCodeAddressOf (left);
3373 case '|': /* bitwise or & xor */
3375 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3376 geniCodeRValue (right, FALSE),
3381 return geniCodeDivision (geniCodeRValue (left, FALSE),
3382 geniCodeRValue (right, FALSE));
3385 return geniCodeModulus (geniCodeRValue (left, FALSE),
3386 geniCodeRValue (right, FALSE));
3389 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3390 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3392 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3396 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3397 geniCodeRValue (right, FALSE));
3399 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3403 return geniCodeAdd (geniCodeRValue (left, FALSE),
3404 geniCodeRValue (right, FALSE),lvl);
3406 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3409 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3410 geniCodeRValue (right, FALSE));
3413 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3414 geniCodeRValue (right, FALSE));
3416 return geniCodeCast (operandType (left),
3417 geniCodeRValue (right, FALSE), FALSE);
3423 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3427 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3428 setOperandType (op, UCHARTYPE);
3439 return geniCodeLogic (geniCodeRValue (left, FALSE),
3440 geniCodeRValue (right, FALSE),
3443 return geniCodeConditional (tree,lvl);
3446 return operandFromLit (getSize (tree->right->ftype));
3450 sym_link *rtype = operandType (right);
3451 sym_link *ltype = operandType (left);
3452 if (IS_PTR (rtype) && IS_ITEMP (right)
3453 && right->isaddr && compareType (rtype->next, ltype) == 1)
3454 right = geniCodeRValue (right, TRUE);
3456 right = geniCodeRValue (right, FALSE);
3458 geniCodeAssign (left, right, 0);
3463 geniCodeAssign (left,
3464 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3466 geniCodeRValue (right, FALSE),FALSE), 0);
3470 geniCodeAssign (left,
3471 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3473 geniCodeRValue (right, FALSE)), 0);
3476 geniCodeAssign (left,
3477 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3479 geniCodeRValue (right, FALSE)), 0);
3482 sym_link *rtype = operandType (right);
3483 sym_link *ltype = operandType (left);
3484 if (IS_PTR (rtype) && IS_ITEMP (right)
3485 && right->isaddr && compareType (rtype->next, ltype) == 1)
3486 right = geniCodeRValue (right, TRUE);
3488 right = geniCodeRValue (right, FALSE);
3491 return geniCodeAssign (left,
3492 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3498 sym_link *rtype = operandType (right);
3499 sym_link *ltype = operandType (left);
3500 if (IS_PTR (rtype) && IS_ITEMP (right)
3501 && right->isaddr && compareType (rtype->next, ltype) == 1)
3503 right = geniCodeRValue (right, TRUE);
3507 right = geniCodeRValue (right, FALSE);
3510 geniCodeAssign (left,
3511 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3517 geniCodeAssign (left,
3518 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3520 geniCodeRValue (right, FALSE)), 0);
3523 geniCodeAssign (left,
3524 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3526 geniCodeRValue (right, FALSE)), 0);
3529 geniCodeAssign (left,
3530 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3532 geniCodeRValue (right, FALSE),
3534 operandType (left)), 0);
3537 geniCodeAssign (left,
3538 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3540 geniCodeRValue (right, FALSE),
3542 operandType (left)), 0);
3545 geniCodeAssign (left,
3546 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3548 geniCodeRValue (right, FALSE),
3550 operandType (left)), 0);
3552 return geniCodeRValue (right, FALSE);
3555 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3558 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3559 return ast2iCode (tree->right,lvl+1);
3562 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3563 return ast2iCode (tree->right,lvl+1);
3566 geniCodeFunctionBody (tree,lvl);
3570 geniCodeReturn (right);
3574 geniCodeIfx (tree,lvl);
3578 geniCodeSwitch (tree,lvl);
3582 geniCodeInline (tree);
3586 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3593 /*-----------------------------------------------------------------*/
3594 /* reverseICChain - gets from the list and creates a linkedlist */
3595 /*-----------------------------------------------------------------*/
3602 while ((loop = getSet (&iCodeChain)))
3614 /*-----------------------------------------------------------------*/
3615 /* iCodeFromAst - given an ast will convert it to iCode */
3616 /*-----------------------------------------------------------------*/
3618 iCodeFromAst (ast * tree)
3620 returnLabel = newiTempLabel ("_return");
3621 entryLabel = newiTempLabel ("_entry");
3623 return reverseiCChain ();