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 -------------------------------------------------------------------------*/
25 #include "SDCCglobl.h"
29 #include "SDCChasht.h"
30 #include "SDCCicode.h"
32 #include "SDCCralloc.h"
34 /*-----------------------------------------------------------------*/
35 /* global variables */
37 set *iCodeChain = NULL ;
50 symbol *returnLabel ; /* function return label */
51 symbol *entryLabel ; /* function entry label */
52 /*-----------------------------------------------------------------*/
53 /* forward definition of some functions */
54 operand *geniCodeDivision (operand *,operand *);
55 operand *geniCodeAssign (operand *,operand *,int);
56 operand *geniCodeArray (operand *,operand *);
57 operand *geniCodeArray2Ptr (operand *);
58 operand *geniCodeRValue (operand *, bool );
59 operand *geniCodeDerefPtr (operand *);
61 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
63 /* forward definition of print functions */
64 PRINTFUNC(picGetValueAtAddr);
65 PRINTFUNC(picSetValueAtAddr);
67 PRINTFUNC(picGeneric);
68 PRINTFUNC(picGenericOne);
70 PRINTFUNC(picIncrement);
71 PRINTFUNC(picDecrement);
76 PRINTFUNC(picJumpTable);
78 PRINTFUNC(picReceive);
80 iCodeTable codeTable[] = {
81 { '!' , "not", picGenericOne , NULL },
82 { '~' , "~" , picGenericOne , NULL },
83 { RRC , "rrc", picGenericOne , NULL },
84 { RLC , "rlc", picGenericOne , NULL },
85 { GETHBIT ,"ghbit", picGenericOne , NULL },
86 { UNARYMINUS , "-" , picGenericOne , NULL },
87 { IPUSH , "push",picGenericOne , NULL },
88 { IPOP , "pop", picGenericOne , NULL },
89 { CALL , "call",picGenericOne , NULL },
90 { PCALL , "pcall",picGenericOne , NULL },
91 { FUNCTION , "proc", picGenericOne , NULL },
92 { ENDFUNCTION ,"eproc", picGenericOne , NULL },
93 { RETURN , "ret", picGenericOne , NULL },
94 { '+' , "+" , picGeneric , NULL },
95 { '-' , "-" , picGeneric , NULL },
96 { '*' , "*" , picGeneric , NULL },
97 { '/' , "/" , picGeneric , NULL },
98 { '%' , "%" , picGeneric , NULL },
99 { '>' , ">" , picGeneric , NULL },
100 { '<' , "<" , picGeneric , NULL },
101 { LE_OP , "<=" , picGeneric , NULL },
102 { GE_OP , ">=" , picGeneric , NULL },
103 { EQ_OP , "==" , picGeneric , NULL },
104 { NE_OP , "!=" , picGeneric , NULL },
105 { AND_OP , "&&" , picGeneric , NULL },
106 { OR_OP , "||" , picGeneric , NULL },
107 { '^' , "^" , picGeneric , NULL },
108 { '|' , "|" , picGeneric , NULL },
109 { BITWISEAND , "&" , picGeneric , NULL },
110 { LEFT_OP , "<<" , picGeneric , NULL },
111 { RIGHT_OP , ">>" , picGeneric , NULL },
112 { GET_VALUE_AT_ADDRESS, "@" , picGetValueAtAddr, NULL },
113 { ADDRESS_OF , "&" , picAddrOf , NULL },
114 { CAST , "<>" , picCast , NULL },
115 { '=' , ":=" , picAssign , NULL },
116 { LABEL , "" , picLabel , NULL },
117 { GOTO , "" , picGoto , NULL },
118 { JUMPTABLE ,"jtab" , picJumpTable , NULL },
119 { IFX , "if" , picIfx , NULL },
120 { INLINEASM , "" , picInline , NULL },
121 { RECEIVE , "recv", picReceive , NULL },
122 { SEND , "send", picGenericOne , NULL }
126 /*-----------------------------------------------------------------*/
127 /* operandName - returns the name of the operand */
128 /*-----------------------------------------------------------------*/
129 int printOperand (operand *op, FILE *file)
144 opetype = getSpec (operandType(op));
145 if (SPEC_NOUN(opetype) == V_FLOAT)
146 fprintf (file,"%g {", SPEC_CVAL(opetype).v_float);
148 fprintf (file,"0x%x {",(int) floatFromVal(op->operand.valOperand));
149 printTypeChain(operandType(op),file);
156 fprintf (file,"%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d}",/*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" ,*/
157 (OP_SYMBOL(op)->rname[0] ? OP_SYMBOL(op)->rname : OP_SYMBOL(op)->name),
159 OP_LIVEFROM(op),OP_LIVETO(op),
160 OP_SYMBOL(op)->stack,
161 op->isaddr, OP_SYMBOL(op)->isreqv,OP_SYMBOL(op)->remat
163 /* OP_SYMBOL(op)->allocreq,OP_SYMBOL(op)->remat, */
164 /* OP_SYMBOL(op)->ruonly, */
165 /* OP_SYMBOL(op)->isptr,op->isaddr,OP_SYMBOL(op)->used, */
166 /* OP_SYMBOL(op)->isind, */
167 /* OP_SYMBOL(op)->accuse, op->key, OP_SYMBOL(op)->key */
170 fprintf(file,"{"); printTypeChain(operandType(op),file);
171 if (SPIL_LOC(op) && IS_ITEMP(op))
172 fprintf(file,"}{ sir@ %s",SPIL_LOC(op)->rname);
177 /* if assigned to registers */
178 if (OP_SYMBOL(op)->nRegs) {
179 if (OP_SYMBOL(op)->isspilt) {
180 if (!OP_SYMBOL(op)->remat)
181 if (OP_SYMBOL(op)->usl.spillLoc)
182 fprintf(file,"[%s]",(OP_SYMBOL(op)->usl.spillLoc->rname[0] ?
183 OP_SYMBOL(op)->usl.spillLoc->rname :
184 OP_SYMBOL(op)->usl.spillLoc->name));
186 fprintf(file,"[err]");
188 fprintf(file,"[remat]");
193 for(i=0;i<OP_SYMBOL(op)->nRegs;i++)
194 fprintf(file,"%s ",(OP_SYMBOL(op)->regs[i] ?
195 OP_SYMBOL(op)->regs[i]->name :
201 fprintf(file,"%s",(OP_SYMBOL(op)->rname[0] ?
202 OP_SYMBOL(op)->rname : OP_SYMBOL(op)->name));
203 /* if assigned to registers */
204 if (OP_SYMBOL(op)->nRegs && !OP_SYMBOL(op)->isspilt) {
207 for(i=0;i<OP_SYMBOL(op)->nRegs;i++)
208 fprintf(file,"%s ",(OP_SYMBOL(op)->regs[i] ?
209 OP_SYMBOL(op)->regs[i]->name :
218 printTypeChain(op->operand.typeOperand,file);
229 /*-----------------------------------------------------------------*/
230 /* print functions */
231 /*-----------------------------------------------------------------*/
232 PRINTFUNC(picGetValueAtAddr)
235 printOperand (IC_RESULT(ic),of);
238 printOperand (IC_LEFT(ic), of);
244 PRINTFUNC(picSetValueAtAddr)
248 printOperand(IC_LEFT(ic),of);
250 printOperand(IC_RIGHT(ic),of);
257 printOperand(IC_RESULT(ic),of);
258 if (IS_ITEMP(IC_LEFT(ic)))
262 printOperand(IC_LEFT(ic),of);
264 if (IS_ITEMP(IC_LEFT(ic)))
265 fprintf(of," offsetAdd ");
268 printOperand(IC_RIGHT(ic),of);
270 if (IS_ITEMP(IC_LEFT(ic)))
276 PRINTFUNC(picJumpTable)
281 fprintf(of,"%s\t",s);
282 printOperand(IC_JTCOND(ic),of);
284 for ( sym = setFirstItem(IC_JTLABELS(ic)); sym;
285 sym = setNextItem(IC_JTLABELS(ic)))
286 fprintf(of,"\t\t\t%s\n",sym->name);
289 PRINTFUNC(picGeneric)
292 printOperand(IC_RESULT(ic),of);
294 printOperand(IC_LEFT(ic),of);
295 fprintf(of," %s ",s);
296 printOperand(IC_RIGHT(ic),of);
300 PRINTFUNC(picGenericOne)
303 if ( IC_RESULT(ic) ) {
304 printOperand(IC_RESULT(ic),of);
309 fprintf (of,"%s ",s);
310 printOperand(IC_LEFT(ic),of);
313 if (! IC_RESULT(ic) && !IC_LEFT(ic))
322 printOperand(IC_RESULT(ic),of);
324 printOperand(IC_LEFT(ic),of);
325 printOperand(IC_RIGHT(ic),of);
334 if (IC_RESULT(ic)->isaddr && IS_ITEMP(IC_RESULT(ic)))
337 printOperand(IC_RESULT(ic),of);
339 if (IC_RESULT(ic)->isaddr && IS_ITEMP(IC_RESULT(ic)))
342 fprintf(of," %s ", s);
343 printOperand (IC_RIGHT(ic),of);
350 fprintf(of," %s($%d) :\n",IC_LABEL(ic)->name,IC_LABEL(ic)->key);
356 fprintf (of," goto %s($%d)\n", IC_LABEL(ic)->name,IC_LABEL(ic)->key);
363 printOperand(IC_COND(ic),of);
366 fprintf (of," == 0 goto %s($%d)\n",IC_FALSE(ic)->name,IC_FALSE(ic)->key);
368 fprintf (of," != 0 goto %s($%d)\n",IC_TRUE(ic)->name,IC_TRUE(ic)->key);
370 fprintf (of,"\tzzgoto %s\n",IC_FALSE(ic)->name);
376 fprintf(of,"%s",IC_INLINE(ic));
379 PRINTFUNC(picReceive)
381 printOperand(IC_RESULT(ic),of);
382 fprintf(of," = %s ",s);
383 printOperand(IC_LEFT(ic),of);
387 /*-----------------------------------------------------------------*/
388 /* piCode - prints one iCode */
389 /*-----------------------------------------------------------------*/
390 int piCode (void *item, FILE *of)
398 icTab = getTableEntry(ic->op) ;
399 fprintf(stdout,"%s(%d:%d:%d:%d:%d)\t",
400 ic->filename,ic->lineno,
401 ic->seq,ic->key,ic->depth,ic->supportRtn);
402 icTab->iCodePrint(of,ic,icTab->printName);
406 /*-----------------------------------------------------------------*/
407 /* printiCChain - prints intermediate code for humans */
408 /*-----------------------------------------------------------------*/
409 void printiCChain (iCode *icChain, FILE *of)
416 for ( loop = icChain ; loop ; loop = loop->next ) {
417 if ((icTab = getTableEntry (loop->op ))) {
418 fprintf(of,"%s(%d:%d:%d:%d:%d)\t",
419 loop->filename,loop->lineno,
420 loop->seq,loop->key,loop->depth,loop->supportRtn);
422 icTab->iCodePrint (of,loop,icTab->printName);
428 /*-----------------------------------------------------------------*/
429 /* newOperand - allocate, init & return a new iCode */
430 /*-----------------------------------------------------------------*/
431 operand *newOperand ()
435 ALLOC(op,sizeof(operand));
441 /*-----------------------------------------------------------------*/
442 /* newiCode - create and return a new iCode entry initialised */
443 /*-----------------------------------------------------------------*/
444 iCode *newiCode (int op, operand *left, operand *right)
448 ALLOC(ic,sizeof(iCode));
450 ic->lineno = lineno ;
451 ic->filename= filename ;
453 ic->level = scopeLevel;
455 ic->key= iCodeKey++ ;
462 /*-----------------------------------------------------------------*/
463 /* newiCode for conditional statements */
464 /*-----------------------------------------------------------------*/
465 iCode *newiCodeCondition (operand *condition,
471 ic = newiCode(IFX,NULL,NULL);
472 IC_COND(ic) = condition ;
473 IC_TRUE(ic) = trueLabel ;
474 IC_FALSE(ic) = falseLabel;
478 /*-----------------------------------------------------------------*/
479 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
480 /*-----------------------------------------------------------------*/
481 iCode *newiCodeLabelGoto (int op, symbol *label)
485 ic = newiCode(op,NULL,NULL);
487 ic->argLabel.label = label ;
489 IC_RIGHT(ic) = NULL ;
490 IC_RESULT(ic) = NULL ;
494 /*-----------------------------------------------------------------*/
495 /* newiTemp - allocate & return a newItemp Variable */
496 /*-----------------------------------------------------------------*/
497 symbol *newiTemp (char *s)
502 sprintf(buffer,"%s",s);
504 sprintf (buffer,"iTemp%d",iTempNum++);
505 itmp = newSymbol (buffer,1);
506 strcpy(itmp->rname,itmp->name);
512 /*-----------------------------------------------------------------*/
513 /* newiTempLabel - creates a temp variable label */
514 /*-----------------------------------------------------------------*/
515 symbol *newiTempLabel (char *s)
519 /* check if this alredy exists */
520 if (s && (itmplbl = findSym(LabelTab, NULL, s)))
524 itmplbl = newSymbol(s,1);
526 sprintf(buffer,"iTempLbl%d",iTempLblNum++);
527 itmplbl = newSymbol(buffer,1);
532 itmplbl->key = labelKey++ ;
533 addSym (LabelTab, itmplbl, itmplbl->name,0,0);
537 /*-----------------------------------------------------------------*/
538 /* newiTempPreheaderLabel - creates a new preheader label */
539 /*-----------------------------------------------------------------*/
540 symbol *newiTempPreheaderLabel()
544 sprintf(buffer,"preHeaderLbl%d",iTempLblNum++);
545 itmplbl = newSymbol(buffer,1);
549 itmplbl->key = labelKey++ ;
550 addSym (LabelTab, itmplbl, itmplbl->name,0,0);
555 /*-----------------------------------------------------------------*/
556 /* initiCode - initialises some iCode related stuff */
557 /*-----------------------------------------------------------------*/
563 /*-----------------------------------------------------------------*/
564 /* getTableEntry - gets the table entry for the given operator */
565 /*-----------------------------------------------------------------*/
566 iCodeTable *getTableEntry (int oper )
570 for ( i = 0 ; i < (sizeof(codeTable)/sizeof(iCodeTable)); i++ )
571 if (oper == codeTable[i].icode)
572 return &codeTable[i] ;
577 /*-----------------------------------------------------------------*/
578 /* newiTempOperand - new intermediate temp operand */
579 /*-----------------------------------------------------------------*/
580 operand *newiTempOperand (link *type, char throwType)
583 operand *op = newOperand();
587 itmp = newiTemp(NULL);
589 etype = getSpec(type);
591 if (IS_LITERAL(etype) )
594 /* copy the type information */
596 itmp->etype = getSpec (itmp->type = (throwType ? type :
597 copyLinkChain(type)));
598 if (IS_LITERAL(itmp->etype)) {
599 SPEC_SCLS(itmp->etype) = S_REGISTER ;
600 SPEC_OCLS(itmp->etype) = reg;
603 op->operand.symOperand = itmp;
604 op->key = itmp->key = ++operandKey ;
608 /*-----------------------------------------------------------------*/
609 /* operandType - returns the type chain for an operand */
610 /*-----------------------------------------------------------------*/
611 link *operandType (operand *op)
613 /* depending on type of operand */
617 return op->operand.valOperand->type ;
620 return op->operand.symOperand->type ;
623 return op->operand.typeOperand ;
626 werror (E_INTERNAL_ERROR,__FILE__,__LINE__,
627 " operand type not known ");
628 assert (0) ; /* should never come here */
629 /* Just to keep the compiler happy */
633 /*-----------------------------------------------------------------*/
634 /* isParamterToCall - will return 1 if op is a parameter to args */
635 /*-----------------------------------------------------------------*/
636 int isParameterToCall (value *args, operand *op)
642 isSymbolEqual(op->operand.symOperand,tval->sym))
649 /*-----------------------------------------------------------------*/
650 /* isOperandGlobal - return 1 if operand is a global variable */
651 /*-----------------------------------------------------------------*/
652 int isOperandGlobal ( operand *op )
660 if (op->type == SYMBOL &&
661 (op->operand.symOperand->level == 0 ||
662 IS_STATIC(op->operand.symOperand->etype) ||
663 IS_EXTERN(op->operand.symOperand->etype))
670 /*-----------------------------------------------------------------*/
671 /* isOperandVolatile - return 1 if the operand is volatile */
672 /*-----------------------------------------------------------------*/
673 int isOperandVolatile ( operand *op , bool chkTemp)
678 if (IS_ITEMP(op) && !chkTemp)
681 opetype = getSpec(optype = operandType(op));
683 if (IS_PTR(optype) && DCL_PTR_VOLATILE(optype))
686 if (IS_VOLATILE(opetype))
691 /*-----------------------------------------------------------------*/
692 /* isOperandLiteral - returns 1 if an operand contains a literal */
693 /*-----------------------------------------------------------------*/
694 int isOperandLiteral ( operand *op )
701 opetype = getSpec (operandType(op));
703 if (IS_LITERAL(opetype))
708 /*-----------------------------------------------------------------*/
709 /* isOperandInFarSpace - will return true if operand is in farSpace*/
710 /*-----------------------------------------------------------------*/
711 bool isOperandInFarSpace (operand *op)
721 if (!IS_TRUE_SYMOP(op)) {
723 etype = SPIL_LOC(op)->etype;
728 etype = getSpec(operandType(op));
729 return (IN_FARSPACE(SPEC_OCLS(etype)) ? TRUE : FALSE);
732 /*-----------------------------------------------------------------*/
733 /* operandLitValue - literal value of an operand */
734 /*-----------------------------------------------------------------*/
735 double operandLitValue ( operand *op )
737 assert(isOperandLiteral(op));
739 return floatFromVal(op->operand.valOperand);
742 /*-----------------------------------------------------------------*/
743 /* operandOperation - perforoms operations on operands */
744 /*-----------------------------------------------------------------*/
745 operand *operandOperation (operand *left,operand *right,
748 operand *retval = (operand *)0;
750 assert(isOperandLiteral(left));
752 assert(isOperandLiteral(right));
756 retval = operandFromValue (valCastLiteral(type,
757 operandLitValue(left) +
758 operandLitValue(right)));
761 retval = operandFromValue(valCastLiteral(type,
762 operandLitValue(left) -
763 operandLitValue(right)));
766 retval = operandFromValue(valCastLiteral(type,
767 operandLitValue(left) *
768 operandLitValue(right)));
771 if ((unsigned long) operandLitValue(right) == 0){
772 werror(E_DIVIDE_BY_ZERO);
777 retval = operandFromValue (valCastLiteral(type,
778 operandLitValue(left) /
779 operandLitValue(right)));
782 if ((unsigned long) operandLitValue(right) == 0){
783 werror(E_DIVIDE_BY_ZERO);
787 retval = operandFromLit ((unsigned long) operandLitValue(left) %
788 (unsigned long) operandLitValue(right));
791 retval = operandFromLit ((unsigned long) operandLitValue(left) <<
792 (unsigned long) operandLitValue(right));
795 retval = operandFromLit ((unsigned long) operandLitValue(left) >>
796 (unsigned long) operandLitValue(right));
799 retval = operandFromLit (operandLitValue(left) ==
800 operandLitValue(right));
803 retval = operandFromLit (operandLitValue(left) <
804 operandLitValue(right));
807 retval = operandFromLit (operandLitValue(left) <=
808 operandLitValue(right));
811 retval = operandFromLit (operandLitValue(left) !=
812 operandLitValue(right));
815 retval = operandFromLit (operandLitValue(left) >
816 operandLitValue(right));
819 retval = operandFromLit (operandLitValue(left) >=
820 operandLitValue(right));
823 retval = operandFromLit ((unsigned long) operandLitValue(left) &
824 (unsigned long) operandLitValue(right));
827 retval = operandFromLit ((unsigned long) operandLitValue(left) |
828 (unsigned long) operandLitValue(right));
831 retval = operandFromLit ((unsigned long) operandLitValue(left) ^
832 (unsigned long) operandLitValue(right));
835 retval = operandFromLit (operandLitValue(left) &&
836 operandLitValue(right));
839 retval = operandFromLit (operandLitValue(left) ||
840 operandLitValue(right));
844 long i = operandLitValue(left);
846 retval = operandFromLit ((i >> (getSize(operandType(left))*8 - 1)) |
852 long i = operandLitValue(left);
854 retval = operandFromLit ((i << (getSize(operandType(left))*8 - 1)) |
860 retval = operandFromLit(-1 * operandLitValue(left));
864 retval = operandFromLit(~ ((long) operandLitValue(left)));
868 retval = operandFromLit(! operandLitValue(left));
872 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
873 " operandOperation invalid operator ");
881 /*-----------------------------------------------------------------*/
882 /* isOperandEqual - compares two operand & return 1 if they r = */
883 /*-----------------------------------------------------------------*/
884 int isOperandEqual (operand *left, operand *right)
886 /* if the pointers are equal then they are equal */
890 /* if either of them null then false */
891 if ( !left || !right)
894 if (left->type != right->type)
897 if (IS_SYMOP(left) && IS_SYMOP(right))
898 return left->key == right->key ;
900 /* if types are the same */
901 switch (left->type) {
903 return isSymbolEqual(left->operand.symOperand,
904 right->operand.symOperand);
906 return (floatFromVal(left->operand.valOperand) ==
907 floatFromVal(right->operand.valOperand));
909 if (checkType(left->operand.typeOperand,
910 right->operand.typeOperand) == 1)
917 /*-----------------------------------------------------------------*/
918 /* isiCodeEqual - comapres two iCodes are returns true if yes */
919 /*-----------------------------------------------------------------*/
920 int isiCodeEqual (iCode *left, iCode *right)
922 /* if the same pointer */
926 /* if either of them null */
930 /* if operand are the same */
931 if ( left->op == right->op ) {
933 /* compare all the elements depending on type */
934 if (left->op != IFX ) {
935 if (!isOperandEqual(IC_LEFT(left),IC_LEFT(right)))
937 if (!isOperandEqual(IC_RIGHT(left),IC_RIGHT(right)))
941 if (!isOperandEqual(IC_COND(left),IC_COND(right)))
943 if (!isSymbolEqual (IC_TRUE(left),IC_TRUE(right)))
945 if (!isSymbolEqual(IC_FALSE(left),IC_FALSE(right)))
953 /*-----------------------------------------------------------------*/
954 /* operand from operand - creates an operand holder for the type */
955 /*-----------------------------------------------------------------*/
956 operand *operandFromOperand (operand *op)
958 operand *nop = newOperand();
960 nop->type = op->type;
961 nop->isaddr = op->isaddr ;
963 nop->isvolatile = op->isvolatile ;
964 nop->isGlobal = op->isGlobal ;
965 nop->isLiteral= op->isLiteral ;
966 nop->noSpilLoc= op->noSpilLoc;
967 nop->usesDefs = op->usesDefs;
968 nop->isParm = op->isParm;
969 nop->parmBytes = op->parmBytes;
973 nop->operand.symOperand = op->operand.symOperand ;
976 nop->operand.valOperand = op->operand.valOperand;
979 nop->operand.typeOperand = op->operand.typeOperand ;
986 /*-----------------------------------------------------------------*/
987 /* opFromOpWithDU - makes a copy of the operand and DU chains */
988 /*-----------------------------------------------------------------*/
989 operand *opFromOpWithDU (operand *op, bitVect *defs, bitVect *uses)
991 operand *nop = operandFromOperand(op);
993 if (nop->type == SYMBOL) {
994 OP_SYMBOL(nop)->defs = bitVectCopy(defs);
995 OP_SYMBOL(nop)->uses = bitVectCopy(uses);
1001 /*-----------------------------------------------------------------*/
1002 /* operandFromSymbol - creates an operand from a symbol */
1003 /*-----------------------------------------------------------------*/
1004 operand *operandFromSymbol (symbol *sym)
1009 /* if the symbol's type is a literal */
1010 /* then it is an enumerator type */
1011 if (IS_LITERAL(sym->etype) && SPEC_ENUM(sym->etype))
1012 return operandFromValue (valFromType(sym->etype));
1015 sym->key = ++operandKey ;
1017 /* if this an implicit variable, means struct/union */
1018 /* member so just return it */
1019 if (sym->implicit || IS_FUNC(sym->type)) {
1022 op->operand.symOperand = sym;
1023 op->key = sym->key ;
1024 op->isvolatile = isOperandVolatile(op,TRUE);
1025 op->isGlobal = isOperandGlobal(op);
1029 /* under the following conditions create a
1030 register equivalent for a local symbol */
1031 if (!IS_AGGREGATE(sym->type) && /* not an aggregate */
1032 !IS_FUNC(sym->type) && /* not a function */
1033 !sym->_isparm && /* not a parameter */
1034 sym->level && /* is a local variable */
1035 !sym->addrtaken && /* whose address has not been taken */
1036 !sym->reqv && /* does not already have a register euivalence */
1037 !IS_VOLATILE(sym->etype) && /* not declared as volatile */
1038 !IS_STATIC(sym->etype) && /* and not declared static */
1040 !IN_FARSPACE(SPEC_OCLS(sym->etype))) { /* not a label */
1042 /* we will use it after all optimizations
1043 and before liveRange calculation */
1044 sym->reqv = newiTempOperand(sym->type,0);
1045 sym->reqv->key = sym->key ;
1046 OP_SYMBOL(sym->reqv)->key = sym->key;
1047 OP_SYMBOL(sym->reqv)->isreqv = 1;
1048 OP_SYMBOL(sym->reqv)->islocal = 1;
1049 SPIL_LOC(sym->reqv) = sym;
1052 if (!IS_AGGREGATE(sym->type)) {
1055 op->operand.symOperand = sym;
1058 op->isvolatile = isOperandVolatile(op,TRUE);
1059 op->isGlobal = isOperandGlobal(op);
1060 op->isPtr = IS_PTR(operandType(op));
1061 op->isParm = sym->_isparm ;
1066 /* itemp = &[_symbol] */
1068 ic = newiCode(ADDRESS_OF,newOperand(),NULL);
1069 IC_LEFT(ic)->type = SYMBOL ;
1070 IC_LEFT(ic)->operand.symOperand = sym ;
1071 IC_LEFT(ic)->key = sym->key;
1072 (IC_LEFT(ic))->isvolatile = isOperandVolatile(IC_LEFT(ic),TRUE);
1073 (IC_LEFT(ic))->isGlobal = isOperandGlobal(IC_LEFT(ic));
1074 IC_LEFT(ic)->isPtr = IS_PTR(operandType(IC_LEFT(ic)));
1077 IC_RESULT(ic) = newiTempOperand(sym->type,0);
1078 if (IS_ARRAY(sym->type)) {
1079 IC_RESULT(ic) = geniCodeArray2Ptr (IC_RESULT(ic));
1080 IC_RESULT(ic)->isaddr = 0;
1082 IC_RESULT(ic)->isaddr = (!IS_AGGREGATE(sym->type));
1084 IC_RESULT(ic)->operand.symOperand->args = sym->args;
1088 return IC_RESULT(ic) ;
1091 /*-----------------------------------------------------------------*/
1092 /* operandFromValue - creates an operand from value */
1093 /*-----------------------------------------------------------------*/
1094 operand *operandFromValue (value *val)
1098 /* if this is a symbol then do the symbol thing */
1100 return operandFromSymbol (val->sym);
1102 /* this is not a symbol */
1105 op->operand.valOperand = val ;
1106 op->isLiteral = isOperandLiteral(op);
1110 /*-----------------------------------------------------------------*/
1111 /* operandFromLink - operand from typeChain */
1112 /*-----------------------------------------------------------------*/
1113 operand *operandFromLink (link *type)
1117 /* operand from link */
1123 op->operand.typeOperand = copyLinkChain(type);
1127 /*-----------------------------------------------------------------*/
1128 /* operandFromLit - makes an operand from a literal value */
1129 /*-----------------------------------------------------------------*/
1130 operand *operandFromLit ( float i)
1132 return operandFromValue (valueFromLit (i));
1135 /*-----------------------------------------------------------------*/
1136 /* operandFromAst - creates an operand from an ast */
1137 /*-----------------------------------------------------------------*/
1138 operand *operandFromAst ( ast *tree )
1144 /* depending on type do */
1145 switch (tree->type ) {
1147 return ast2iCode (tree) ;
1151 return operandFromValue(tree->opval.val) ;
1155 return operandFromLink (tree->opval.lnk) ;
1159 /* Just to keep the comiler happy */
1160 return (operand *)0;
1163 /*-----------------------------------------------------------------*/
1164 /* setOperandType - sets the operand's type to the given type */
1165 /*-----------------------------------------------------------------*/
1166 void setOperandType (operand *op, link *type)
1168 /* depending on the type of operand */
1172 op->operand.valOperand->etype =
1173 getSpec( op->operand.valOperand->type =
1174 copyLinkChain (type )) ;
1178 if (op->operand.symOperand->isitmp )
1179 op->operand.symOperand->etype =
1180 getSpec( op->operand.symOperand->type =
1181 copyLinkChain (type )) ;
1183 werror (E_INTERNAL_ERROR,__FILE__,__LINE__,
1184 "attempt to modify type of source");
1188 op->operand.typeOperand = copyLinkChain (type);
1194 /*-----------------------------------------------------------------*/
1195 /* geniCodeValueAtAddress - generate intermeditate code for value */
1197 /*-----------------------------------------------------------------*/
1198 operand *geniCodeRValue (operand *op, bool force)
1201 link *type = operandType(op);
1202 link *etype= getSpec(type);
1204 /* if this is an array & already */
1205 /* an address then return this */
1206 if (IS_AGGREGATE(type) ||
1207 (IS_PTR(type) && !force && !op->isaddr))
1208 return operandFromOperand(op);
1210 /* if this is not an address then must be */
1211 /* rvalue already so return this one */
1215 /* if this is not a temp symbol then */
1216 if (!IS_ITEMP(op) &&
1218 !IN_FARSPACE(SPEC_OCLS(etype))) {
1219 op = operandFromOperand(op);
1224 if (IS_SPEC(type) &&
1225 IS_TRUE_SYMOP(op) &&
1226 !IN_FARSPACE(SPEC_OCLS(etype))) {
1227 op = operandFromOperand(op);
1232 ic = newiCode(GET_VALUE_AT_ADDRESS,op,NULL);
1233 if (IS_PTR(type) && op->isaddr && force)
1236 type = copyLinkChain(type);
1238 IC_RESULT(ic) = newiTempOperand (type,1);
1239 IC_RESULT(ic)->isaddr = 0;
1241 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1243 /* if the right is a symbol */
1244 if (op->type == SYMBOL)
1245 IC_RESULT(ic)->operand.symOperand->args =
1246 op->operand.symOperand->args ;
1249 return IC_RESULT(ic) ;
1252 /*-----------------------------------------------------------------*/
1253 /* geniCodeCast - changes the value from one type to another */
1254 /*-----------------------------------------------------------------*/
1255 operand *geniCodeCast (link *type, operand *op, bool implicit)
1259 link *opetype = getSpec(optype = operandType(op));
1262 /* one of them has size zero then error */
1263 if (IS_VOID(optype)) {
1264 werror(E_CAST_ZERO);
1268 /* if the operand is already the desired type then do nothing */
1269 if ( checkType (type,optype) == 1)
1272 /* if this is a literal then just change the type & return */
1273 if (IS_LITERAL(opetype) && !IS_PTR(type) && !IS_PTR(optype))
1274 return operandFromValue(valCastLiteral(type,
1275 operandLitValue(op)));
1277 /* if casting to some pointer type &&
1278 the destination is not a generic pointer
1279 then give a warning : (only for implicit casts)*/
1280 if (IS_PTR(optype) && implicit &&
1281 (DCL_TYPE(optype) != DCL_TYPE(type)) &&
1283 werror(E_INCOMPAT_CAST);
1284 werror(E_CONTINUE,"from type '");
1285 printTypeChain(optype,stderr);fprintf(stderr,"' to type '");
1286 printTypeChain(type,stderr);fprintf(stderr,"'\n");
1289 /* if they are the same size create an assignment */
1290 if (getSize(type) == getSize(optype) &&
1291 !IS_BITFIELD(type) &&
1293 !IS_FLOAT(optype) &&
1294 ((IS_SPEC(type) && IS_SPEC(optype)) ||
1295 (!IS_SPEC(type) && !IS_SPEC(optype)))) {
1297 ic = newiCode('=',NULL,op);
1298 IC_RESULT(ic) = newiTempOperand(type,0);
1299 SPIL_LOC(IC_RESULT(ic)) =
1300 (IS_TRUE_SYMOP(op) ? OP_SYMBOL(op) : NULL);
1301 IC_RESULT(ic)->isaddr = 0;
1303 ic = newiCode(CAST,operandFromLink(type),
1304 geniCodeRValue(op,FALSE));
1306 IC_RESULT(ic)= newiTempOperand(type,0);
1309 /* preserve the storage class & output class */
1310 /* of the original variable */
1311 restype = getSpec(operandType(IC_RESULT(ic)));
1312 SPEC_SCLS(restype) = SPEC_SCLS(opetype);
1313 SPEC_OCLS(restype) = SPEC_OCLS(opetype);
1316 return IC_RESULT(ic) ;
1319 /*-----------------------------------------------------------------*/
1320 /* geniCodeLabel - will create a Label */
1321 /*-----------------------------------------------------------------*/
1322 void geniCodeLabel (symbol *label)
1326 ic = newiCodeLabelGoto(LABEL,label);
1330 /*-----------------------------------------------------------------*/
1331 /* geniCodeGoto - will create a Goto */
1332 /*-----------------------------------------------------------------*/
1333 void geniCodeGoto (symbol *label)
1337 ic = newiCodeLabelGoto(GOTO,label);
1341 /*-----------------------------------------------------------------*/
1342 /* geniCodeMultiply - gen intermediate code for multiplication */
1343 /*-----------------------------------------------------------------*/
1344 operand *geniCodeMultiply (operand *left, operand *right)
1351 /* if they are both literal then we know the result */
1352 if (IS_LITERAL(letype) && IS_LITERAL(retype))
1353 return operandFromValue (valMult(left->operand.valOperand,
1354 right->operand.valOperand));
1356 resType = computeType (ltype,rtype) ;
1357 left = geniCodeCast(resType,left,TRUE);
1358 right= geniCodeCast(resType,right,TRUE);
1360 /* if the right is a literal & power of 2 */
1361 /* then make it a left shift */
1362 if (IS_LITERAL(retype) && !IS_FLOAT(letype) &&
1363 (p2 = powof2 ((unsigned long)floatFromVal(right->operand.valOperand))))
1364 ic = newiCode(LEFT_OP, left,operandFromLit(p2)); /* left shift */
1366 ic = newiCode('*',left,right); /* normal multiplication */
1367 /* if the size left or right > 1 then support routine */
1368 if (getSize(ltype) > 1 || getSize(rtype) > 1)
1372 IC_RESULT(ic) = newiTempOperand(resType,1);
1375 return IC_RESULT(ic) ;
1378 /*-----------------------------------------------------------------*/
1379 /* geniCodeDivision - gen intermediate code for division */
1380 /*-----------------------------------------------------------------*/
1381 operand *geniCodeDivision (operand *left, operand *right)
1386 link *rtype = operandType(right);
1387 link *retype= getSpec(rtype);
1388 link *ltype = operandType(left);
1389 link *letype= getSpec(ltype);
1391 resType = computeType (ltype,rtype) ;
1392 left = geniCodeCast(resType,left,TRUE);
1393 right= geniCodeCast(resType,right,TRUE);
1395 /* if the right is a literal & power of 2 */
1396 /* then make it a right shift */
1397 if (IS_LITERAL(retype) &&
1398 !IS_FLOAT(letype) &&
1399 (p2 = powof2 ((unsigned long)
1400 floatFromVal(right->operand.valOperand))))
1401 ic = newiCode(RIGHT_OP, left,operandFromLit(p2)); /* right shift */
1403 ic = newiCode('/',left,right); /* normal division */
1404 /* if the size left or right > 1 then support routine */
1405 if (getSize(ltype) > 1 || getSize(rtype) > 1)
1408 IC_RESULT(ic) = newiTempOperand(resType,0);
1411 return IC_RESULT(ic) ;
1413 /*-----------------------------------------------------------------*/
1414 /* geniCodeModulus - gen intermediate code for modulus */
1415 /*-----------------------------------------------------------------*/
1416 operand *geniCodeModulus (operand *left, operand *right)
1422 /* if they are both literal then we know the result */
1423 if (IS_LITERAL(letype) && IS_LITERAL(retype))
1424 return operandFromValue (valMod(left->operand.valOperand,
1425 right->operand.valOperand));
1427 resType = computeType (ltype,rtype) ;
1428 left = geniCodeCast(resType,left,TRUE);
1429 right= geniCodeCast(resType,right,TRUE);
1431 /* now they are the same size */
1432 ic = newiCode('%',left,right);
1434 /* if the size left or right > 1 then support routine */
1435 if (getSize(ltype) > 1 || getSize(rtype) > 1)
1437 IC_RESULT(ic) = newiTempOperand(resType,0);
1440 return IC_RESULT(ic) ;
1443 /*-----------------------------------------------------------------*/
1444 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1445 /*-----------------------------------------------------------------*/
1446 operand *geniCodePtrPtrSubtract (operand *left, operand *right)
1452 /* if they are both literals then */
1453 if (IS_LITERAL(letype) && IS_LITERAL(retype)) {
1454 result = operandFromValue (valMinus(left->operand.valOperand,
1455 right->operand.valOperand));
1459 ic = newiCode('-',left,right);
1461 IC_RESULT(ic) = result = newiTempOperand(newIntLink(),1);
1465 return geniCodeDivision (result,
1466 operandFromLit(getSize(ltype->next)));
1469 /*-----------------------------------------------------------------*/
1470 /* geniCodeSubtract - generates code for subtraction */
1471 /*-----------------------------------------------------------------*/
1472 operand *geniCodeSubtract (operand *left, operand *right)
1479 /* if they both pointers then */
1480 if ((IS_PTR(ltype) || IS_ARRAY(ltype)) &&
1481 (IS_PTR(rtype) || IS_ARRAY(rtype)))
1482 return geniCodePtrPtrSubtract (left,right);
1484 /* if they are both literal then we know the result */
1485 if (IS_LITERAL(letype) && IS_LITERAL(retype))
1486 return operandFromValue (valMinus(left->operand.valOperand,
1487 right->operand.valOperand));
1489 /* if left is an array or pointer */
1490 if ( IS_PTR(ltype) || IS_ARRAY(ltype) ) {
1491 isarray = left->isaddr ;
1492 right = geniCodeMultiply (right,
1493 operandFromLit(getSize(ltype->next)));
1494 resType = copyLinkChain(IS_ARRAY(ltype) ? ltype->next : ltype);
1496 else { /* make them the same size */
1497 resType = computeType (ltype,rtype) ;
1498 left = geniCodeCast(resType,left,TRUE);
1499 right= geniCodeCast(resType,right,TRUE);
1502 ic = newiCode('-',left,right);
1504 IC_RESULT(ic)= newiTempOperand(resType,1);
1505 IC_RESULT(ic)->isaddr = (isarray ? 1 : 0);
1507 /* if left or right is a float */
1508 if (IS_FLOAT(ltype) || IS_FLOAT(rtype))
1512 return IC_RESULT(ic) ;
1515 /*-----------------------------------------------------------------*/
1516 /* geniCodeAdd - generates iCode for addition */
1517 /*-----------------------------------------------------------------*/
1518 operand *geniCodeAdd (operand *left, operand *right )
1526 /* if left is an array then array access */
1527 if (IS_ARRAY(ltype))
1528 return geniCodeArray (left,right);
1530 /* if the right side is LITERAL zero */
1531 /* return the left side */
1532 if (IS_LITERAL(retype) && !floatFromVal(valFromType(retype)))
1535 /* if left is literal zero return right */
1536 if (IS_LITERAL(letype) && !floatFromVal(valFromType(letype)))
1539 /* if left is an array or pointer then size */
1540 if (IS_PTR(ltype)) {
1542 isarray = left->isaddr;
1544 operandFromLit(getSize(ltype->next));
1545 right = geniCodeMultiply (right ,size);
1546 resType = copyLinkChain(ltype);
1548 else { /* make them the same size */
1549 resType = computeType (ltype,rtype) ;
1550 left = geniCodeCast(resType,left,TRUE);
1551 right= geniCodeCast(resType,right,TRUE);
1554 /* if they are both literals then we know */
1555 if (IS_LITERAL(letype) && IS_LITERAL(retype))
1556 return operandFromValue (valPlus(valFromType(letype),
1557 valFromType(retype)));
1559 ic = newiCode('+',left,right);
1561 IC_RESULT(ic) = newiTempOperand(resType,1);
1562 IC_RESULT(ic)->isaddr = ( isarray ? 1 : 0);
1564 /* if left or right is a float then support
1566 if (IS_FLOAT(ltype) || IS_FLOAT(rtype))
1571 return IC_RESULT(ic) ;
1575 /*-----------------------------------------------------------------*/
1576 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1577 /*-----------------------------------------------------------------*/
1578 link *aggrToPtr ( link *type, bool force)
1584 if (IS_PTR(type) && !force)
1587 etype = getSpec(type);
1591 /* if the output class is generic */
1592 if (SPEC_OCLS(etype) == generic)
1593 DCL_TYPE(ptype) = GPOINTER;
1595 if (SPEC_OCLS(etype)->codesp ) {
1596 DCL_TYPE(ptype) = CPOINTER ;
1597 DCL_PTR_CONST(ptype) = 1;
1600 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
1601 DCL_TYPE(ptype) = FPOINTER ;
1603 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
1604 DCL_TYPE(ptype) = PPOINTER ;
1606 if (SPEC_OCLS(etype) == idata)
1607 DCL_TYPE(ptype) = IPOINTER;
1609 DCL_TYPE(ptype) = POINTER ;
1611 /* if the variable was declared a constant */
1612 /* then the pointer points to a constant */
1613 if (IS_CONSTANT(etype) )
1614 DCL_PTR_CONST(ptype) = 1;
1616 /* the variable was volatile then pointer to volatile */
1617 if (IS_VOLATILE(etype))
1618 DCL_PTR_VOLATILE(ptype) = 1;
1622 /*-----------------------------------------------------------------*/
1623 /* geniCodeArray2Ptr - array to pointer */
1624 /*-----------------------------------------------------------------*/
1625 operand *geniCodeArray2Ptr (operand *op)
1627 link *optype = operandType(op);
1628 link *opetype = getSpec(optype);
1630 /* set the pointer depending on the storage class */
1631 if (SPEC_OCLS(opetype)->codesp ) {
1632 DCL_TYPE(optype) = CPOINTER ;
1633 DCL_PTR_CONST(optype) = 1;
1636 if (SPEC_OCLS(opetype)->fmap && !SPEC_OCLS(opetype)->paged)
1637 DCL_TYPE(optype) = FPOINTER ;
1639 if (SPEC_OCLS(opetype)->fmap && SPEC_OCLS(opetype)->paged)
1640 DCL_TYPE(optype) = PPOINTER ;
1642 if (SPEC_OCLS(opetype) == idata)
1643 DCL_TYPE(optype) = IPOINTER;
1645 DCL_TYPE(optype) = POINTER ;
1647 /* if the variable was declared a constant */
1648 /* then the pointer points to a constant */
1649 if (IS_CONSTANT(opetype) )
1650 DCL_PTR_CONST(optype) = 1;
1652 /* the variable was volatile then pointer to volatile */
1653 if (IS_VOLATILE(opetype))
1654 DCL_PTR_VOLATILE(optype) = 1;
1659 /*-----------------------------------------------------------------*/
1660 /* geniCodeArray - array access */
1661 /*-----------------------------------------------------------------*/
1662 operand *geniCodeArray (operand *left,operand *right)
1665 link *ltype = operandType(left);
1667 if (IS_PTR(ltype)) {
1669 int olval = lvaluereq ;
1670 lvaluereq = IS_PTR(ltype->next);
1671 r= geniCodeDerefPtr(geniCodeAdd(left,right));
1677 right = geniCodeMultiply(right,
1678 operandFromLit(getSize(ltype->next)));
1680 /* we can check for limits here */
1681 if (isOperandLiteral(right) &&
1684 (operandLitValue(right)/getSize(ltype->next)) >= DCL_ELEM(ltype)) {
1685 werror(E_ARRAY_BOUND);
1686 right = operandFromLit(0);
1689 ic = newiCode('+',left,right);
1691 IC_RESULT(ic) = newiTempOperand(((IS_PTR(ltype) &&
1692 !IS_AGGREGATE(ltype->next) &&
1693 !IS_PTR(ltype->next))
1694 ? ltype : ltype->next),0);
1695 /* IC_RESULT(ic) = newiTempOperand(ltype->next,0); */
1696 IC_RESULT(ic)->isaddr = (!IS_AGGREGATE(ltype->next));
1698 return IC_RESULT(ic) ;
1701 /*-----------------------------------------------------------------*/
1702 /* geniCodeStruct - generates intermediate code for structres */
1703 /*-----------------------------------------------------------------*/
1704 operand *geniCodeStruct (operand *left, operand *right, bool islval)
1707 link *type = operandType(left);
1708 link *etype = getSpec(type);
1710 symbol *element = getStructElement(SPEC_STRUCT(etype),
1711 right->operand.symOperand);
1713 /* add the offset */
1714 ic = newiCode('+',left,operandFromLit(element->offset));
1716 IC_RESULT(ic) = newiTempOperand(element->type,0);
1718 /* preserve the storage & output class of the struct */
1719 /* as well as the volatile attribute */
1720 retype = getSpec(operandType(IC_RESULT(ic)));
1721 SPEC_SCLS(retype) = SPEC_SCLS(etype);
1722 SPEC_OCLS(retype) = SPEC_OCLS(etype);
1723 SPEC_VOLATILE(retype) |= SPEC_VOLATILE(etype);
1725 if (IS_PTR(element->type))
1726 setOperandType(IC_RESULT(ic),aggrToPtr(operandType(IC_RESULT(ic)),TRUE));
1728 IC_RESULT(ic)->isaddr = (!IS_AGGREGATE(element->type));
1732 return (islval ? IC_RESULT(ic) : geniCodeRValue(IC_RESULT(ic),TRUE));
1735 /*-----------------------------------------------------------------*/
1736 /* geniCodePostInc - generate int code for Post increment */
1737 /*-----------------------------------------------------------------*/
1738 operand *geniCodePostInc (operand *op)
1742 link *optype = operandType(op);
1744 operand *rv = (IS_ITEMP(op) ?
1745 geniCodeRValue(op,(IS_PTR(optype) ? TRUE : FALSE)) :
1747 link *rvtype = operandType(rv);
1748 int diff = (IS_PTR(rvtype) && DCL_TYPE(optype) != DCL_TYPE(rvtype));
1751 /* if this is not an address we have trouble */
1752 if ( ! op->isaddr ) {
1753 werror (E_LVALUE_REQUIRED,"++");
1757 rOp = newiTempOperand((diff ? rvtype : optype),0);
1763 geniCodeAssign(rOp,rv,0);
1765 size = (IS_PTR(rvtype) ? getSize(rvtype->next) : 1);
1766 ic = newiCode('+',rv,operandFromLit(size));
1767 IC_RESULT(ic) = result =newiTempOperand((diff ? rvtype : optype),0);
1770 geniCodeAssign(op,result,0);
1776 /*-----------------------------------------------------------------*/
1777 /* geniCodePreInc - generate code for preIncrement */
1778 /*-----------------------------------------------------------------*/
1779 operand *geniCodePreInc (operand *op)
1782 link *optype = operandType(op);
1783 operand *rop = (IS_ITEMP(op) ?
1784 geniCodeRValue (op,(IS_PTR(optype) ? TRUE : FALSE)) :
1786 link *roptype = operandType(rop);
1787 int diff = (IS_PTR(roptype) && (DCL_TYPE(roptype) != DCL_TYPE(optype)));
1791 if ( ! op->isaddr ) {
1792 werror(E_LVALUE_REQUIRED,"++");
1797 size = (IS_PTR(roptype) ? getSize(roptype->next) : 1);
1798 ic = newiCode('+',rop,operandFromLit(size));
1799 IC_RESULT(ic) = result = newiTempOperand((diff ? roptype : optype),0) ;
1803 return geniCodeAssign(op,result,0) ;
1806 /*-----------------------------------------------------------------*/
1807 /* geniCodePostDec - generates code for Post decrement */
1808 /*-----------------------------------------------------------------*/
1809 operand *geniCodePostDec (operand *op)
1813 link *optype = operandType(op);
1815 operand *rv = (IS_ITEMP(op) ?
1816 geniCodeRValue(op,(IS_PTR(optype) ? TRUE : FALSE)) :
1818 link *rvtype = operandType(rv);
1819 int diff = (IS_PTR(rvtype) && DCL_TYPE(optype) != DCL_TYPE(rvtype));
1822 /* if this is not an address we have trouble */
1823 if ( ! op->isaddr ) {
1824 werror (E_LVALUE_REQUIRED,"++");
1828 rOp = newiTempOperand((diff ? rvtype : optype),0);
1834 geniCodeAssign(rOp,rv,0);
1836 size = (IS_PTR(rvtype) ? getSize(rvtype->next) : 1);
1837 ic = newiCode('-',rv,operandFromLit(size));
1838 IC_RESULT(ic) = result =newiTempOperand((diff ? rvtype : optype),0);
1841 geniCodeAssign(op,result,0);
1847 /*-----------------------------------------------------------------*/
1848 /* geniCodePreDec - generate code for pre decrement */
1849 /*-----------------------------------------------------------------*/
1850 operand *geniCodePreDec (operand *op)
1853 link *optype = operandType(op);
1854 operand *rop = (IS_ITEMP(op) ?
1855 geniCodeRValue (op,(IS_PTR(optype) ? TRUE : FALSE)) :
1857 link *roptype = operandType(rop);
1858 int diff = (IS_PTR(roptype) && (DCL_TYPE(roptype) != DCL_TYPE(optype)));
1862 if ( ! op->isaddr ) {
1863 werror(E_LVALUE_REQUIRED,"++");
1868 size = (IS_PTR(roptype) ? getSize(roptype->next) : 1);
1869 ic = newiCode('-',rop,operandFromLit(size));
1870 IC_RESULT(ic) = result = newiTempOperand((diff ? roptype : optype),0) ;
1874 return geniCodeAssign(op,result,0) ;
1878 /*-----------------------------------------------------------------*/
1879 /* geniCodeBitwise - gen int code for bitWise operators */
1880 /*-----------------------------------------------------------------*/
1881 operand *geniCodeBitwise (operand *left, operand *right,
1882 int oper, link *resType)
1886 left = geniCodeCast(resType,left,TRUE);
1887 right= geniCodeCast(resType,right,TRUE);
1889 ic = newiCode(oper,left,right);
1890 IC_RESULT(ic) = newiTempOperand(resType,0);
1893 return IC_RESULT(ic) ;
1896 /*-----------------------------------------------------------------*/
1897 /* geniCodeAddressOf - gens icode for '&' address of operator */
1898 /*-----------------------------------------------------------------*/
1899 operand *geniCodeAddressOf (operand *op)
1903 link *optype = operandType(op);
1904 link *opetype= getSpec(optype);
1906 /* this must be a lvalue */
1907 if (!op->isaddr && !IS_AGGREGATE(optype)) {
1908 werror (E_LVALUE_REQUIRED,"&");
1913 p->class = DECLARATOR ;
1914 /* set the pointer depending on the storage class */
1915 if (SPEC_OCLS(opetype)->codesp ) {
1916 DCL_TYPE(p) = CPOINTER ;
1917 DCL_PTR_CONST(p) = 1;
1920 if (SPEC_OCLS(opetype)->fmap && !SPEC_OCLS(opetype)->paged)
1921 DCL_TYPE(p) = FPOINTER ;
1923 if (SPEC_OCLS(opetype)->fmap && SPEC_OCLS(opetype)->paged)
1924 DCL_TYPE(p) = PPOINTER ;
1926 if (SPEC_OCLS(opetype) == idata)
1927 DCL_TYPE(p) = IPOINTER;
1929 if (SPEC_OCLS(opetype) == data ||
1930 SPEC_OCLS(opetype) == overlay)
1931 DCL_TYPE(p) = POINTER ;
1933 DCL_TYPE(p) = GPOINTER;
1935 /* make sure we preserve the const & volatile */
1936 if (IS_CONSTANT(opetype))
1937 DCL_PTR_CONST(p) = 1;
1939 if (IS_VOLATILE(opetype))
1940 DCL_PTR_VOLATILE(p) = 1;
1942 p->next = copyLinkChain(optype);
1944 /* if already a temp */
1946 setOperandType (op,p);
1951 /* other wise make this of the type coming in */
1952 ic = newiCode(ADDRESS_OF,op,NULL);
1953 IC_RESULT(ic) = newiTempOperand(p,1);
1954 IC_RESULT(ic)->isaddr = 0;
1956 return IC_RESULT(ic);
1958 /*-----------------------------------------------------------------*/
1959 /* setOClass - sets the output class depending on the pointer type */
1960 /*-----------------------------------------------------------------*/
1961 void setOClass (link *ptr, link *spec)
1963 switch (DCL_TYPE(ptr)) {
1965 SPEC_OCLS(spec) = data ;
1969 SPEC_OCLS(spec) = generic;
1973 SPEC_OCLS(spec) = xdata ;
1977 SPEC_OCLS(spec) = code ;
1981 SPEC_OCLS(spec) = idata;
1985 SPEC_OCLS(spec) = xstack;
1991 /*-----------------------------------------------------------------*/
1992 /* geniCodeDerefPtr - dereference pointer with '*' */
1993 /*-----------------------------------------------------------------*/
1994 operand *geniCodeDerefPtr (operand *op)
1996 link *rtype , *retype ;
1997 link *optype = operandType(op);
1999 /* if this is a pointer then generate the rvalue */
2000 if (IS_PTR(optype)) {
2001 if (IS_TRUE_SYMOP(op)) {
2003 op = geniCodeRValue(op,TRUE);
2006 op = geniCodeRValue(op,TRUE);
2009 /* now get rid of the pointer part */
2010 if (lvaluereq && IS_ITEMP(op))
2011 retype = getSpec(rtype = copyLinkChain(optype)) ;
2013 retype = getSpec(rtype = copyLinkChain(optype->next)) ;
2015 /* if this is a pointer then outputclass needs 2b updated */
2017 setOClass(optype,retype);
2019 op = geniCodeRValue(op,TRUE);
2020 op->isGptr = IS_GENPTR(optype);
2022 /* if the pointer was declared as a constant */
2023 /* then we cannot allow assignment to the derefed */
2024 if (IS_PTR_CONST(optype))
2025 SPEC_CONST(retype) = 1;
2028 setOperandType(op,rtype);
2029 op->isaddr = (IS_PTR(rtype) ||
2038 /*-----------------------------------------------------------------*/
2039 /* geniCodeUnaryMinus - does a unary minus of the operand */
2040 /*-----------------------------------------------------------------*/
2041 operand *geniCodeUnaryMinus (operand *op)
2044 link *optype = operandType(op);
2046 if (IS_LITERAL(optype))
2047 return operandFromLit(- floatFromVal(op->operand.valOperand));
2049 ic = newiCode(UNARYMINUS,op,NULL);
2050 IC_RESULT(ic) = newiTempOperand(optype,0);
2052 return IC_RESULT(ic);
2055 /*-----------------------------------------------------------------*/
2056 /* geniCodeLeftShift - gen i code for left shift */
2057 /*-----------------------------------------------------------------*/
2058 operand *geniCodeLeftShift (operand *left, operand *right)
2061 link *ltype = operandType(left);
2063 ic = newiCode(LEFT_OP,left,right);
2064 IC_RESULT(ic) = newiTempOperand(ltype,0);
2066 return IC_RESULT(ic) ;
2069 /*-----------------------------------------------------------------*/
2070 /* geniCodeRightShift - gen i code for right shift */
2071 /*-----------------------------------------------------------------*/
2072 operand *geniCodeRightShift (operand *left, operand *right)
2075 link *ltype = operandType(left);
2077 ic = newiCode(RIGHT_OP,left,right);
2078 IC_RESULT(ic) = newiTempOperand(ltype,0);
2080 return IC_RESULT(ic) ;
2083 /*-----------------------------------------------------------------*/
2084 /* geniCodeLogic- logic code */
2085 /*-----------------------------------------------------------------*/
2086 operand *geniCodeLogic (operand *left, operand *right, int op )
2090 link *rtype = operandType(right);
2091 link *ltype = operandType(left);
2093 /* left is integral type and right is literal then
2094 check if the literal value is within bounds */
2095 if (IS_INTEGRAL(ltype) && IS_LITERAL(rtype)) {
2096 int nbits = bitsForType(ltype);
2097 long v = operandLitValue(right);
2099 if (v > ((long long) 1 << nbits) && v > 0)
2100 werror(W_CONST_RANGE," compare operation ");
2103 ctype = computeType(ltype,rtype);
2104 left = geniCodeCast(ctype,left,TRUE);
2105 right= geniCodeCast(ctype,right,TRUE);
2107 ic = newiCode(op,left,right);
2108 IC_RESULT(ic) = newiTempOperand (newCharLink(),1);
2110 /* if comparing anything greater than one byte
2111 and not a '==' || '!=' || '&&' || '||' (these
2113 if (getSize(ctype) > 1 &&
2121 return IC_RESULT(ic);
2124 /*-----------------------------------------------------------------*/
2125 /* geniCodeUnary - for a a generic unary operation */
2126 /*-----------------------------------------------------------------*/
2127 operand *geniCodeUnary (operand *op, int oper )
2129 iCode *ic = newiCode (oper,op,NULL);
2131 IC_RESULT(ic)= newiTempOperand(operandType(op),0);
2133 return IC_RESULT(ic) ;
2136 /*-----------------------------------------------------------------*/
2137 /* geniCodeConditional - geniCode for '?' ':' operation */
2138 /*-----------------------------------------------------------------*/
2139 operand *geniCodeConditional (ast *tree)
2142 symbol *falseLabel = newiTempLabel(NULL);
2143 symbol *exitLabel = newiTempLabel(NULL);
2144 operand *cond = ast2iCode(tree->left);
2145 operand *true, *false , *result;
2147 ic = newiCodeCondition(geniCodeRValue(cond,FALSE),
2151 true = ast2iCode(tree->right->left);
2153 /* move the value to a new Operand */
2154 result = newiTempOperand(operandType(true),0);
2155 geniCodeAssign(result,geniCodeRValue(true,FALSE),0);
2157 /* generate an unconditional goto */
2158 geniCodeGoto(exitLabel);
2160 /* now for the right side */
2161 geniCodeLabel(falseLabel);
2163 false = ast2iCode(tree->right->right);
2164 geniCodeAssign(result,geniCodeRValue(false,FALSE),0);
2166 /* create the exit label */
2167 geniCodeLabel(exitLabel);
2172 /*-----------------------------------------------------------------*/
2173 /* geniCodeAssign - generate code for assignment */
2174 /*-----------------------------------------------------------------*/
2175 operand *geniCodeAssign (operand *left, operand *right, int nosupdate)
2178 link *ltype = operandType(left);
2179 link *rtype = operandType(right);
2181 if (!left->isaddr && !IS_ITEMP(left)) {
2182 werror(E_LVALUE_REQUIRED,"assignment");
2186 /* left is integral type and right is literal then
2187 check if the literal value is within bounds */
2188 if (IS_INTEGRAL(ltype) && IS_LITERAL(rtype)) {
2189 int nbits = bitsForType(ltype);
2190 long v = operandLitValue(right);
2192 if (v > ((long long)1 << nbits) && v > 0)
2193 werror(W_CONST_RANGE," = operation");
2195 /* if the left & right type don't exactly match */
2196 /* if pointer set then make sure the check is
2197 done with the type & not the pointer */
2198 /* then cast rights type to left */
2200 /* first check the type for pointer assignement */
2201 if (left->isaddr && IS_PTR(ltype) && IS_ITEMP(left) &&
2202 checkType(ltype,rtype)<0) {
2203 if (checkType(ltype->next,rtype) < 0)
2204 right = geniCodeCast(ltype->next,right,TRUE);
2206 if (checkType(ltype,rtype) < 0 )
2207 right = geniCodeCast(ltype,right,TRUE);
2209 /* if left is a true symbol & ! volatile
2210 create an assignment to temporary for
2211 the right & then assign this temporary
2212 to the symbol this is SSA . isn't it simple
2213 and folks have published mountains of paper on it */
2214 if (IS_TRUE_SYMOP(left) &&
2215 !isOperandVolatile(left,FALSE) &&
2216 isOperandGlobal(left)) {
2219 if (IS_TRUE_SYMOP(right))
2220 sym = OP_SYMBOL(right);
2221 ic = newiCode('=',NULL,right);
2222 IC_RESULT(ic) = right = newiTempOperand(ltype,0);
2223 SPIL_LOC(right) = sym ;
2227 ic = newiCode('=',NULL,right);
2228 IC_RESULT(ic) = left;
2231 /* if left isgptr flag is set then support
2232 routine will be required */
2236 ic->nosupdate = nosupdate;
2240 /*-----------------------------------------------------------------*/
2241 /* geniCodeSEParms - generate code for side effecting fcalls */
2242 /*-----------------------------------------------------------------*/
2243 static void geniCodeSEParms (ast *parms)
2248 if (parms->type == EX_OP && parms->opval.op == PARAM) {
2249 geniCodeSEParms (parms->left) ;
2250 geniCodeSEParms (parms->right);
2254 /* hack don't like this but too lazy to think of
2256 if (IS_ADDRESS_OF_OP(parms))
2257 parms->left->lvalue = 1;
2259 if (IS_CAST_OP(parms) &&
2260 IS_PTR(parms->ftype) &&
2261 IS_ADDRESS_OF_OP(parms->right))
2262 parms->right->left->lvalue = 1;
2264 parms->opval.oprnd =
2265 geniCodeRValue(ast2iCode (parms),TRUE);
2267 parms->type = EX_OPERAND ;
2270 /*-----------------------------------------------------------------*/
2271 /* geniCodeParms - generates parameters */
2272 /*-----------------------------------------------------------------*/
2273 static void geniCodeParms ( ast *parms , int *stack, link *fetype)
2281 /* if this is a param node then do the left & right */
2282 if (parms->type == EX_OP && parms->opval.op == PARAM) {
2283 geniCodeParms (parms->left, stack,fetype) ;
2284 geniCodeParms (parms->right, stack,fetype);
2288 /* get the parameter value */
2289 if (parms->type == EX_OPERAND)
2290 pval = parms->opval.oprnd ;
2292 /* maybe this else should go away ?? */
2293 /* hack don't like this but too lazy to think of
2295 if (IS_ADDRESS_OF_OP(parms))
2296 parms->left->lvalue = 1;
2298 if (IS_CAST_OP(parms) &&
2299 IS_PTR(parms->ftype) &&
2300 IS_ADDRESS_OF_OP(parms->right))
2301 parms->right->left->lvalue = 1;
2303 pval = geniCodeRValue(ast2iCode (parms),FALSE);
2306 /* if register parm then make it a send */
2307 if ((parms->argSym && IS_REGPARM(parms->argSym->etype)) ||
2308 IS_REGPARM(parms->etype)) {
2309 ic = newiCode(SEND,pval,NULL);
2312 /* now decide whether to push or assign */
2313 if (!(options.stackAuto || IS_RENT(fetype))) {
2316 operand *top = operandFromSymbol(parms->argSym);
2317 geniCodeAssign(top,pval,1);
2322 ic = newiCode(IPUSH,pval,NULL);
2324 /* update the stack adjustment */
2325 *stack += getSize(operandType(pval));
2332 /*-----------------------------------------------------------------*/
2333 /* geniCodeCall - generates temp code for calling */
2334 /*-----------------------------------------------------------------*/
2335 operand *geniCodeCall (operand *left, ast *parms)
2342 /* take care of parameters with side-effecting
2343 function calls in them, this is required to take care
2344 of overlaying function parameters */
2345 geniCodeSEParms ( parms );
2347 /* first the parameters */
2348 geniCodeParms ( parms , &stack , getSpec(operandType(left)));
2350 /* now call : if symbol then pcall */
2352 ic = newiCode(PCALL,left,NULL);
2354 ic = newiCode(CALL,left,NULL);
2356 IC_ARGS(ic) = left->operand.symOperand->args ;
2357 type = copyLinkChain(operandType(left)->next);
2358 etype = getSpec(type);
2359 SPEC_EXTR(etype) = 0;
2360 IC_RESULT(ic) = result = newiTempOperand(type,1);
2364 /* stack adjustment after call */
2365 left->parmBytes = stack;
2370 /*-----------------------------------------------------------------*/
2371 /* geniCodeReceive - generate intermediate code for "receive" */
2372 /*-----------------------------------------------------------------*/
2373 static void geniCodeReceive (value *args)
2375 /* for all arguments that are passed in registers */
2378 if (IS_REGPARM(args->etype)) {
2379 operand *opr = operandFromValue(args);
2381 symbol *sym = OP_SYMBOL(opr);
2384 /* we will use it after all optimizations
2385 and before liveRange calculation */
2386 if (!sym->addrtaken &&
2387 !IS_VOLATILE(sym->etype) &&
2388 !IN_FARSPACE(SPEC_OCLS(sym->etype))) {
2389 opl = newiTempOperand(args->type,0);
2391 sym->reqv->key = sym->key ;
2392 OP_SYMBOL(sym->reqv)->key = sym->key;
2393 OP_SYMBOL(sym->reqv)->isreqv = 1;
2394 OP_SYMBOL(sym->reqv)->islocal= 0;
2395 SPIL_LOC(sym->reqv) = sym;
2398 ic = newiCode(RECEIVE,NULL,NULL);
2399 currFunc->recvSize = getSize(sym->etype);
2400 IC_RESULT(ic) = opr;
2408 /*-----------------------------------------------------------------*/
2409 /* geniCodeFunctionBody - create the function body */
2410 /*-----------------------------------------------------------------*/
2411 void geniCodeFunctionBody (ast *tree)
2418 /* reset the auto generation */
2424 func = ast2iCode(tree->left);
2425 fetype = getSpec(operandType(func));
2427 savelineno = lineno;
2428 lineno = OP_SYMBOL(func)->lineDef;
2429 /* create an entry label */
2430 geniCodeLabel(entryLabel);
2431 lineno = savelineno;
2433 /* create a proc icode */
2434 ic = newiCode(FUNCTION,func,NULL);
2435 /* if the function has parmas then */
2436 /* save the parameters information */
2437 ic->argLabel.args = tree->values.args ;
2438 ic->lineno = OP_SYMBOL(func)->lineDef;
2442 /* for all parameters that are passed
2443 on registers add a "receive" */
2444 geniCodeReceive( tree->values.args );
2446 /* generate code for the body */
2447 ast2iCode(tree->right);
2449 /* create a label for return */
2450 geniCodeLabel(returnLabel);
2452 /* now generate the end proc */
2453 ic = newiCode(ENDFUNCTION,func,NULL);
2458 /*-----------------------------------------------------------------*/
2459 /* geniCodeReturn - gen icode for 'return' statement */
2460 /*-----------------------------------------------------------------*/
2461 void geniCodeReturn (operand *op)
2465 /* if the operand is present force an rvalue */
2467 op = geniCodeRValue(op,FALSE);
2469 ic = newiCode(RETURN,op,NULL);
2473 /*-----------------------------------------------------------------*/
2474 /* geniCodeIfx - generates code for extended if statement */
2475 /*-----------------------------------------------------------------*/
2476 void geniCodeIfx (ast *tree)
2479 operand *condition = ast2iCode(tree->left);
2480 /* link *ctype = operandType(condition); */
2483 /* if condition is null then exit */
2487 condition = geniCodeRValue(condition,FALSE);
2489 cetype = getSpec(operandType(condition));
2490 /* if the condition is a literal */
2491 if (IS_LITERAL(cetype)) {
2492 if (floatFromVal(condition->operand.valOperand)) {
2493 if (tree->trueLabel)
2494 geniCodeGoto(tree->trueLabel);
2499 if (tree->falseLabel)
2500 geniCodeGoto (tree->falseLabel);
2507 if ( tree->trueLabel ) {
2508 ic = newiCodeCondition(condition,
2513 if ( tree->falseLabel)
2514 geniCodeGoto(tree->falseLabel);
2517 ic = newiCodeCondition (condition,
2524 ast2iCode(tree->right);
2527 /*-----------------------------------------------------------------*/
2528 /* geniCodeJumpTable - tries to create a jump table for switch */
2529 /*-----------------------------------------------------------------*/
2530 int geniCodeJumpTable (operand *cond, value *caseVals, ast *tree)
2532 int min = 0 ,max = 0, t, cnt = 0;
2537 set *labels = NULL ;
2539 if (!tree || !caseVals)
2542 /* the criteria for creating a jump table is */
2543 /* all integer numbers between the maximum & minimum must */
2544 /* be present , the maximum value should not exceed 255 */
2545 min = max = (int)floatFromVal(vch = caseVals);
2546 sprintf(buffer,"_case_%d_%d",
2547 tree->values.switchVals.swNum,
2549 addSet(&labels,newiTempLabel(buffer));
2551 /* if there is only one case value then no need */
2552 if (!(vch = vch->next ))
2556 if (((t = (int)floatFromVal(vch)) - max) != 1)
2558 sprintf(buffer,"_case_%d_%d",
2559 tree->values.switchVals.swNum,
2561 addSet(&labels,newiTempLabel(buffer));
2567 /* if the number of case statements <= 2 then */
2568 /* it is not economical to create the jump table */
2569 /* since two compares are needed for boundary conditions */
2570 if ((! optimize.noJTabBoundary && cnt <= 2) || max > (255/3))
2573 if ( tree->values.switchVals.swDefault )
2574 sprintf (buffer,"_default_%d",tree->values.switchVals.swNum);
2576 sprintf (buffer,"_swBrk_%d",tree->values.switchVals.swNum );
2578 falseLabel = newiTempLabel (buffer);
2580 /* so we can create a jumptable */
2581 /* first we rule out the boundary conditions */
2582 /* if only optimization says so */
2583 if ( ! optimize.noJTabBoundary ) {
2584 link *cetype = getSpec(operandType(cond));
2585 /* no need to check the lower bound if
2586 the condition is unsigned & minimum value is zero */
2587 if (!( min == 0 && SPEC_USIGN(cetype))) {
2588 boundary = geniCodeLogic (cond,operandFromLit(min),'<');
2589 ic = newiCodeCondition (boundary,falseLabel,NULL);
2593 /* now for upper bounds */
2594 boundary = geniCodeLogic(cond,operandFromLit(max),'>');
2595 ic = newiCodeCondition (boundary,falseLabel,NULL);
2599 /* if the min is not zero then we no make it zero */
2601 cond = geniCodeSubtract(cond,operandFromLit(min));
2602 setOperandType(cond,ucharType);
2605 /* now create the jumptable */
2606 ic = newiCode(JUMPTABLE,NULL,NULL);
2607 IC_JTCOND(ic) = cond;
2608 IC_JTLABELS(ic) = labels;
2613 /*-----------------------------------------------------------------*/
2614 /* geniCodeSwitch - changes a switch to a if statement */
2615 /*-----------------------------------------------------------------*/
2616 void geniCodeSwitch (ast *tree)
2619 operand *cond = geniCodeRValue(ast2iCode (tree->left),FALSE);
2620 value *caseVals = tree->values.switchVals.swVals ;
2621 symbol *trueLabel , *falseLabel;
2623 /* if we can make this a jump table */
2624 if ( geniCodeJumpTable (cond,caseVals,tree) )
2625 goto jumpTable ; /* no need for the comparison */
2627 /* for the cases defined do */
2630 operand *compare = geniCodeLogic (cond,
2631 operandFromValue(caseVals),
2634 sprintf(buffer,"_case_%d_%d",
2635 tree->values.switchVals.swNum,
2636 (int) floatFromVal(caseVals));
2637 trueLabel = newiTempLabel(buffer);
2639 ic = newiCodeCondition(compare,trueLabel,NULL);
2641 caseVals = caseVals->next;
2646 /* if default is present then goto break else break */
2647 if ( tree->values.switchVals.swDefault )
2648 sprintf (buffer,"_default_%d",tree->values.switchVals.swNum);
2650 sprintf (buffer,"_swBrk_%d",tree->values.switchVals.swNum );
2652 falseLabel = newiTempLabel (buffer);
2653 geniCodeGoto(falseLabel);
2656 ast2iCode(tree->right);
2659 /*-----------------------------------------------------------------*/
2660 /* geniCodeInline - intermediate code for inline assembler */
2661 /*-----------------------------------------------------------------*/
2662 static void geniCodeInline (ast *tree)
2666 ic = newiCode(INLINEASM,NULL,NULL);
2667 IC_INLINE(ic) = tree->values.inlineasm;
2671 /*-----------------------------------------------------------------*/
2672 /* ast2iCode - creates an icodeList from an ast */
2673 /*-----------------------------------------------------------------*/
2674 operand *ast2iCode (ast *tree)
2676 operand *left = NULL;
2677 operand *right= NULL;
2682 /* set the global variables for filename & line number */
2683 if ( tree->filename )
2684 filename = tree->filename ;
2686 lineno = tree->lineno ;
2688 block = tree->block ;
2690 scopeLevel = tree->level;
2692 if (tree->type == EX_VALUE )
2693 return operandFromValue(tree->opval.val);
2695 if (tree->type == EX_LINK )
2696 return operandFromLink (tree->opval.lnk);
2698 /* if we find a nullop */
2699 if (tree->type == EX_OP &&
2700 ( tree->opval.op == NULLOP ||
2701 tree->opval.op == BLOCK )) {
2702 ast2iCode (tree->left);
2703 ast2iCode (tree->right);
2707 /* special cases for not evaluating */
2708 if ( tree->opval.op != ':' &&
2709 tree->opval.op != '?' &&
2710 tree->opval.op != CALL &&
2711 tree->opval.op != IFX &&
2712 tree->opval.op != LABEL &&
2713 tree->opval.op != GOTO &&
2714 tree->opval.op != SWITCH &&
2715 tree->opval.op != FUNCTION &&
2716 tree->opval.op != INLINEASM ) {
2717 if (IS_ASSIGN_OP(tree->opval.op) || IS_DEREF_OP(tree)) {
2719 left = operandFromAst(tree->left);
2722 left = operandFromAst(tree->left);
2724 right= operandFromAst(tree->right);
2727 /* now depending on the type of operand */
2728 /* this will be a biggy */
2729 switch (tree->opval.op) {
2731 case '[' : /* array operation */
2732 left= geniCodeRValue (left,FALSE);
2733 right=geniCodeRValue (right,TRUE);
2735 return geniCodeArray (left,right);
2737 case '.' : /* structure dereference */
2738 if (IS_PTR(operandType(left)))
2739 left = geniCodeRValue(left,TRUE);
2741 left = geniCodeRValue(left,FALSE);
2743 return geniCodeStruct (left,right,tree->lvalue);
2745 case PTR_OP: /* structure pointer dereference */
2748 pType = operandType(left);
2749 left = geniCodeRValue(left,TRUE);
2751 setOClass (pType,getSpec(operandType(left)));
2754 return geniCodeStruct (left, right,tree->lvalue);
2756 case INC_OP: /* increment operator */
2758 return geniCodePostInc (left);
2760 return geniCodePreInc (right);
2762 case DEC_OP: /* decrement operator */
2764 return geniCodePostDec (left);
2766 return geniCodePreDec (right);
2768 case '&' : /* bitwise and or address of operator */
2769 if ( right ) { /* this is a bitwise operator */
2770 left= geniCodeRValue(left,FALSE);
2771 right= geniCodeRValue(right,FALSE);
2772 return geniCodeBitwise (left,right,BITWISEAND,tree->ftype);
2774 return geniCodeAddressOf (left);
2776 case '|': /* bitwise or & xor */
2778 return geniCodeBitwise (geniCodeRValue(left,FALSE),
2779 geniCodeRValue(right,FALSE),
2784 return geniCodeDivision (geniCodeRValue(left,FALSE),
2785 geniCodeRValue(right,FALSE));
2788 return geniCodeModulus (geniCodeRValue(left,FALSE),
2789 geniCodeRValue(right,FALSE));
2792 return geniCodeMultiply (geniCodeRValue(left,FALSE),
2793 geniCodeRValue(right,FALSE));
2795 return geniCodeDerefPtr (geniCodeRValue(left,FALSE));
2799 return geniCodeSubtract (geniCodeRValue(left,FALSE),
2800 geniCodeRValue(right,FALSE));
2802 return geniCodeUnaryMinus (geniCodeRValue(left,FALSE));
2806 return geniCodeAdd (geniCodeRValue(left,FALSE),
2807 geniCodeRValue(right,FALSE));
2809 return geniCodeRValue(left,FALSE) ; /* unary '+' has no meaning */
2812 return geniCodeLeftShift (geniCodeRValue(left,FALSE),
2813 geniCodeRValue(right,FALSE));
2816 return geniCodeRightShift (geniCodeRValue(left,FALSE),
2817 geniCodeRValue(right,FALSE));
2819 return geniCodeCast (operandType(left),
2820 geniCodeRValue(right,FALSE),FALSE);
2826 return geniCodeUnary (geniCodeRValue(left,FALSE),tree->opval.op);
2830 operand *op = geniCodeUnary (geniCodeRValue(left,FALSE),tree->opval.op);
2831 setOperandType(op,ucharType);
2842 return geniCodeLogic (geniCodeRValue(left,FALSE),
2843 geniCodeRValue(right,FALSE),
2846 return geniCodeConditional (tree);
2849 return operandFromLit(getSize(tree->right->ftype));
2853 link *rtype = operandType(right);
2854 link *ltype = operandType(left);
2855 if (IS_PTR(rtype) && IS_ITEMP(right)
2856 && right->isaddr && checkType(rtype->next,ltype)==1)
2857 right = geniCodeRValue(right,TRUE);
2859 right = geniCodeRValue(right,FALSE);
2861 geniCodeAssign (left,right,0);
2866 geniCodeAssign(left,
2867 geniCodeMultiply(geniCodeRValue (operandFromOperand(left),
2869 geniCodeRValue(right,FALSE)),0);
2873 geniCodeAssign(left,
2874 geniCodeDivision(geniCodeRValue(operandFromOperand(left),
2876 geniCodeRValue(right,FALSE)),0);
2879 geniCodeAssign(left,
2880 geniCodeModulus(geniCodeRValue(operandFromOperand(left),
2882 geniCodeRValue(right,FALSE)),0);
2885 link *rtype = operandType(right);
2886 link *ltype = operandType(left);
2887 if (IS_PTR(rtype) && IS_ITEMP(right)
2888 && right->isaddr && checkType(rtype->next,ltype)==1)
2889 right = geniCodeRValue(right,TRUE);
2891 right = geniCodeRValue(right,FALSE);
2894 return geniCodeAssign(left,
2895 geniCodeAdd (geniCodeRValue(operandFromOperand(left),
2901 link *rtype = operandType(right);
2902 link *ltype = operandType(left);
2903 if (IS_PTR(rtype) && IS_ITEMP(right)
2904 && right->isaddr && checkType(rtype->next,ltype)==1) {
2905 right = geniCodeRValue(right,TRUE);
2908 right = geniCodeRValue(right,FALSE);
2911 geniCodeAssign (left,
2912 geniCodeSubtract(geniCodeRValue(operandFromOperand(left),
2918 geniCodeAssign (left,
2919 geniCodeLeftShift(geniCodeRValue(operandFromOperand(left)
2921 geniCodeRValue(right,FALSE)),0);
2924 geniCodeAssign(left,
2925 geniCodeRightShift(geniCodeRValue(operandFromOperand(left)
2927 geniCodeRValue(right,FALSE)),0);
2930 geniCodeAssign (left,
2931 geniCodeBitwise(geniCodeRValue(operandFromOperand(left),
2933 geniCodeRValue(right,FALSE),
2935 operandType(left)),0);
2938 geniCodeAssign (left,
2939 geniCodeBitwise (geniCodeRValue(operandFromOperand(left),
2941 geniCodeRValue(right,FALSE),
2943 operandType(left)),0);
2946 geniCodeAssign (left,
2947 geniCodeBitwise (geniCodeRValue(operandFromOperand(left)
2949 geniCodeRValue(right,FALSE),
2951 operandType(left)),0);
2953 return geniCodeRValue(right,FALSE);
2956 return geniCodeCall (ast2iCode(tree->left),
2959 geniCodeLabel(ast2iCode(tree->left)->operand.symOperand);
2960 return ast2iCode (tree->right);
2963 geniCodeGoto (ast2iCode(tree->left)->operand.symOperand);
2964 return ast2iCode (tree->right);
2967 geniCodeFunctionBody ( tree );
2971 geniCodeReturn (right);
2979 geniCodeSwitch (tree);
2983 geniCodeInline (tree);
2990 /*-----------------------------------------------------------------*/
2991 /* reverseICChain - gets from the list and creates a linkedlist */
2992 /*-----------------------------------------------------------------*/
2993 iCode *reverseiCChain ()
2995 iCode *loop = NULL ;
2996 iCode *prev = NULL ;
2998 while ((loop = getSet(&iCodeChain))) {
3009 /*-----------------------------------------------------------------*/
3010 /* iCodeFromAst - given an ast will convert it to iCode */
3011 /*-----------------------------------------------------------------*/
3012 iCode *iCodeFromAst ( ast *tree )
3014 returnLabel = newiTempLabel("_return");
3015 entryLabel = newiTempLabel("_entry") ;
3017 return reverseiCChain ();