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]="";
141 if (SPEC_LONG(val->type)) {
142 v=SPEC_CVAL(val->type).v_long;
144 v=SPEC_CVAL(val->type).v_int;
149 // this could be a good idea
150 if (options.pedantic)
154 if (SPEC_NOUN(ltype)==FLOAT) {
159 if (!SPEC_USIGN(val->type) && v<0) {
161 if (SPEC_USIGN(ltype) && (pedantic>1)) {
167 // if very pedantic: "char c=200" is not allowed
168 if (pedantic>1 && !SPEC_USIGN(ltype)) {
169 max = max/2 + negative;
177 sprintf (message, "for %s %s in %s",
178 SPEC_USIGN(ltype) ? "unsigned" : "signed",
179 nounName(ltype), msg);
180 werror (W_CONST_RANGE, message);
187 /*-----------------------------------------------------------------*/
188 /* operandName - returns the name of the operand */
189 /*-----------------------------------------------------------------*/
191 printOperand (operand * op, FILE * file)
208 opetype = getSpec (operandType (op));
209 if (SPEC_NOUN (opetype) == V_FLOAT)
210 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
212 fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
213 printTypeChain (operandType (op), file);
220 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}" , */
221 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
223 OP_LIVEFROM (op), OP_LIVETO (op),
224 OP_SYMBOL (op)->stack,
225 op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc
229 printTypeChain (operandType (op), file);
230 if (SPIL_LOC (op) && IS_ITEMP (op))
231 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
236 /* if assigned to registers */
237 if (OP_SYMBOL (op)->nRegs)
239 if (OP_SYMBOL (op)->isspilt)
241 if (!OP_SYMBOL (op)->remat)
242 if (OP_SYMBOL (op)->usl.spillLoc)
243 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
244 OP_SYMBOL (op)->usl.spillLoc->rname :
245 OP_SYMBOL (op)->usl.spillLoc->name));
247 fprintf (file, "[err]");
249 fprintf (file, "[remat]");
255 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
256 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
261 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
262 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
263 /* if assigned to registers */
264 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
268 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
269 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
270 OP_SYMBOL (op)->regs[i]->name :
279 printTypeChain (op->operand.typeOperand, file);
285 fprintf (file, "\n");
290 /*-----------------------------------------------------------------*/
291 /* print functions */
292 /*-----------------------------------------------------------------*/
293 PRINTFUNC (picGetValueAtAddr)
296 printOperand (IC_RESULT (ic), of);
299 printOperand (IC_LEFT (ic), of);
305 PRINTFUNC (picSetValueAtAddr)
309 printOperand (IC_LEFT (ic), of);
310 fprintf (of, "] = ");
311 printOperand (IC_RIGHT (ic), of);
315 PRINTFUNC (picAddrOf)
318 printOperand (IC_RESULT (ic), of);
319 if (IS_ITEMP (IC_LEFT (ic)))
322 fprintf (of, " = &[");
323 printOperand (IC_LEFT (ic), of);
326 if (IS_ITEMP (IC_LEFT (ic)))
327 fprintf (of, " offsetAdd ");
330 printOperand (IC_RIGHT (ic), of);
332 if (IS_ITEMP (IC_LEFT (ic)))
338 PRINTFUNC (picJumpTable)
343 fprintf (of, "%s\t", s);
344 printOperand (IC_JTCOND (ic), of);
346 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
347 sym = setNextItem (IC_JTLABELS (ic)))
348 fprintf (of, "\t\t\t%s\n", sym->name);
351 PRINTFUNC (picGeneric)
354 printOperand (IC_RESULT (ic), of);
356 printOperand (IC_LEFT (ic), of);
357 fprintf (of, " %s ", s);
358 printOperand (IC_RIGHT (ic), of);
362 PRINTFUNC (picGenericOne)
367 printOperand (IC_RESULT (ic), of);
373 fprintf (of, "%s ", s);
374 printOperand (IC_LEFT (ic), of);
377 if (!IC_RESULT (ic) && !IC_LEFT (ic))
386 printOperand (IC_RESULT (ic), of);
388 printOperand (IC_LEFT (ic), of);
389 printOperand (IC_RIGHT (ic), of);
394 PRINTFUNC (picAssign)
398 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
401 printOperand (IC_RESULT (ic), of);
403 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
406 fprintf (of, " %s ", s);
407 printOperand (IC_RIGHT (ic), of);
414 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
420 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
427 printOperand (IC_COND (ic), of);
430 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
433 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
435 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
439 PRINTFUNC (picInline)
441 fprintf (of, "%s", IC_INLINE (ic));
444 PRINTFUNC (picReceive)
446 printOperand (IC_RESULT (ic), of);
447 fprintf (of, " = %s ", s);
448 printOperand (IC_LEFT (ic), of);
452 /*-----------------------------------------------------------------*/
453 /* piCode - prints one iCode */
454 /*-----------------------------------------------------------------*/
456 piCode (void *item, FILE * of)
464 icTab = getTableEntry (ic->op);
465 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
466 ic->filename, ic->lineno,
467 ic->seq, ic->key, ic->depth, ic->supportRtn);
468 icTab->iCodePrint (of, ic, icTab->printName);
474 printiCChain(ic,stdout);
476 /*-----------------------------------------------------------------*/
477 /* printiCChain - prints intermediate code for humans */
478 /*-----------------------------------------------------------------*/
480 printiCChain (iCode * icChain, FILE * of)
487 for (loop = icChain; loop; loop = loop->next)
489 if ((icTab = getTableEntry (loop->op)))
491 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
492 loop->filename, loop->lineno,
493 loop->seq, loop->key, loop->depth, loop->supportRtn);
495 icTab->iCodePrint (of, loop, icTab->printName);
501 /*-----------------------------------------------------------------*/
502 /* newOperand - allocate, init & return a new iCode */
503 /*-----------------------------------------------------------------*/
509 op = Safe_alloc ( sizeof (operand));
515 /*-----------------------------------------------------------------*/
516 /* newiCode - create and return a new iCode entry initialised */
517 /*-----------------------------------------------------------------*/
519 newiCode (int op, operand * left, operand * right)
523 ic = Safe_alloc ( sizeof (iCode));
526 ic->filename = filename;
528 ic->level = scopeLevel;
530 ic->key = iCodeKey++;
532 IC_RIGHT (ic) = right;
537 /*-----------------------------------------------------------------*/
538 /* newiCode for conditional statements */
539 /*-----------------------------------------------------------------*/
541 newiCodeCondition (operand * condition,
547 if (IS_VOID(OP_SYMBOL(condition)->type)) {
548 werror(E_VOID_VALUE_USED);
551 ic = newiCode (IFX, NULL, NULL);
552 IC_COND (ic) = condition;
553 IC_TRUE (ic) = trueLabel;
554 IC_FALSE (ic) = falseLabel;
558 /*-----------------------------------------------------------------*/
559 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
560 /*-----------------------------------------------------------------*/
562 newiCodeLabelGoto (int op, symbol * label)
566 ic = newiCode (op, NULL, NULL);
568 ic->argLabel.label = label;
570 IC_RIGHT (ic) = NULL;
571 IC_RESULT (ic) = NULL;
575 /*-----------------------------------------------------------------*/
576 /* newiTemp - allocate & return a newItemp Variable */
577 /*-----------------------------------------------------------------*/
584 sprintf (buffer, "%s", s);
586 sprintf (buffer, "iTemp%d", iTempNum++);
587 itmp = newSymbol (buffer, 1);
588 strcpy (itmp->rname, itmp->name);
594 /*-----------------------------------------------------------------*/
595 /* newiTempLabel - creates a temp variable label */
596 /*-----------------------------------------------------------------*/
598 newiTempLabel (char *s)
602 /* check if this alredy exists */
603 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
607 itmplbl = newSymbol (s, 1);
610 sprintf (buffer, "iTempLbl%d", iTempLblNum++);
611 itmplbl = newSymbol (buffer, 1);
616 itmplbl->key = labelKey++;
617 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
621 /*-----------------------------------------------------------------*/
622 /* newiTempPreheaderLabel - creates a new preheader label */
623 /*-----------------------------------------------------------------*/
625 newiTempPreheaderLabel ()
629 sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
630 itmplbl = newSymbol (buffer, 1);
634 itmplbl->key = labelKey++;
635 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
640 /*-----------------------------------------------------------------*/
641 /* initiCode - initialises some iCode related stuff */
642 /*-----------------------------------------------------------------*/
649 /*-----------------------------------------------------------------*/
650 /* copyiCode - make a copy of the iCode given */
651 /*-----------------------------------------------------------------*/
653 copyiCode (iCode * ic)
655 iCode *nic = newiCode (ic->op, NULL, NULL);
657 nic->lineno = ic->lineno;
658 nic->filename = ic->filename;
659 nic->block = ic->block;
660 nic->level = ic->level;
661 nic->parmBytes = ic->parmBytes;
663 /* deal with the special cases first */
667 IC_COND (nic) = operandFromOperand (IC_COND (ic));
668 IC_TRUE (nic) = IC_TRUE (ic);
669 IC_FALSE (nic) = IC_FALSE (ic);
673 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
674 IC_JTLABELS (nic) = IC_JTLABELS (ic);
679 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
680 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
681 IC_ARGS (nic) = IC_ARGS (ic);
685 IC_INLINE (nic) = IC_INLINE (ic);
689 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
693 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
694 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
695 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
701 /*-----------------------------------------------------------------*/
702 /* getTableEntry - gets the table entry for the given operator */
703 /*-----------------------------------------------------------------*/
705 getTableEntry (int oper)
709 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
710 if (oper == codeTable[i].icode)
711 return &codeTable[i];
716 /*-----------------------------------------------------------------*/
717 /* newiTempOperand - new intermediate temp operand */
718 /*-----------------------------------------------------------------*/
720 newiTempOperand (sym_link * type, char throwType)
723 operand *op = newOperand ();
727 itmp = newiTemp (NULL);
729 etype = getSpec (type);
731 if (IS_LITERAL (etype))
734 /* copy the type information */
736 itmp->etype = getSpec (itmp->type = (throwType ? type :
737 copyLinkChain (type)));
738 if (IS_LITERAL (itmp->etype))
740 SPEC_SCLS (itmp->etype) = S_REGISTER;
741 SPEC_OCLS (itmp->etype) = reg;
744 op->operand.symOperand = itmp;
745 op->key = itmp->key = ++operandKey;
749 /*-----------------------------------------------------------------*/
750 /* operandType - returns the type chain for an operand */
751 /*-----------------------------------------------------------------*/
753 operandType (operand * op)
755 /* depending on type of operand */
760 return op->operand.valOperand->type;
763 return op->operand.symOperand->type;
766 return op->operand.typeOperand;
768 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
769 " operand type not known ");
770 assert (0); /* should never come here */
771 /* Just to keep the compiler happy */
772 return (sym_link *) 0;
776 /*-----------------------------------------------------------------*/
777 /* isParamterToCall - will return 1 if op is a parameter to args */
778 /*-----------------------------------------------------------------*/
780 isParameterToCall (value * args, operand * op)
787 isSymbolEqual (op->operand.symOperand, tval->sym))
794 /*-----------------------------------------------------------------*/
795 /* isOperandGlobal - return 1 if operand is a global variable */
796 /*-----------------------------------------------------------------*/
798 isOperandGlobal (operand * op)
806 if (op->type == SYMBOL &&
807 (op->operand.symOperand->level == 0 ||
808 IS_STATIC (op->operand.symOperand->etype) ||
809 IS_EXTERN (op->operand.symOperand->etype))
816 /*-----------------------------------------------------------------*/
817 /* isOperandVolatile - return 1 if the operand is volatile */
818 /*-----------------------------------------------------------------*/
820 isOperandVolatile (operand * op, bool chkTemp)
825 if (IS_ITEMP (op) && !chkTemp)
828 opetype = getSpec (optype = operandType (op));
830 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
833 if (IS_VOLATILE (opetype))
838 /*-----------------------------------------------------------------*/
839 /* isOperandLiteral - returns 1 if an operand contains a literal */
840 /*-----------------------------------------------------------------*/
842 isOperandLiteral (operand * op)
849 opetype = getSpec (operandType (op));
851 if (IS_LITERAL (opetype))
856 /*-----------------------------------------------------------------*/
857 /* isOperandInFarSpace - will return true if operand is in farSpace */
858 /*-----------------------------------------------------------------*/
860 isOperandInFarSpace (operand * op)
870 if (!IS_TRUE_SYMOP (op))
873 etype = SPIL_LOC (op)->etype;
879 etype = getSpec (operandType (op));
881 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
884 /*-----------------------------------------------------------------*/
885 /* isOperandOnStack - will return true if operand is on stack */
886 /*-----------------------------------------------------------------*/
888 isOperandOnStack (operand * op)
898 etype = getSpec (operandType (op));
900 return ((IN_STACK (etype)) ? TRUE : FALSE);
903 /*-----------------------------------------------------------------*/
904 /* operandLitValue - literal value of an operand */
905 /*-----------------------------------------------------------------*/
907 operandLitValue (operand * op)
909 assert (isOperandLiteral (op));
911 return floatFromVal (op->operand.valOperand);
914 /*-----------------------------------------------------------------*/
915 /* operandOperation - perforoms operations on operands */
916 /*-----------------------------------------------------------------*/
918 operandOperation (operand * left, operand * right,
919 int op, sym_link * type)
921 sym_link *let , *ret=NULL;
922 operand *retval = (operand *) 0;
924 assert (isOperandLiteral (left));
925 let = getSpec(operandType(left));
927 assert (isOperandLiteral (right));
928 ret = getSpec(operandType(left));
934 retval = operandFromValue (valCastLiteral (type,
935 operandLitValue (left) +
936 operandLitValue (right)));
939 retval = operandFromValue (valCastLiteral (type,
940 operandLitValue (left) -
941 operandLitValue (right)));
944 retval = operandFromValue (valCastLiteral (type,
945 operandLitValue (left) *
946 operandLitValue (right)));
949 if ((unsigned long) operandLitValue (right) == 0)
951 werror (E_DIVIDE_BY_ZERO);
956 retval = operandFromValue (valCastLiteral (type,
957 operandLitValue (left) /
958 operandLitValue (right)));
961 if ((unsigned long) operandLitValue (right) == 0) {
962 werror (E_DIVIDE_BY_ZERO);
966 retval = operandFromLit ((SPEC_USIGN(let) ?
967 (unsigned long) operandLitValue (left) :
968 (long) operandLitValue (left)) %
970 (unsigned long) operandLitValue (right) :
971 (long) operandLitValue (right)));
975 retval = operandFromLit ((SPEC_USIGN(let) ?
976 (unsigned long) operandLitValue (left) :
977 (long) operandLitValue (left)) <<
979 (unsigned long) operandLitValue (right) :
980 (long) operandLitValue (right)));
983 retval = operandFromLit ((SPEC_USIGN(let) ?
984 (unsigned long) operandLitValue (left) :
985 (long) operandLitValue (left)) >>
987 (unsigned long) operandLitValue (right) :
988 (long) operandLitValue (right)));
991 retval = operandFromLit (operandLitValue (left) ==
992 operandLitValue (right));
995 retval = operandFromLit (operandLitValue (left) <
996 operandLitValue (right));
999 retval = operandFromLit (operandLitValue (left) <=
1000 operandLitValue (right));
1003 retval = operandFromLit (operandLitValue (left) !=
1004 operandLitValue (right));
1007 retval = operandFromLit (operandLitValue (left) >
1008 operandLitValue (right));
1011 retval = operandFromLit (operandLitValue (left) >=
1012 operandLitValue (right));
1015 retval = operandFromLit ((long)operandLitValue(left) &
1016 (long)operandLitValue(right));
1019 retval = operandFromLit ((long)operandLitValue (left) |
1020 (long)operandLitValue (right));
1023 retval = operandFromLit ((long)operandLitValue (left) ^
1024 (long)operandLitValue (right));
1027 retval = operandFromLit (operandLitValue (left) &&
1028 operandLitValue (right));
1031 retval = operandFromLit (operandLitValue (left) ||
1032 operandLitValue (right));
1036 long i = (long) operandLitValue (left);
1038 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1044 long i = (long) operandLitValue (left);
1046 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1052 retval = operandFromLit (-1 * operandLitValue (left));
1056 retval = operandFromLit (~((long) operandLitValue (left)));
1060 retval = operandFromLit (!operandLitValue (left));
1064 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1065 " operandOperation invalid operator ");
1073 /*-----------------------------------------------------------------*/
1074 /* isOperandEqual - compares two operand & return 1 if they r = */
1075 /*-----------------------------------------------------------------*/
1077 isOperandEqual (operand * left, operand * right)
1079 /* if the pointers are equal then they are equal */
1083 /* if either of them null then false */
1084 if (!left || !right)
1087 if (left->type != right->type)
1090 if (IS_SYMOP (left) && IS_SYMOP (right))
1091 return left->key == right->key;
1093 /* if types are the same */
1097 return isSymbolEqual (left->operand.symOperand,
1098 right->operand.symOperand);
1100 return (floatFromVal (left->operand.valOperand) ==
1101 floatFromVal (right->operand.valOperand));
1103 if (compareType (left->operand.typeOperand,
1104 right->operand.typeOperand) == 1)
1111 /*-------------------------------------------------------------------*/
1112 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1113 /*-------------------------------------------------------------------*/
1115 isiCodeEqual (iCode * left, iCode * right)
1117 /* if the same pointer */
1121 /* if either of them null */
1122 if (!left || !right)
1125 /* if operand are the same */
1126 if (left->op == right->op)
1129 /* compare all the elements depending on type */
1130 if (left->op != IFX)
1132 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1134 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1140 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1142 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1144 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1153 /*-----------------------------------------------------------------*/
1154 /* newiTempFromOp - create a temp Operand with same attributes */
1155 /*-----------------------------------------------------------------*/
1157 newiTempFromOp (operand * op)
1167 nop = newiTempOperand (operandType (op), TRUE);
1168 nop->isaddr = op->isaddr;
1169 nop->isvolatile = op->isvolatile;
1170 nop->isGlobal = op->isGlobal;
1171 nop->isLiteral = op->isLiteral;
1172 nop->usesDefs = op->usesDefs;
1173 nop->isParm = op->isParm;
1177 /*-----------------------------------------------------------------*/
1178 /* operand from operand - creates an operand holder for the type */
1179 /*-----------------------------------------------------------------*/
1181 operandFromOperand (operand * op)
1187 nop = newOperand ();
1188 nop->type = op->type;
1189 nop->isaddr = op->isaddr;
1191 nop->isvolatile = op->isvolatile;
1192 nop->isGlobal = op->isGlobal;
1193 nop->isLiteral = op->isLiteral;
1194 nop->usesDefs = op->usesDefs;
1195 nop->isParm = op->isParm;
1200 nop->operand.symOperand = op->operand.symOperand;
1203 nop->operand.valOperand = op->operand.valOperand;
1206 nop->operand.typeOperand = op->operand.typeOperand;
1213 /*-----------------------------------------------------------------*/
1214 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1215 /*-----------------------------------------------------------------*/
1217 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1219 operand *nop = operandFromOperand (op);
1221 if (nop->type == SYMBOL)
1223 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1224 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1230 /*-----------------------------------------------------------------*/
1231 /* operandFromSymbol - creates an operand from a symbol */
1232 /*-----------------------------------------------------------------*/
1234 operandFromSymbol (symbol * sym)
1239 /* if the symbol's type is a literal */
1240 /* then it is an enumerator type */
1241 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1242 return operandFromValue (valFromType (sym->etype));
1245 sym->key = ++operandKey;
1247 /* if this an implicit variable, means struct/union */
1248 /* member so just return it */
1249 if (sym->implicit || IS_FUNC (sym->type))
1253 op->operand.symOperand = sym;
1255 op->isvolatile = isOperandVolatile (op, TRUE);
1256 op->isGlobal = isOperandGlobal (op);
1260 /* under the following conditions create a
1261 register equivalent for a local symbol */
1262 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1263 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1264 /* (!TARGET_IS_DS390)) && */
1265 (!(options.model == MODEL_FLAT24)) ) &&
1266 options.stackAuto == 0)
1269 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1270 !IS_FUNC (sym->type) && /* not a function */
1271 !sym->_isparm && /* not a parameter */
1272 sym->level && /* is a local variable */
1273 !sym->addrtaken && /* whose address has not been taken */
1274 !sym->reqv && /* does not already have a register euivalence */
1275 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1276 !IS_STATIC (sym->etype) && /* and not declared static */
1277 !sym->islbl && /* not a label */
1278 ok && /* farspace check */
1279 !IS_BITVAR (sym->etype) /* not a bit variable */
1283 /* we will use it after all optimizations
1284 and before liveRange calculation */
1285 sym->reqv = newiTempOperand (sym->type, 0);
1286 sym->reqv->key = sym->key;
1287 OP_SYMBOL (sym->reqv)->key = sym->key;
1288 OP_SYMBOL (sym->reqv)->isreqv = 1;
1289 OP_SYMBOL (sym->reqv)->islocal = 1;
1290 SPIL_LOC (sym->reqv) = sym;
1293 if (!IS_AGGREGATE (sym->type))
1297 op->operand.symOperand = sym;
1300 op->isvolatile = isOperandVolatile (op, TRUE);
1301 op->isGlobal = isOperandGlobal (op);
1302 op->isPtr = IS_PTR (operandType (op));
1303 op->isParm = sym->_isparm;
1308 /* itemp = &[_symbol] */
1310 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1311 IC_LEFT (ic)->type = SYMBOL;
1312 IC_LEFT (ic)->operand.symOperand = sym;
1313 IC_LEFT (ic)->key = sym->key;
1314 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1315 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1316 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1319 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1320 if (IS_ARRAY (sym->type))
1322 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1323 IC_RESULT (ic)->isaddr = 0;
1326 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1328 IC_RESULT (ic)->operand.symOperand->args = sym->args;
1332 return IC_RESULT (ic);
1335 /*-----------------------------------------------------------------*/
1336 /* operandFromValue - creates an operand from value */
1337 /*-----------------------------------------------------------------*/
1339 operandFromValue (value * val)
1343 /* if this is a symbol then do the symbol thing */
1345 return operandFromSymbol (val->sym);
1347 /* this is not a symbol */
1350 op->operand.valOperand = val;
1351 op->isLiteral = isOperandLiteral (op);
1355 /*-----------------------------------------------------------------*/
1356 /* operandFromLink - operand from typeChain */
1357 /*-----------------------------------------------------------------*/
1359 operandFromLink (sym_link * type)
1363 /* operand from sym_link */
1369 op->operand.typeOperand = copyLinkChain (type);
1373 /*-----------------------------------------------------------------*/
1374 /* operandFromLit - makes an operand from a literal value */
1375 /*-----------------------------------------------------------------*/
1377 operandFromLit (double i)
1379 return operandFromValue (valueFromLit (i));
1382 /*-----------------------------------------------------------------*/
1383 /* operandFromAst - creates an operand from an ast */
1384 /*-----------------------------------------------------------------*/
1386 operandFromAst (ast * tree,int lvl)
1392 /* depending on type do */
1396 return ast2iCode (tree,lvl+1);
1400 return operandFromValue (tree->opval.val);
1404 return operandFromLink (tree->opval.lnk);
1408 /* Just to keep the comiler happy */
1409 return (operand *) 0;
1412 /*-----------------------------------------------------------------*/
1413 /* setOperandType - sets the operand's type to the given type */
1414 /*-----------------------------------------------------------------*/
1416 setOperandType (operand * op, sym_link * type)
1418 /* depending on the type of operand */
1423 op->operand.valOperand->etype =
1424 getSpec (op->operand.valOperand->type =
1425 copyLinkChain (type));
1429 if (op->operand.symOperand->isitmp)
1430 op->operand.symOperand->etype =
1431 getSpec (op->operand.symOperand->type =
1432 copyLinkChain (type));
1434 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1435 "attempt to modify type of source");
1439 op->operand.typeOperand = copyLinkChain (type);
1444 /*-----------------------------------------------------------------*/
1445 /* Get size in byte of ptr need to access an array */
1446 /*-----------------------------------------------------------------*/
1448 getArraySizePtr (operand * op)
1450 sym_link *ltype = operandType(op);
1454 int size = getSize(ltype);
1455 return(IS_GENPTR(ltype)?(size-1):size);
1460 sym_link *letype = getSpec(ltype);
1461 switch (PTR_TYPE (SPEC_OCLS (letype)))
1473 return (GPTRSIZE-1);
1482 /*-----------------------------------------------------------------*/
1483 /* perform "usual unary conversions" */
1484 /*-----------------------------------------------------------------*/
1486 usualUnaryConversions (operand * op)
1488 if (IS_INTEGRAL (operandType (op)))
1490 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1493 return geniCodeCast (INTTYPE, op, TRUE);
1499 /*-----------------------------------------------------------------*/
1500 /* perform "usual binary conversions" */
1501 /*-----------------------------------------------------------------*/
1503 usualBinaryConversions (operand ** op1, operand ** op2)
1506 sym_link *rtype = operandType (*op2);
1507 sym_link *ltype = operandType (*op1);
1509 ctype = computeType (ltype, rtype);
1510 *op1 = geniCodeCast (ctype, *op1, TRUE);
1511 *op2 = geniCodeCast (ctype, *op2, TRUE);
1516 /*-----------------------------------------------------------------*/
1517 /* geniCodeValueAtAddress - generate intermeditate code for value */
1519 /*-----------------------------------------------------------------*/
1521 geniCodeRValue (operand * op, bool force)
1524 sym_link *type = operandType (op);
1525 sym_link *etype = getSpec (type);
1527 /* if this is an array & already */
1528 /* an address then return this */
1529 if (IS_AGGREGATE (type) ||
1530 (IS_PTR (type) && !force && !op->isaddr))
1531 return operandFromOperand (op);
1533 /* if this is not an address then must be */
1534 /* rvalue already so return this one */
1538 /* if this is not a temp symbol then */
1539 if (!IS_ITEMP (op) &&
1541 !IN_FARSPACE (SPEC_OCLS (etype)))
1543 op = operandFromOperand (op);
1548 if (IS_SPEC (type) &&
1549 IS_TRUE_SYMOP (op) &&
1550 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1551 /* TARGET_IS_DS390)) */
1552 (options.model == MODEL_FLAT24) ))
1554 op = operandFromOperand (op);
1559 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1560 if (IS_PTR (type) && op->isaddr && force)
1563 type = copyLinkChain (type);
1565 IC_RESULT (ic) = newiTempOperand (type, 1);
1566 IC_RESULT (ic)->isaddr = 0;
1568 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1570 /* if the right is a symbol */
1571 if (op->type == SYMBOL)
1572 IC_RESULT (ic)->operand.symOperand->args =
1573 op->operand.symOperand->args;
1576 return IC_RESULT (ic);
1579 /*-----------------------------------------------------------------*/
1580 /* geniCodeCast - changes the value from one type to another */
1581 /*-----------------------------------------------------------------*/
1583 geniCodeCast (sym_link * type, operand * op, bool implicit)
1587 sym_link *opetype = getSpec (optype = operandType (op));
1591 /* one of them has size zero then error */
1592 if (IS_VOID (optype))
1594 werror (E_CAST_ZERO);
1598 /* if the operand is already the desired type then do nothing */
1599 if (compareType (type, optype) == 1)
1602 /* if this is a literal then just change the type & return */
1603 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1604 return operandFromValue (valCastLiteral (type,
1605 operandLitValue (op)));
1607 /* if casting to/from pointers, do some checking */
1608 if (IS_PTR(type)) { // to a pointer
1609 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1610 if (IS_INTEGRAL(optype)) {
1611 // maybe this is NULL, than it's ok.
1612 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1613 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1614 // no way to set the storage
1615 if (IS_LITERAL(optype)) {
1616 werror(E_LITERAL_GENERIC);
1619 werror(E_NONPTR2_GENPTR);
1622 } else if (implicit) {
1623 werror(W_INTEGRAL2PTR_NOCAST);
1628 // shouldn't do that with float, array or structure unless to void
1629 if (!IS_VOID(getSpec(type)) &&
1630 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1631 werror(E_INCOMPAT_TYPES);
1635 } else { // from a pointer to a pointer
1636 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1637 // if not a pointer to a function
1638 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1639 if (implicit) { // if not to generic, they have to match
1640 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1641 werror(E_INCOMPAT_PTYPES);
1648 } else { // to a non pointer
1649 if (IS_PTR(optype)) { // from a pointer
1650 if (implicit) { // sneaky
1651 if (IS_INTEGRAL(type)) {
1652 werror(W_PTR2INTEGRAL_NOCAST);
1654 } else { // shouldn't do that with float, array or structure
1655 werror(E_INCOMPAT_TYPES);
1662 /* fprintf (stderr, "%s%s %d: ", op->operand.symOperand->name,
1663 implicit?"(implicit)":"", errors); */
1664 fprintf (stderr, "from type '");
1665 printTypeChain (optype, stderr);
1666 fprintf (stderr, "' to type '");
1667 printTypeChain (type, stderr);
1668 fprintf (stderr, "'\n");
1671 /* if they are the same size create an assignment */
1672 if (getSize (type) == getSize (optype) &&
1673 !IS_BITFIELD (type) &&
1675 !IS_FLOAT (optype) &&
1676 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1677 (!IS_SPEC (type) && !IS_SPEC (optype))))
1680 ic = newiCode ('=', NULL, op);
1681 IC_RESULT (ic) = newiTempOperand (type, 0);
1682 SPIL_LOC (IC_RESULT (ic)) =
1683 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1684 IC_RESULT (ic)->isaddr = 0;
1688 ic = newiCode (CAST, operandFromLink (type),
1689 geniCodeRValue (op, FALSE));
1691 IC_RESULT (ic) = newiTempOperand (type, 0);
1694 /* preserve the storage class & output class */
1695 /* of the original variable */
1696 restype = getSpec (operandType (IC_RESULT (ic)));
1697 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1698 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1701 return IC_RESULT (ic);
1704 /*-----------------------------------------------------------------*/
1705 /* geniCodeLabel - will create a Label */
1706 /*-----------------------------------------------------------------*/
1708 geniCodeLabel (symbol * label)
1712 ic = newiCodeLabelGoto (LABEL, label);
1716 /*-----------------------------------------------------------------*/
1717 /* geniCodeGoto - will create a Goto */
1718 /*-----------------------------------------------------------------*/
1720 geniCodeGoto (symbol * label)
1724 ic = newiCodeLabelGoto (GOTO, label);
1728 /*-----------------------------------------------------------------*/
1729 /* geniCodeMultiply - gen intermediate code for multiplication */
1730 /*-----------------------------------------------------------------*/
1732 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1739 /* if they are both literal then we know the result */
1740 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1741 return operandFromValue (valMult (left->operand.valOperand,
1742 right->operand.valOperand));
1744 if (IS_LITERAL(retype)) {
1745 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1748 resType = usualBinaryConversions (&left, &right);
1750 rtype = operandType (right);
1751 retype = getSpec (rtype);
1752 ltype = operandType (left);
1753 letype = getSpec (ltype);
1757 SPEC_NOUN(getSpec(resType))=V_INT;
1760 /* if the right is a literal & power of 2 */
1761 /* then make it a left shift */
1762 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1763 efficient in most cases than 2 bytes result = 2 bytes << literal
1764 if port has 1 byte muldiv */
1765 if (p2 && !IS_FLOAT (letype) &&
1766 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1767 (port->support.muldiv == 1)))
1769 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1771 /* LEFT_OP need same size for left and result, */
1772 left = geniCodeCast (resType, left, TRUE);
1773 ltype = operandType (left);
1775 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1779 ic = newiCode ('*', left, right); /* normal multiplication */
1780 /* if the size left or right > 1 then support routine */
1781 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1785 IC_RESULT (ic) = newiTempOperand (resType, 1);
1788 return IC_RESULT (ic);
1791 /*-----------------------------------------------------------------*/
1792 /* geniCodeDivision - gen intermediate code for division */
1793 /*-----------------------------------------------------------------*/
1795 geniCodeDivision (operand * left, operand * right)
1800 sym_link *rtype = operandType (right);
1801 sym_link *retype = getSpec (rtype);
1802 sym_link *ltype = operandType (left);
1803 sym_link *letype = getSpec (ltype);
1805 resType = usualBinaryConversions (&left, &right);
1807 /* if the right is a literal & power of 2 */
1808 /* then make it a right shift */
1809 if (IS_LITERAL (retype) &&
1810 !IS_FLOAT (letype) &&
1811 (p2 = powof2 ((unsigned long)
1812 floatFromVal (right->operand.valOperand)))) {
1813 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1817 ic = newiCode ('/', left, right); /* normal division */
1818 /* if the size left or right > 1 then support routine */
1819 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1822 IC_RESULT (ic) = newiTempOperand (resType, 0);
1825 return IC_RESULT (ic);
1827 /*-----------------------------------------------------------------*/
1828 /* geniCodeModulus - gen intermediate code for modulus */
1829 /*-----------------------------------------------------------------*/
1831 geniCodeModulus (operand * left, operand * right)
1837 /* if they are both literal then we know the result */
1838 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1839 return operandFromValue (valMod (left->operand.valOperand,
1840 right->operand.valOperand));
1842 resType = usualBinaryConversions (&left, &right);
1844 /* now they are the same size */
1845 ic = newiCode ('%', left, right);
1847 /* if the size left or right > 1 then support routine */
1848 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1850 IC_RESULT (ic) = newiTempOperand (resType, 0);
1853 return IC_RESULT (ic);
1856 /*-----------------------------------------------------------------*/
1857 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1858 /*-----------------------------------------------------------------*/
1860 geniCodePtrPtrSubtract (operand * left, operand * right)
1866 /* if they are both literals then */
1867 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1869 result = operandFromValue (valMinus (left->operand.valOperand,
1870 right->operand.valOperand));
1874 ic = newiCode ('-', left, right);
1876 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1880 return geniCodeDivision (result,
1881 operandFromLit (getSize (ltype->next)));
1884 /*-----------------------------------------------------------------*/
1885 /* geniCodeSubtract - generates code for subtraction */
1886 /*-----------------------------------------------------------------*/
1888 geniCodeSubtract (operand * left, operand * right)
1895 /* if they both pointers then */
1896 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1897 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1898 return geniCodePtrPtrSubtract (left, right);
1900 /* if they are both literal then we know the result */
1901 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1902 && left->isLiteral && right->isLiteral)
1903 return operandFromValue (valMinus (left->operand.valOperand,
1904 right->operand.valOperand));
1906 /* if left is an array or pointer */
1907 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1909 isarray = left->isaddr;
1910 right = geniCodeMultiply (right,
1911 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1912 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1915 { /* make them the same size */
1916 resType = usualBinaryConversions (&left, &right);
1919 ic = newiCode ('-', left, right);
1921 IC_RESULT (ic) = newiTempOperand (resType, 1);
1922 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1924 /* if left or right is a float */
1925 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1929 return IC_RESULT (ic);
1932 /*-----------------------------------------------------------------*/
1933 /* geniCodeAdd - generates iCode for addition */
1934 /*-----------------------------------------------------------------*/
1936 geniCodeAdd (operand * left, operand * right,int lvl)
1944 /* if left is an array then array access */
1945 if (IS_ARRAY (ltype))
1946 return geniCodeArray (left, right,lvl);
1948 /* if the right side is LITERAL zero */
1949 /* return the left side */
1950 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1953 /* if left is literal zero return right */
1954 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1957 /* if left is an array or pointer then size */
1960 isarray = left->isaddr;
1961 // there is no need to multiply with 1
1962 if (getSize(ltype->next)!=1) {
1963 size = operandFromLit (getSize (ltype->next));
1964 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1966 resType = copyLinkChain (ltype);
1969 { /* make them the same size */
1970 resType = usualBinaryConversions (&left, &right);
1973 /* if they are both literals then we know */
1974 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1975 && left->isLiteral && right->isLiteral)
1976 return operandFromValue (valPlus (valFromType (letype),
1977 valFromType (retype)));
1979 ic = newiCode ('+', left, right);
1981 IC_RESULT (ic) = newiTempOperand (resType, 1);
1982 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1984 /* if left or right is a float then support
1986 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1991 return IC_RESULT (ic);
1995 /*-----------------------------------------------------------------*/
1996 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1997 /*-----------------------------------------------------------------*/
1999 aggrToPtr (sym_link * type, bool force)
2005 if (IS_PTR (type) && !force)
2008 etype = getSpec (type);
2012 /* if the output class is generic */
2013 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2014 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2016 /* if the variable was declared a constant */
2017 /* then the pointer points to a constant */
2018 if (IS_CONSTANT (etype))
2019 DCL_PTR_CONST (ptype) = 1;
2021 /* the variable was volatile then pointer to volatile */
2022 if (IS_VOLATILE (etype))
2023 DCL_PTR_VOLATILE (ptype) = 1;
2027 /*-----------------------------------------------------------------*/
2028 /* geniCodeArray2Ptr - array to pointer */
2029 /*-----------------------------------------------------------------*/
2031 geniCodeArray2Ptr (operand * op)
2033 sym_link *optype = operandType (op);
2034 sym_link *opetype = getSpec (optype);
2036 /* set the pointer depending on the storage class */
2037 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2038 DCL_PTR_CONST (optype) = port->mem.code_ro;
2041 /* if the variable was declared a constant */
2042 /* then the pointer points to a constant */
2043 if (IS_CONSTANT (opetype))
2044 DCL_PTR_CONST (optype) = 1;
2046 /* the variable was volatile then pointer to volatile */
2047 if (IS_VOLATILE (opetype))
2048 DCL_PTR_VOLATILE (optype) = 1;
2054 /*-----------------------------------------------------------------*/
2055 /* geniCodeArray - array access */
2056 /*-----------------------------------------------------------------*/
2058 geniCodeArray (operand * left, operand * right,int lvl)
2061 sym_link *ltype = operandType (left);
2065 if (IS_PTR (ltype->next) && left->isaddr)
2067 left = geniCodeRValue (left, FALSE);
2069 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
2072 right = geniCodeMultiply (right,
2073 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2075 /* we can check for limits here */
2076 if (isOperandLiteral (right) &&
2079 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2081 werror (E_ARRAY_BOUND);
2082 right = operandFromLit (0);
2085 ic = newiCode ('+', left, right);
2087 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2088 !IS_AGGREGATE (ltype->next) &&
2089 !IS_PTR (ltype->next))
2090 ? ltype : ltype->next), 0);
2092 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2094 return IC_RESULT (ic);
2097 /*-----------------------------------------------------------------*/
2098 /* geniCodeStruct - generates intermediate code for structres */
2099 /*-----------------------------------------------------------------*/
2101 geniCodeStruct (operand * left, operand * right, bool islval)
2104 sym_link *type = operandType (left);
2105 sym_link *etype = getSpec (type);
2107 symbol *element = getStructElement (SPEC_STRUCT (etype),
2108 right->operand.symOperand);
2110 /* add the offset */
2111 ic = newiCode ('+', left, operandFromLit (element->offset));
2113 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2115 /* preserve the storage & output class of the struct */
2116 /* as well as the volatile attribute */
2117 retype = getSpec (operandType (IC_RESULT (ic)));
2118 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2119 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2120 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2122 if (IS_PTR (element->type))
2123 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2125 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2129 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2132 /*-----------------------------------------------------------------*/
2133 /* geniCodePostInc - generate int code for Post increment */
2134 /*-----------------------------------------------------------------*/
2136 geniCodePostInc (operand * op)
2140 sym_link *optype = operandType (op);
2142 operand *rv = (IS_ITEMP (op) ?
2143 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2145 sym_link *rvtype = operandType (rv);
2148 /* if this is not an address we have trouble */
2151 werror (E_LVALUE_REQUIRED, "++");
2155 rOp = newiTempOperand (rvtype, 0);
2156 OP_SYMBOL(rOp)->noSpilLoc = 1;
2159 OP_SYMBOL(rv)->noSpilLoc = 1;
2161 geniCodeAssign (rOp, rv, 0);
2163 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2164 if (IS_FLOAT (rvtype))
2165 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2167 ic = newiCode ('+', rv, operandFromLit (size));
2169 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2172 geniCodeAssign (op, result, 0);
2178 /*-----------------------------------------------------------------*/
2179 /* geniCodePreInc - generate code for preIncrement */
2180 /*-----------------------------------------------------------------*/
2182 geniCodePreInc (operand * op)
2185 sym_link *optype = operandType (op);
2186 operand *rop = (IS_ITEMP (op) ?
2187 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2189 sym_link *roptype = operandType (rop);
2195 werror (E_LVALUE_REQUIRED, "++");
2200 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2201 if (IS_FLOAT (roptype))
2202 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2204 ic = newiCode ('+', rop, operandFromLit (size));
2205 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2209 return geniCodeAssign (op, result, 0);
2212 /*-----------------------------------------------------------------*/
2213 /* geniCodePostDec - generates code for Post decrement */
2214 /*-----------------------------------------------------------------*/
2216 geniCodePostDec (operand * op)
2220 sym_link *optype = operandType (op);
2222 operand *rv = (IS_ITEMP (op) ?
2223 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2225 sym_link *rvtype = operandType (rv);
2228 /* if this is not an address we have trouble */
2231 werror (E_LVALUE_REQUIRED, "--");
2235 rOp = newiTempOperand (rvtype, 0);
2236 OP_SYMBOL(rOp)->noSpilLoc = 1;
2239 OP_SYMBOL(rv)->noSpilLoc = 1;
2241 geniCodeAssign (rOp, rv, 0);
2243 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2244 if (IS_FLOAT (rvtype))
2245 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2247 ic = newiCode ('-', rv, operandFromLit (size));
2249 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2252 geniCodeAssign (op, result, 0);
2258 /*-----------------------------------------------------------------*/
2259 /* geniCodePreDec - generate code for pre decrement */
2260 /*-----------------------------------------------------------------*/
2262 geniCodePreDec (operand * op)
2265 sym_link *optype = operandType (op);
2266 operand *rop = (IS_ITEMP (op) ?
2267 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2269 sym_link *roptype = operandType (rop);
2275 werror (E_LVALUE_REQUIRED, "--");
2280 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2281 if (IS_FLOAT (roptype))
2282 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2284 ic = newiCode ('-', rop, operandFromLit (size));
2285 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2289 return geniCodeAssign (op, result, 0);
2293 /*-----------------------------------------------------------------*/
2294 /* geniCodeBitwise - gen int code for bitWise operators */
2295 /*-----------------------------------------------------------------*/
2297 geniCodeBitwise (operand * left, operand * right,
2298 int oper, sym_link * resType)
2302 left = geniCodeCast (resType, left, TRUE);
2303 right = geniCodeCast (resType, right, TRUE);
2305 ic = newiCode (oper, left, right);
2306 IC_RESULT (ic) = newiTempOperand (resType, 0);
2309 return IC_RESULT (ic);
2312 /*-----------------------------------------------------------------*/
2313 /* geniCodeAddressOf - gens icode for '&' address of operator */
2314 /*-----------------------------------------------------------------*/
2316 geniCodeAddressOf (operand * op)
2320 sym_link *optype = operandType (op);
2321 sym_link *opetype = getSpec (optype);
2323 /* lvalue check already done in decorateType */
2324 /* this must be a lvalue */
2325 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2326 /* werror (E_LVALUE_REQUIRED,"&"); */
2331 p->class = DECLARATOR;
2333 /* set the pointer depending on the storage class */
2334 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2335 DCL_PTR_CONST (p) = port->mem.code_ro;
2337 /* make sure we preserve the const & volatile */
2338 if (IS_CONSTANT (opetype))
2339 DCL_PTR_CONST (p) = 1;
2341 if (IS_VOLATILE (opetype))
2342 DCL_PTR_VOLATILE (p) = 1;
2344 p->next = copyLinkChain (optype);
2346 /* if already a temp */
2349 setOperandType (op, p);
2354 /* other wise make this of the type coming in */
2355 ic = newiCode (ADDRESS_OF, op, NULL);
2356 IC_RESULT (ic) = newiTempOperand (p, 1);
2357 IC_RESULT (ic)->isaddr = 0;
2359 return IC_RESULT (ic);
2361 /*-----------------------------------------------------------------*/
2362 /* setOClass - sets the output class depending on the pointer type */
2363 /*-----------------------------------------------------------------*/
2365 setOClass (sym_link * ptr, sym_link * spec)
2367 switch (DCL_TYPE (ptr))
2370 SPEC_OCLS (spec) = data;
2374 SPEC_OCLS (spec) = generic;
2378 SPEC_OCLS (spec) = xdata;
2382 SPEC_OCLS (spec) = code;
2386 SPEC_OCLS (spec) = idata;
2390 SPEC_OCLS (spec) = xstack;
2394 SPEC_OCLS (spec) = eeprom;
2403 /*-----------------------------------------------------------------*/
2404 /* geniCodeDerefPtr - dereference pointer with '*' */
2405 /*-----------------------------------------------------------------*/
2407 geniCodeDerefPtr (operand * op,int lvl)
2409 sym_link *rtype, *retype;
2410 sym_link *optype = operandType (op);
2412 /* if this is a pointer then generate the rvalue */
2413 if (IS_PTR (optype))
2415 if (IS_TRUE_SYMOP (op))
2418 op = geniCodeRValue (op, TRUE);
2421 op = geniCodeRValue (op, TRUE);
2424 /* now get rid of the pointer part */
2425 if (isLvaluereq(lvl) && IS_ITEMP (op))
2427 retype = getSpec (rtype = copyLinkChain (optype));
2431 retype = getSpec (rtype = copyLinkChain (optype->next));
2434 /* if this is a pointer then outputclass needs 2b updated */
2435 if (IS_PTR (optype))
2436 setOClass (optype, retype);
2438 op->isGptr = IS_GENPTR (optype);
2440 /* if the pointer was declared as a constant */
2441 /* then we cannot allow assignment to the derefed */
2442 if (IS_PTR_CONST (optype))
2443 SPEC_CONST (retype) = 1;
2445 op->isaddr = (IS_PTR (rtype) ||
2446 IS_STRUCT (rtype) ||
2451 if (!isLvaluereq(lvl))
2452 op = geniCodeRValue (op, TRUE);
2454 setOperandType (op, rtype);
2459 /*-----------------------------------------------------------------*/
2460 /* geniCodeUnaryMinus - does a unary minus of the operand */
2461 /*-----------------------------------------------------------------*/
2463 geniCodeUnaryMinus (operand * op)
2466 sym_link *optype = operandType (op);
2468 if (IS_LITERAL (optype))
2469 return operandFromLit (-floatFromVal (op->operand.valOperand));
2471 ic = newiCode (UNARYMINUS, op, NULL);
2472 IC_RESULT (ic) = newiTempOperand (optype, 0);
2474 return IC_RESULT (ic);
2477 /*-----------------------------------------------------------------*/
2478 /* geniCodeLeftShift - gen i code for left shift */
2479 /*-----------------------------------------------------------------*/
2481 geniCodeLeftShift (operand * left, operand * right)
2485 ic = newiCode (LEFT_OP, left, right);
2486 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2488 return IC_RESULT (ic);
2491 /*-----------------------------------------------------------------*/
2492 /* geniCodeRightShift - gen i code for right shift */
2493 /*-----------------------------------------------------------------*/
2495 geniCodeRightShift (operand * left, operand * right)
2499 ic = newiCode (RIGHT_OP, left, right);
2500 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2502 return IC_RESULT (ic);
2505 /*-----------------------------------------------------------------*/
2506 /* geniCodeLogic- logic code */
2507 /*-----------------------------------------------------------------*/
2509 geniCodeLogic (operand * left, operand * right, int op)
2513 sym_link *rtype = operandType (right);
2514 sym_link *ltype = operandType (left);
2516 /* left is integral type and right is literal then
2517 check if the literal value is within bounds */
2518 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2520 checkConstantRange(ltype,
2521 OP_VALUE(right), "compare operation", 1);
2524 ctype = usualBinaryConversions (&left, &right);
2526 ic = newiCode (op, left, right);
2527 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2529 /* if comparing float
2530 and not a '==' || '!=' || '&&' || '||' (these
2532 if (IS_FLOAT(ctype) &&
2540 return IC_RESULT (ic);
2543 /*-----------------------------------------------------------------*/
2544 /* geniCodeUnary - for a a generic unary operation */
2545 /*-----------------------------------------------------------------*/
2547 geniCodeUnary (operand * op, int oper)
2549 iCode *ic = newiCode (oper, op, NULL);
2551 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2553 return IC_RESULT (ic);
2556 /*-----------------------------------------------------------------*/
2557 /* geniCodeConditional - geniCode for '?' ':' operation */
2558 /*-----------------------------------------------------------------*/
2560 geniCodeConditional (ast * tree,int lvl)
2563 symbol *falseLabel = newiTempLabel (NULL);
2564 symbol *exitLabel = newiTempLabel (NULL);
2565 operand *cond = ast2iCode (tree->left,lvl+1);
2566 operand *true, *false, *result;
2568 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2572 true = ast2iCode (tree->right->left,lvl+1);
2574 /* move the value to a new Operand */
2575 result = newiTempOperand (operandType (true), 0);
2576 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2578 /* generate an unconditional goto */
2579 geniCodeGoto (exitLabel);
2581 /* now for the right side */
2582 geniCodeLabel (falseLabel);
2584 false = ast2iCode (tree->right->right,lvl+1);
2585 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2587 /* create the exit label */
2588 geniCodeLabel (exitLabel);
2593 /*-----------------------------------------------------------------*/
2594 /* geniCodeAssign - generate code for assignment */
2595 /*-----------------------------------------------------------------*/
2597 geniCodeAssign (operand * left, operand * right, int nosupdate)
2600 sym_link *ltype = operandType (left);
2601 sym_link *rtype = operandType (right);
2603 if (!left->isaddr && !IS_ITEMP (left))
2605 werror (E_LVALUE_REQUIRED, "assignment");
2609 /* left is integral type and right is literal then
2610 check if the literal value is within bounds */
2611 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2613 checkConstantRange(ltype,
2614 OP_VALUE(right), "= operation", 0);
2617 /* if the left & right type don't exactly match */
2618 /* if pointer set then make sure the check is
2619 done with the type & not the pointer */
2620 /* then cast rights type to left */
2622 /* first check the type for pointer assignement */
2623 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2624 compareType (ltype, rtype) < 0)
2626 if (compareType (ltype->next, rtype) < 0)
2627 right = geniCodeCast (ltype->next, right, TRUE);
2629 else if (compareType (ltype, rtype) < 0)
2630 right = geniCodeCast (ltype, right, TRUE);
2632 /* if left is a true symbol & ! volatile
2633 create an assignment to temporary for
2634 the right & then assign this temporary
2635 to the symbol this is SSA . isn't it simple
2636 and folks have published mountains of paper on it */
2637 if (IS_TRUE_SYMOP (left) &&
2638 !isOperandVolatile (left, FALSE) &&
2639 isOperandGlobal (left))
2643 if (IS_TRUE_SYMOP (right))
2644 sym = OP_SYMBOL (right);
2645 ic = newiCode ('=', NULL, right);
2646 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2647 SPIL_LOC (right) = sym;
2651 ic = newiCode ('=', NULL, right);
2652 IC_RESULT (ic) = left;
2655 /* if left isgptr flag is set then support
2656 routine will be required */
2660 ic->nosupdate = nosupdate;
2664 /*-----------------------------------------------------------------*/
2665 /* geniCodeSEParms - generate code for side effecting fcalls */
2666 /*-----------------------------------------------------------------*/
2668 geniCodeSEParms (ast * parms,int lvl)
2673 if (parms->type == EX_OP && parms->opval.op == PARAM)
2675 geniCodeSEParms (parms->left,lvl);
2676 geniCodeSEParms (parms->right,lvl);
2680 /* hack don't like this but too lazy to think of
2682 if (IS_ADDRESS_OF_OP (parms))
2683 parms->left->lvalue = 1;
2685 if (IS_CAST_OP (parms) &&
2686 IS_PTR (parms->ftype) &&
2687 IS_ADDRESS_OF_OP (parms->right))
2688 parms->right->left->lvalue = 1;
2690 parms->opval.oprnd =
2691 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2693 parms->type = EX_OPERAND;
2696 /*-----------------------------------------------------------------*/
2697 /* geniCodeParms - generates parameters */
2698 /*-----------------------------------------------------------------*/
2700 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl)
2708 /* if this is a param node then do the left & right */
2709 if (parms->type == EX_OP && parms->opval.op == PARAM)
2711 geniCodeParms (parms->left, stack, fetype, func,lvl);
2712 geniCodeParms (parms->right, stack, fetype, func,lvl);
2716 /* get the parameter value */
2717 if (parms->type == EX_OPERAND)
2718 pval = parms->opval.oprnd;
2721 /* maybe this else should go away ?? */
2722 /* hack don't like this but too lazy to think of
2724 if (IS_ADDRESS_OF_OP (parms))
2725 parms->left->lvalue = 1;
2727 if (IS_CAST_OP (parms) &&
2728 IS_PTR (parms->ftype) &&
2729 IS_ADDRESS_OF_OP (parms->right))
2730 parms->right->left->lvalue = 1;
2732 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2735 /* if register parm then make it a send */
2736 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2737 IS_REGPARM (parms->etype)) && !func->hasVargs)
2739 ic = newiCode (SEND, pval, NULL);
2744 /* now decide whether to push or assign */
2745 if (!(options.stackAuto || IS_RENT (fetype)))
2749 operand *top = operandFromSymbol (parms->argSym);
2750 geniCodeAssign (top, pval, 1);
2754 sym_link *p = operandType (pval);
2756 ic = newiCode (IPUSH, pval, NULL);
2758 /* update the stack adjustment */
2759 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2766 /*-----------------------------------------------------------------*/
2767 /* geniCodeCall - generates temp code for calling */
2768 /*-----------------------------------------------------------------*/
2770 geniCodeCall (operand * left, ast * parms,int lvl)
2774 sym_link *type, *etype;
2777 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2778 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2779 werror (E_FUNCTION_EXPECTED);
2783 /* take care of parameters with side-effecting
2784 function calls in them, this is required to take care
2785 of overlaying function parameters */
2786 geniCodeSEParms (parms,lvl);
2788 /* first the parameters */
2789 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2791 /* now call : if symbol then pcall */
2792 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2793 ic = newiCode (PCALL, left, NULL);
2795 ic = newiCode (CALL, left, NULL);
2797 IC_ARGS (ic) = left->operand.symOperand->args;
2798 type = copyLinkChain (operandType (left)->next);
2799 etype = getSpec (type);
2800 SPEC_EXTR (etype) = 0;
2801 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2805 /* stack adjustment after call */
2806 ic->parmBytes = stack;
2811 /*-----------------------------------------------------------------*/
2812 /* geniCodeReceive - generate intermediate code for "receive" */
2813 /*-----------------------------------------------------------------*/
2815 geniCodeReceive (value * args)
2817 /* for all arguments that are passed in registers */
2821 if (IS_REGPARM (args->etype))
2823 operand *opr = operandFromValue (args);
2825 symbol *sym = OP_SYMBOL (opr);
2828 /* we will use it after all optimizations
2829 and before liveRange calculation */
2830 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2833 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2834 options.stackAuto == 0 &&
2835 /* !TARGET_IS_DS390) */
2836 (!(options.model == MODEL_FLAT24)) )
2841 opl = newiTempOperand (args->type, 0);
2843 sym->reqv->key = sym->key;
2844 OP_SYMBOL (sym->reqv)->key = sym->key;
2845 OP_SYMBOL (sym->reqv)->isreqv = 1;
2846 OP_SYMBOL (sym->reqv)->islocal = 0;
2847 SPIL_LOC (sym->reqv) = sym;
2851 ic = newiCode (RECEIVE, NULL, NULL);
2852 currFunc->recvSize = getSize (sym->etype);
2853 IC_RESULT (ic) = opr;
2861 /*-----------------------------------------------------------------*/
2862 /* geniCodeFunctionBody - create the function body */
2863 /*-----------------------------------------------------------------*/
2865 geniCodeFunctionBody (ast * tree,int lvl)
2872 /* reset the auto generation */
2878 func = ast2iCode (tree->left,lvl+1);
2879 fetype = getSpec (operandType (func));
2881 savelineno = lineno;
2882 lineno = OP_SYMBOL (func)->lineDef;
2883 /* create an entry label */
2884 geniCodeLabel (entryLabel);
2885 lineno = savelineno;
2887 /* create a proc icode */
2888 ic = newiCode (FUNCTION, func, NULL);
2889 /* if the function has parmas then */
2890 /* save the parameters information */
2891 ic->argLabel.args = tree->values.args;
2892 ic->lineno = OP_SYMBOL (func)->lineDef;
2896 /* for all parameters that are passed
2897 on registers add a "receive" */
2898 geniCodeReceive (tree->values.args);
2900 /* generate code for the body */
2901 ast2iCode (tree->right,lvl+1);
2903 /* create a label for return */
2904 geniCodeLabel (returnLabel);
2906 /* now generate the end proc */
2907 ic = newiCode (ENDFUNCTION, func, NULL);
2912 /*-----------------------------------------------------------------*/
2913 /* geniCodeReturn - gen icode for 'return' statement */
2914 /*-----------------------------------------------------------------*/
2916 geniCodeReturn (operand * op)
2920 /* if the operand is present force an rvalue */
2922 op = geniCodeRValue (op, FALSE);
2924 ic = newiCode (RETURN, op, NULL);
2928 /*-----------------------------------------------------------------*/
2929 /* geniCodeIfx - generates code for extended if statement */
2930 /*-----------------------------------------------------------------*/
2932 geniCodeIfx (ast * tree,int lvl)
2935 operand *condition = ast2iCode (tree->left,lvl+1);
2938 /* if condition is null then exit */
2942 condition = geniCodeRValue (condition, FALSE);
2944 cetype = getSpec (operandType (condition));
2945 /* if the condition is a literal */
2946 if (IS_LITERAL (cetype))
2948 if (floatFromVal (condition->operand.valOperand))
2950 if (tree->trueLabel)
2951 geniCodeGoto (tree->trueLabel);
2957 if (tree->falseLabel)
2958 geniCodeGoto (tree->falseLabel);
2965 if (tree->trueLabel)
2967 ic = newiCodeCondition (condition,
2972 if (tree->falseLabel)
2973 geniCodeGoto (tree->falseLabel);
2977 ic = newiCodeCondition (condition,
2984 ast2iCode (tree->right,lvl+1);
2987 /*-----------------------------------------------------------------*/
2988 /* geniCodeJumpTable - tries to create a jump table for switch */
2989 /*-----------------------------------------------------------------*/
2991 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2993 int min = 0, max = 0, t, cnt = 0;
3000 if (!tree || !caseVals)
3003 /* the criteria for creating a jump table is */
3004 /* all integer numbers between the maximum & minimum must */
3005 /* be present , the maximum value should not exceed 255 */
3006 min = max = (int) floatFromVal (vch = caseVals);
3007 sprintf (buffer, "_case_%d_%d",
3008 tree->values.switchVals.swNum,
3010 addSet (&labels, newiTempLabel (buffer));
3012 /* if there is only one case value then no need */
3013 if (!(vch = vch->next))
3018 if (((t = (int) floatFromVal (vch)) - max) != 1)
3020 sprintf (buffer, "_case_%d_%d",
3021 tree->values.switchVals.swNum,
3023 addSet (&labels, newiTempLabel (buffer));
3029 /* if the number of case statements <= 2 then */
3030 /* it is not economical to create the jump table */
3031 /* since two compares are needed for boundary conditions */
3032 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3035 if (tree->values.switchVals.swDefault)
3036 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3038 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3040 falseLabel = newiTempLabel (buffer);
3042 /* so we can create a jumptable */
3043 /* first we rule out the boundary conditions */
3044 /* if only optimization says so */
3045 if (!optimize.noJTabBoundary)
3047 sym_link *cetype = getSpec (operandType (cond));
3048 /* no need to check the lower bound if
3049 the condition is unsigned & minimum value is zero */
3050 if (!(min == 0 && SPEC_USIGN (cetype)))
3052 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3053 ic = newiCodeCondition (boundary, falseLabel, NULL);
3057 /* now for upper bounds */
3058 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3059 ic = newiCodeCondition (boundary, falseLabel, NULL);
3063 /* if the min is not zero then we no make it zero */
3066 cond = geniCodeSubtract (cond, operandFromLit (min));
3067 setOperandType (cond, UCHARTYPE);
3070 /* now create the jumptable */
3071 ic = newiCode (JUMPTABLE, NULL, NULL);
3072 IC_JTCOND (ic) = cond;
3073 IC_JTLABELS (ic) = labels;
3078 /*-----------------------------------------------------------------*/
3079 /* geniCodeSwitch - changes a switch to a if statement */
3080 /*-----------------------------------------------------------------*/
3082 geniCodeSwitch (ast * tree,int lvl)
3085 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3086 value *caseVals = tree->values.switchVals.swVals;
3087 symbol *trueLabel, *falseLabel;
3089 /* if we can make this a jump table */
3090 if (geniCodeJumpTable (cond, caseVals, tree))
3091 goto jumpTable; /* no need for the comparison */
3093 /* for the cases defined do */
3097 operand *compare = geniCodeLogic (cond,
3098 operandFromValue (caseVals),
3101 sprintf (buffer, "_case_%d_%d",
3102 tree->values.switchVals.swNum,
3103 (int) floatFromVal (caseVals));
3104 trueLabel = newiTempLabel (buffer);
3106 ic = newiCodeCondition (compare, trueLabel, NULL);
3108 caseVals = caseVals->next;
3113 /* if default is present then goto break else break */
3114 if (tree->values.switchVals.swDefault)
3115 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3117 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3119 falseLabel = newiTempLabel (buffer);
3120 geniCodeGoto (falseLabel);
3123 ast2iCode (tree->right,lvl+1);
3126 /*-----------------------------------------------------------------*/
3127 /* geniCodeInline - intermediate code for inline assembler */
3128 /*-----------------------------------------------------------------*/
3130 geniCodeInline (ast * tree)
3134 ic = newiCode (INLINEASM, NULL, NULL);
3135 IC_INLINE (ic) = tree->values.inlineasm;
3139 /*-----------------------------------------------------------------*/
3140 /* geniCodeArrayInit - intermediate code for array initializer */
3141 /*-----------------------------------------------------------------*/
3143 geniCodeArrayInit (ast * tree, operand *array)
3147 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3148 ic = newiCode (ARRAYINIT, array, NULL);
3149 IC_ARRAYILIST (ic) = tree->values.constlist;
3151 operand *left=newOperand(), *right=newOperand();
3152 left->type=right->type=SYMBOL;
3153 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3154 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3155 ic = newiCode (ARRAYINIT, left, right);
3160 /*-----------------------------------------------------------------*/
3161 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3162 /* particular case. Ie : assigning or dereferencing array or ptr */
3163 /*-----------------------------------------------------------------*/
3164 set * lvaluereqSet = NULL;
3165 typedef struct lvalItem
3172 /*-----------------------------------------------------------------*/
3173 /* addLvaluereq - add a flag for lvalreq for current ast level */
3174 /*-----------------------------------------------------------------*/
3175 void addLvaluereq(int lvl)
3177 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3180 addSetHead(&lvaluereqSet,lpItem);
3183 /*-----------------------------------------------------------------*/
3184 /* delLvaluereq - del a flag for lvalreq for current ast level */
3185 /*-----------------------------------------------------------------*/
3189 lpItem = getSet(&lvaluereqSet);
3190 if(lpItem) Safe_free(lpItem);
3192 /*-----------------------------------------------------------------*/
3193 /* clearLvaluereq - clear lvalreq flag */
3194 /*-----------------------------------------------------------------*/
3195 void clearLvaluereq()
3198 lpItem = peekSet(lvaluereqSet);
3199 if(lpItem) lpItem->req = 0;
3201 /*-----------------------------------------------------------------*/
3202 /* getLvaluereq - get the last lvalreq level */
3203 /*-----------------------------------------------------------------*/
3204 int getLvaluereqLvl()
3207 lpItem = peekSet(lvaluereqSet);
3208 if(lpItem) return lpItem->lvl;
3211 /*-----------------------------------------------------------------*/
3212 /* isLvaluereq - is lvalreq valid for this level ? */
3213 /*-----------------------------------------------------------------*/
3214 int isLvaluereq(int lvl)
3217 lpItem = peekSet(lvaluereqSet);
3218 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3222 /*-----------------------------------------------------------------*/
3223 /* ast2iCode - creates an icodeList from an ast */
3224 /*-----------------------------------------------------------------*/
3226 ast2iCode (ast * tree,int lvl)
3228 operand *left = NULL;
3229 operand *right = NULL;
3232 /* set the global variables for filename & line number */
3234 filename = tree->filename;
3236 lineno = tree->lineno;
3238 block = tree->block;
3240 scopeLevel = tree->level;
3242 if (tree->type == EX_VALUE)
3243 return operandFromValue (tree->opval.val);
3245 if (tree->type == EX_LINK)
3246 return operandFromLink (tree->opval.lnk);
3248 /* if we find a nullop */
3249 if (tree->type == EX_OP &&
3250 (tree->opval.op == NULLOP ||
3251 tree->opval.op == BLOCK))
3253 ast2iCode (tree->left,lvl+1);
3254 ast2iCode (tree->right,lvl+1);
3258 /* special cases for not evaluating */
3259 if (tree->opval.op != ':' &&
3260 tree->opval.op != '?' &&
3261 tree->opval.op != CALL &&
3262 tree->opval.op != IFX &&
3263 tree->opval.op != LABEL &&
3264 tree->opval.op != GOTO &&
3265 tree->opval.op != SWITCH &&
3266 tree->opval.op != FUNCTION &&
3267 tree->opval.op != INLINEASM)
3270 if (IS_ASSIGN_OP (tree->opval.op) ||
3271 IS_DEREF_OP (tree) ||
3272 (tree->opval.op == '&' && !tree->right) ||
3273 tree->opval.op == PTR_OP)
3276 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3277 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3280 left = operandFromAst (tree->left,lvl);
3282 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3283 left = geniCodeRValue (left, TRUE);
3287 left = operandFromAst (tree->left,lvl);
3289 if (tree->opval.op == INC_OP ||
3290 tree->opval.op == DEC_OP)
3293 right = operandFromAst (tree->right,lvl);
3298 right = operandFromAst (tree->right,lvl);
3302 /* now depending on the type of operand */
3303 /* this will be a biggy */
3304 switch (tree->opval.op)
3307 case '[': /* array operation */
3309 //sym_link *ltype = operandType (left);
3310 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3311 left = geniCodeRValue (left, FALSE);
3312 right = geniCodeRValue (right, TRUE);
3315 return geniCodeArray (left, right,lvl);
3317 case '.': /* structure dereference */
3318 if (IS_PTR (operandType (left)))
3319 left = geniCodeRValue (left, TRUE);
3321 left = geniCodeRValue (left, FALSE);
3323 return geniCodeStruct (left, right, tree->lvalue);
3325 case PTR_OP: /* structure pointer dereference */
3328 pType = operandType (left);
3329 left = geniCodeRValue (left, TRUE);
3331 setOClass (pType, getSpec (operandType (left)));
3334 return geniCodeStruct (left, right, tree->lvalue);
3336 case INC_OP: /* increment operator */
3338 return geniCodePostInc (left);
3340 return geniCodePreInc (right);
3342 case DEC_OP: /* decrement operator */
3344 return geniCodePostDec (left);
3346 return geniCodePreDec (right);
3348 case '&': /* bitwise and or address of operator */
3350 { /* this is a bitwise operator */
3351 left = geniCodeRValue (left, FALSE);
3352 right = geniCodeRValue (right, FALSE);
3353 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3356 return geniCodeAddressOf (left);
3358 case '|': /* bitwise or & xor */
3360 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3361 geniCodeRValue (right, FALSE),
3366 return geniCodeDivision (geniCodeRValue (left, FALSE),
3367 geniCodeRValue (right, FALSE));
3370 return geniCodeModulus (geniCodeRValue (left, FALSE),
3371 geniCodeRValue (right, FALSE));
3374 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3375 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3377 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3381 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3382 geniCodeRValue (right, FALSE));
3384 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3388 return geniCodeAdd (geniCodeRValue (left, FALSE),
3389 geniCodeRValue (right, FALSE),lvl);
3391 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3394 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3395 geniCodeRValue (right, FALSE));
3398 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3399 geniCodeRValue (right, FALSE));
3401 return geniCodeCast (operandType (left),
3402 geniCodeRValue (right, FALSE), FALSE);
3408 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3412 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3413 setOperandType (op, UCHARTYPE);
3424 return geniCodeLogic (geniCodeRValue (left, FALSE),
3425 geniCodeRValue (right, FALSE),
3428 return geniCodeConditional (tree,lvl);
3431 return operandFromLit (getSize (tree->right->ftype));
3435 sym_link *rtype = operandType (right);
3436 sym_link *ltype = operandType (left);
3437 if (IS_PTR (rtype) && IS_ITEMP (right)
3438 && right->isaddr && compareType (rtype->next, ltype) == 1)
3439 right = geniCodeRValue (right, TRUE);
3441 right = geniCodeRValue (right, FALSE);
3443 geniCodeAssign (left, right, 0);
3448 geniCodeAssign (left,
3449 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3451 geniCodeRValue (right, FALSE),FALSE), 0);
3455 geniCodeAssign (left,
3456 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3458 geniCodeRValue (right, FALSE)), 0);
3461 geniCodeAssign (left,
3462 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3464 geniCodeRValue (right, FALSE)), 0);
3467 sym_link *rtype = operandType (right);
3468 sym_link *ltype = operandType (left);
3469 if (IS_PTR (rtype) && IS_ITEMP (right)
3470 && right->isaddr && compareType (rtype->next, ltype) == 1)
3471 right = geniCodeRValue (right, TRUE);
3473 right = geniCodeRValue (right, FALSE);
3476 return geniCodeAssign (left,
3477 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3483 sym_link *rtype = operandType (right);
3484 sym_link *ltype = operandType (left);
3485 if (IS_PTR (rtype) && IS_ITEMP (right)
3486 && right->isaddr && compareType (rtype->next, ltype) == 1)
3488 right = geniCodeRValue (right, TRUE);
3492 right = geniCodeRValue (right, FALSE);
3495 geniCodeAssign (left,
3496 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3502 geniCodeAssign (left,
3503 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3505 geniCodeRValue (right, FALSE)), 0);
3508 geniCodeAssign (left,
3509 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3511 geniCodeRValue (right, FALSE)), 0);
3514 geniCodeAssign (left,
3515 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3517 geniCodeRValue (right, FALSE),
3519 operandType (left)), 0);
3522 geniCodeAssign (left,
3523 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3525 geniCodeRValue (right, FALSE),
3527 operandType (left)), 0);
3530 geniCodeAssign (left,
3531 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3533 geniCodeRValue (right, FALSE),
3535 operandType (left)), 0);
3537 return geniCodeRValue (right, FALSE);
3540 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3543 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3544 return ast2iCode (tree->right,lvl+1);
3547 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3548 return ast2iCode (tree->right,lvl+1);
3551 geniCodeFunctionBody (tree,lvl);
3555 geniCodeReturn (right);
3559 geniCodeIfx (tree,lvl);
3563 geniCodeSwitch (tree,lvl);
3567 geniCodeInline (tree);
3571 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3578 /*-----------------------------------------------------------------*/
3579 /* reverseICChain - gets from the list and creates a linkedlist */
3580 /*-----------------------------------------------------------------*/
3587 while ((loop = getSet (&iCodeChain)))
3599 /*-----------------------------------------------------------------*/
3600 /* iCodeFromAst - given an ast will convert it to iCode */
3601 /*-----------------------------------------------------------------*/
3603 iCodeFromAst (ast * tree)
3605 returnLabel = newiTempLabel ("_return");
3606 entryLabel = newiTempLabel ("_entry");
3608 return reverseiCChain ();