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 -------------------------------------------------------------------------*/
27 /*-----------------------------------------------------------------*/
28 /* global variables */
30 set *iCodeChain = NULL ;
41 symbol *returnLabel ; /* function return label */
42 symbol *entryLabel ; /* function entry label */
43 /*-----------------------------------------------------------------*/
44 /* forward definition of some functions */
45 operand *geniCodeDivision (operand *,operand *);
46 operand *geniCodeAssign (operand *,operand *,int);
47 operand *geniCodeArray (operand *,operand *);
48 operand *geniCodeArray2Ptr (operand *);
49 operand *geniCodeRValue (operand *, bool );
50 operand *geniCodeDerefPtr (operand *);
52 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
53 /* forward definition of print functions */
54 PRINTFUNC(picGetValueAtAddr);
55 PRINTFUNC(picSetValueAtAddr);
57 PRINTFUNC(picGeneric);
58 PRINTFUNC(picGenericOne);
64 PRINTFUNC(picJumpTable);
66 PRINTFUNC(picReceive);
68 iCodeTable codeTable[] = {
69 { '!' , "not", picGenericOne , NULL },
70 { '~' , "~" , picGenericOne , NULL },
71 { RRC , "rrc", picGenericOne , NULL },
72 { RLC , "rlc", picGenericOne , NULL },
73 { GETHBIT ,"ghbit", picGenericOne , NULL },
74 { UNARYMINUS , "-" , picGenericOne , NULL },
75 { IPUSH , "push",picGenericOne , NULL },
76 { IPOP , "pop", picGenericOne , NULL },
77 { CALL , "call",picGenericOne , NULL },
78 { PCALL , "pcall",picGenericOne , NULL },
79 { FUNCTION , "proc", picGenericOne , NULL },
80 { ENDFUNCTION ,"eproc", picGenericOne , NULL },
81 { RETURN , "ret", picGenericOne , NULL },
82 { '+' , "+" , picGeneric , NULL },
83 { '-' , "-" , picGeneric , NULL },
84 { '*' , "*" , picGeneric , NULL },
85 { '/' , "/" , picGeneric , NULL },
86 { '%' , "%" , picGeneric , NULL },
87 { '>' , ">" , picGeneric , NULL },
88 { '<' , "<" , picGeneric , NULL },
89 { LE_OP , "<=" , picGeneric , NULL },
90 { GE_OP , ">=" , picGeneric , NULL },
91 { EQ_OP , "==" , picGeneric , NULL },
92 { NE_OP , "!=" , picGeneric , NULL },
93 { AND_OP , "&&" , picGeneric , NULL },
94 { OR_OP , "||" , picGeneric , NULL },
95 { '^' , "^" , picGeneric , NULL },
96 { '|' , "|" , picGeneric , NULL },
97 { BITWISEAND , "&" , picGeneric , NULL },
98 { LEFT_OP , "<<" , picGeneric , NULL },
99 { RIGHT_OP , ">>" , picGeneric , NULL },
100 { GET_VALUE_AT_ADDRESS, "@" , picGetValueAtAddr, NULL },
101 { ADDRESS_OF , "&" , picAddrOf , NULL },
102 { CAST , "<>" , picCast , NULL },
103 { '=' , ":=" , picAssign , NULL },
104 { LABEL , "" , picLabel , NULL },
105 { GOTO , "" , picGoto , NULL },
106 { JUMPTABLE ,"jtab" , picJumpTable , NULL },
107 { IFX , "if" , picIfx , NULL },
108 { INLINEASM , "" , picInline , NULL },
109 { RECEIVE , "recv", picReceive , NULL },
110 { SEND , "send", picGenericOne , NULL }
114 /*-----------------------------------------------------------------*/
115 /* operandName - returns the name of the operand */
116 /*-----------------------------------------------------------------*/
117 int printOperand (operand *op, FILE *file)
132 opetype = getSpec (operandType(op));
133 if (SPEC_NOUN(opetype) == V_FLOAT)
134 fprintf (file,"%g {", SPEC_CVAL(opetype).v_float);
136 fprintf (file,"0x%x {",(int) floatFromVal(op->operand.valOperand));
137 printTypeChain(operandType(op),file);
144 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}" ,*/
145 (OP_SYMBOL(op)->rname[0] ? OP_SYMBOL(op)->rname : OP_SYMBOL(op)->name),
147 OP_LIVEFROM(op),OP_LIVETO(op),
148 OP_SYMBOL(op)->stack,
149 op->isaddr, OP_SYMBOL(op)->isreqv,OP_SYMBOL(op)->remat
152 fprintf(file,"{"); printTypeChain(operandType(op),file);
153 if (SPIL_LOC(op) && IS_ITEMP(op))
154 fprintf(file,"}{ sir@ %s",SPIL_LOC(op)->rname);
159 /* if assigned to registers */
160 if (OP_SYMBOL(op)->nRegs) {
161 if (OP_SYMBOL(op)->isspilt) {
162 if (!OP_SYMBOL(op)->remat)
163 if (OP_SYMBOL(op)->usl.spillLoc)
164 fprintf(file,"[%s]",(OP_SYMBOL(op)->usl.spillLoc->rname[0] ?
165 OP_SYMBOL(op)->usl.spillLoc->rname :
166 OP_SYMBOL(op)->usl.spillLoc->name));
168 fprintf(file,"[err]");
170 fprintf(file,"[remat]");
175 for(i=0;i<OP_SYMBOL(op)->nRegs;i++)
176 fprintf(file,"%s ", port->getRegName(OP_SYMBOL(op)->regs[i]));
181 fprintf(file,"%s",(OP_SYMBOL(op)->rname[0] ?
182 OP_SYMBOL(op)->rname : OP_SYMBOL(op)->name));
183 /* if assigned to registers */
184 if (OP_SYMBOL(op)->nRegs && !OP_SYMBOL(op)->isspilt) {
187 for(i=0;i<OP_SYMBOL(op)->nRegs;i++)
188 fprintf(file,"%s ",(OP_SYMBOL(op)->regs[i] ?
189 OP_SYMBOL(op)->regs[i]->name :
198 printTypeChain(op->operand.typeOperand,file);
209 /*-----------------------------------------------------------------*/
210 /* print functions */
211 /*-----------------------------------------------------------------*/
212 PRINTFUNC(picGetValueAtAddr)
215 printOperand (IC_RESULT(ic),of);
218 printOperand (IC_LEFT(ic), of);
224 PRINTFUNC(picSetValueAtAddr)
228 printOperand(IC_LEFT(ic),of);
230 printOperand(IC_RIGHT(ic),of);
237 printOperand(IC_RESULT(ic),of);
238 if (IS_ITEMP(IC_LEFT(ic)))
242 printOperand(IC_LEFT(ic),of);
244 if (IS_ITEMP(IC_LEFT(ic)))
245 fprintf(of," offsetAdd ");
248 printOperand(IC_RIGHT(ic),of);
250 if (IS_ITEMP(IC_LEFT(ic)))
256 PRINTFUNC(picJumpTable)
261 fprintf(of,"%s\t",s);
262 printOperand(IC_JTCOND(ic),of);
264 for ( sym = setFirstItem(IC_JTLABELS(ic)); sym;
265 sym = setNextItem(IC_JTLABELS(ic)))
266 fprintf(of,"\t\t\t%s\n",sym->name);
269 PRINTFUNC(picGeneric)
272 printOperand(IC_RESULT(ic),of);
274 printOperand(IC_LEFT(ic),of);
275 fprintf(of," %s ",s);
276 printOperand(IC_RIGHT(ic),of);
280 PRINTFUNC(picGenericOne)
283 if ( IC_RESULT(ic) ) {
284 printOperand(IC_RESULT(ic),of);
289 fprintf (of,"%s ",s);
290 printOperand(IC_LEFT(ic),of);
293 if (! IC_RESULT(ic) && !IC_LEFT(ic))
302 printOperand(IC_RESULT(ic),of);
304 printOperand(IC_LEFT(ic),of);
305 printOperand(IC_RIGHT(ic),of);
314 if (IC_RESULT(ic)->isaddr && IS_ITEMP(IC_RESULT(ic)))
317 printOperand(IC_RESULT(ic),of);
319 if (IC_RESULT(ic)->isaddr && IS_ITEMP(IC_RESULT(ic)))
322 fprintf(of," %s ", s);
323 printOperand (IC_RIGHT(ic),of);
330 fprintf(of," %s($%d) :\n",IC_LABEL(ic)->name,IC_LABEL(ic)->key);
336 fprintf (of," goto %s($%d)\n", IC_LABEL(ic)->name,IC_LABEL(ic)->key);
343 printOperand(IC_COND(ic),of);
346 fprintf (of," == 0 goto %s($%d)\n",IC_FALSE(ic)->name,IC_FALSE(ic)->key);
348 fprintf (of," != 0 goto %s($%d)\n",IC_TRUE(ic)->name,IC_TRUE(ic)->key);
350 fprintf (of,"\tzzgoto %s\n",IC_FALSE(ic)->name);
356 fprintf(of,"%s",IC_INLINE(ic));
359 PRINTFUNC(picReceive)
361 printOperand(IC_RESULT(ic),of);
362 fprintf(of," = %s ",s);
363 printOperand(IC_LEFT(ic),of);
367 /*-----------------------------------------------------------------*/
368 /* piCode - prints one iCode */
369 /*-----------------------------------------------------------------*/
370 int piCode (void *item, FILE *of)
378 icTab = getTableEntry(ic->op) ;
379 fprintf(stdout,"%s(%d:%d:%d:%d:%d)\t",
380 ic->filename,ic->lineno,
381 ic->seq,ic->key,ic->depth,ic->supportRtn);
382 icTab->iCodePrint(of,ic,icTab->printName);
386 /*-----------------------------------------------------------------*/
387 /* printiCChain - prints intermediate code for humans */
388 /*-----------------------------------------------------------------*/
389 void printiCChain (iCode *icChain, FILE *of)
396 for ( loop = icChain ; loop ; loop = loop->next ) {
397 if ((icTab = getTableEntry (loop->op ))) {
398 fprintf(of,"%s(%d:%d:%d:%d:%d)\t",
399 loop->filename,loop->lineno,
400 loop->seq,loop->key,loop->depth,loop->supportRtn);
402 icTab->iCodePrint (of,loop,icTab->printName);
408 /*-----------------------------------------------------------------*/
409 /* newOperand - allocate, init & return a new iCode */
410 /*-----------------------------------------------------------------*/
411 operand *newOperand ()
415 ALLOC(op,sizeof(operand));
421 /*-----------------------------------------------------------------*/
422 /* newiCode - create and return a new iCode entry initialised */
423 /*-----------------------------------------------------------------*/
424 iCode *newiCode (int op, operand *left, operand *right)
428 ALLOC(ic,sizeof(iCode));
430 ic->lineno = lineno ;
431 ic->filename= filename ;
433 ic->level = scopeLevel;
435 ic->key= iCodeKey++ ;
442 /*-----------------------------------------------------------------*/
443 /* newiCode for conditional statements */
444 /*-----------------------------------------------------------------*/
445 iCode *newiCodeCondition (operand *condition,
451 ic = newiCode(IFX,NULL,NULL);
452 IC_COND(ic) = condition ;
453 IC_TRUE(ic) = trueLabel ;
454 IC_FALSE(ic) = falseLabel;
458 /*-----------------------------------------------------------------*/
459 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
460 /*-----------------------------------------------------------------*/
461 iCode *newiCodeLabelGoto (int op, symbol *label)
465 ic = newiCode(op,NULL,NULL);
467 ic->argLabel.label = label ;
469 IC_RIGHT(ic) = NULL ;
470 IC_RESULT(ic) = NULL ;
474 /*-----------------------------------------------------------------*/
475 /* newiTemp - allocate & return a newItemp Variable */
476 /*-----------------------------------------------------------------*/
477 symbol *newiTemp (char *s)
482 sprintf(buffer,"%s",s);
484 sprintf (buffer,"iTemp%d",iTempNum++);
485 itmp = newSymbol (buffer,1);
486 strcpy(itmp->rname,itmp->name);
492 /*-----------------------------------------------------------------*/
493 /* newiTempLabel - creates a temp variable label */
494 /*-----------------------------------------------------------------*/
495 symbol *newiTempLabel (char *s)
499 /* check if this alredy exists */
500 if (s && (itmplbl = findSym(LabelTab, NULL, s)))
504 itmplbl = newSymbol(s,1);
506 sprintf(buffer,"iTempLbl%d",iTempLblNum++);
507 itmplbl = newSymbol(buffer,1);
512 itmplbl->key = labelKey++ ;
513 addSym (LabelTab, itmplbl, itmplbl->name,0,0);
517 /*-----------------------------------------------------------------*/
518 /* newiTempPreheaderLabel - creates a new preheader label */
519 /*-----------------------------------------------------------------*/
520 symbol *newiTempPreheaderLabel()
524 sprintf(buffer,"preHeaderLbl%d",iTempLblNum++);
525 itmplbl = newSymbol(buffer,1);
529 itmplbl->key = labelKey++ ;
530 addSym (LabelTab, itmplbl, itmplbl->name,0,0);
535 /*-----------------------------------------------------------------*/
536 /* initiCode - initialises some iCode related stuff */
537 /*-----------------------------------------------------------------*/
543 /*-----------------------------------------------------------------*/
544 /* copyiCode - make a copy of the iCode given */
545 /*-----------------------------------------------------------------*/
546 iCode *copyiCode (iCode *ic)
548 iCode *nic = newiCode(ic->op,NULL,NULL);
550 nic->lineno = ic->lineno ;
551 nic->filename= ic->filename ;
552 nic->block = ic->block;
553 nic->level = ic->level;
555 /* deal with the special cases first */
558 IC_COND(nic) = operandFromOperand(IC_COND(ic));
559 IC_TRUE(nic) = IC_TRUE(ic);
560 IC_FALSE(nic)= IC_FALSE(ic);
564 IC_JTCOND(nic) = operandFromOperand(IC_JTCOND(ic));
565 IC_JTLABELS(nic) = IC_JTLABELS(ic);
570 IC_RESULT(nic) = operandFromOperand(IC_RESULT(ic));
571 IC_LEFT(nic) = operandFromOperand(IC_LEFT(ic));
572 IC_ARGS(nic) = IC_ARGS(ic);
576 IC_INLINE(nic) = IC_INLINE(ic);
580 IC_RESULT(nic) = operandFromOperand(IC_RESULT(ic));
581 IC_LEFT(nic) = operandFromOperand(IC_LEFT(ic));
582 IC_RIGHT(nic)= operandFromOperand(IC_RIGHT(ic));
588 /*-----------------------------------------------------------------*/
589 /* getTableEntry - gets the table entry for the given operator */
590 /*-----------------------------------------------------------------*/
591 iCodeTable *getTableEntry (int oper )
595 for ( i = 0 ; i < (sizeof(codeTable)/sizeof(iCodeTable)); i++ )
596 if (oper == codeTable[i].icode)
597 return &codeTable[i] ;
602 /*-----------------------------------------------------------------*/
603 /* newiTempOperand - new intermediate temp operand */
604 /*-----------------------------------------------------------------*/
605 operand *newiTempOperand (link *type, char throwType)
608 operand *op = newOperand();
612 itmp = newiTemp(NULL);
614 etype = getSpec(type);
616 if (IS_LITERAL(etype) )
619 /* copy the type information */
621 itmp->etype = getSpec (itmp->type = (throwType ? type :
622 copyLinkChain(type)));
623 if (IS_LITERAL(itmp->etype)) {
624 SPEC_SCLS(itmp->etype) = S_REGISTER ;
625 SPEC_OCLS(itmp->etype) = reg;
628 op->operand.symOperand = itmp;
629 op->key = itmp->key = ++operandKey ;
633 /*-----------------------------------------------------------------*/
634 /* operandType - returns the type chain for an operand */
635 /*-----------------------------------------------------------------*/
636 link *operandType (operand *op)
638 /* depending on type of operand */
642 return op->operand.valOperand->type ;
645 return op->operand.symOperand->type ;
648 return op->operand.typeOperand ;
650 werror (E_INTERNAL_ERROR,__FILE__,__LINE__,
651 " operand type not known ");
652 assert (0) ; /* should never come here */
653 /* Just to keep the compiler happy */
658 /*-----------------------------------------------------------------*/
659 /* isParamterToCall - will return 1 if op is a parameter to args */
660 /*-----------------------------------------------------------------*/
661 int isParameterToCall (value *args, operand *op)
667 isSymbolEqual(op->operand.symOperand,tval->sym))
674 /*-----------------------------------------------------------------*/
675 /* isOperandGlobal - return 1 if operand is a global variable */
676 /*-----------------------------------------------------------------*/
677 int isOperandGlobal ( operand *op )
685 if (op->type == SYMBOL &&
686 (op->operand.symOperand->level == 0 ||
687 IS_STATIC(op->operand.symOperand->etype) ||
688 IS_EXTERN(op->operand.symOperand->etype))
695 /*-----------------------------------------------------------------*/
696 /* isOperandVolatile - return 1 if the operand is volatile */
697 /*-----------------------------------------------------------------*/
698 int isOperandVolatile ( operand *op , bool chkTemp)
703 if (IS_ITEMP(op) && !chkTemp)
706 opetype = getSpec(optype = operandType(op));
708 if (IS_PTR(optype) && DCL_PTR_VOLATILE(optype))
711 if (IS_VOLATILE(opetype))
716 /*-----------------------------------------------------------------*/
717 /* isOperandLiteral - returns 1 if an operand contains a literal */
718 /*-----------------------------------------------------------------*/
719 int isOperandLiteral ( operand *op )
726 opetype = getSpec (operandType(op));
728 if (IS_LITERAL(opetype))
733 /*-----------------------------------------------------------------*/
734 /* isOperandInFarSpace - will return true if operand is in farSpace*/
735 /*-----------------------------------------------------------------*/
736 bool isOperandInFarSpace (operand *op)
746 if (!IS_TRUE_SYMOP(op)) {
748 etype = SPIL_LOC(op)->etype;
754 etype = getSpec(operandType(op));
756 return (IN_FARSPACE(SPEC_OCLS(etype)) ? TRUE : FALSE);
759 /*-----------------------------------------------------------------*/
760 /* isOperandOnStack - will return true if operand is on stack */
761 /*-----------------------------------------------------------------*/
762 bool isOperandOnStack(operand *op)
772 etype = getSpec(operandType(op));
774 return ((IN_STACK(etype)) ? TRUE : FALSE);
777 /*-----------------------------------------------------------------*/
778 /* operandLitValue - literal value of an operand */
779 /*-----------------------------------------------------------------*/
780 double operandLitValue ( operand *op )
782 assert(isOperandLiteral(op));
784 return floatFromVal(op->operand.valOperand);
787 /*-----------------------------------------------------------------*/
788 /* operandOperation - perforoms operations on operands */
789 /*-----------------------------------------------------------------*/
790 operand *operandOperation (operand *left,operand *right,
793 operand *retval = (operand *)0;
795 assert(isOperandLiteral(left));
797 assert(isOperandLiteral(right));
801 retval = operandFromValue (valCastLiteral(type,
802 operandLitValue(left) +
803 operandLitValue(right)));
806 retval = operandFromValue(valCastLiteral(type,
807 operandLitValue(left) -
808 operandLitValue(right)));
811 retval = operandFromValue(valCastLiteral(type,
812 operandLitValue(left) *
813 operandLitValue(right)));
816 if ((unsigned long) operandLitValue(right) == 0){
817 werror(E_DIVIDE_BY_ZERO);
822 retval = operandFromValue (valCastLiteral(type,
823 operandLitValue(left) /
824 operandLitValue(right)));
827 if ((unsigned long) operandLitValue(right) == 0){
828 werror(E_DIVIDE_BY_ZERO);
832 retval = operandFromLit ((unsigned long) operandLitValue(left) %
833 (unsigned long) operandLitValue(right));
836 retval = operandFromLit ((unsigned long) operandLitValue(left) <<
837 (unsigned long) operandLitValue(right));
840 retval = operandFromLit ((unsigned long) operandLitValue(left) >>
841 (unsigned long) operandLitValue(right));
844 retval = operandFromLit (operandLitValue(left) ==
845 operandLitValue(right));
848 retval = operandFromLit (operandLitValue(left) <
849 operandLitValue(right));
852 retval = operandFromLit (operandLitValue(left) <=
853 operandLitValue(right));
856 retval = operandFromLit (operandLitValue(left) !=
857 operandLitValue(right));
860 retval = operandFromLit (operandLitValue(left) >
861 operandLitValue(right));
864 retval = operandFromLit (operandLitValue(left) >=
865 operandLitValue(right));
868 retval = operandFromLit ((unsigned long) operandLitValue(left) &
869 (unsigned long) operandLitValue(right));
872 retval = operandFromLit ((unsigned long) operandLitValue(left) |
873 (unsigned long) operandLitValue(right));
876 retval = operandFromLit ((unsigned long) operandLitValue(left) ^
877 (unsigned long) operandLitValue(right));
880 retval = operandFromLit (operandLitValue(left) &&
881 operandLitValue(right));
884 retval = operandFromLit (operandLitValue(left) ||
885 operandLitValue(right));
889 long i = operandLitValue(left);
891 retval = operandFromLit ((i >> (getSize(operandType(left))*8 - 1)) |
897 long i = operandLitValue(left);
899 retval = operandFromLit ((i << (getSize(operandType(left))*8 - 1)) |
905 retval = operandFromLit(-1 * operandLitValue(left));
909 retval = operandFromLit(~ ((long) operandLitValue(left)));
913 retval = operandFromLit(! operandLitValue(left));
917 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
918 " operandOperation invalid operator ");
926 /*-----------------------------------------------------------------*/
927 /* isOperandEqual - compares two operand & return 1 if they r = */
928 /*-----------------------------------------------------------------*/
929 int isOperandEqual (operand *left, operand *right)
931 /* if the pointers are equal then they are equal */
935 /* if either of them null then false */
936 if ( !left || !right)
939 if (left->type != right->type)
942 if (IS_SYMOP(left) && IS_SYMOP(right))
943 return left->key == right->key ;
945 /* if types are the same */
946 switch (left->type) {
948 return isSymbolEqual(left->operand.symOperand,
949 right->operand.symOperand);
951 return (floatFromVal(left->operand.valOperand) ==
952 floatFromVal(right->operand.valOperand));
954 if (checkType(left->operand.typeOperand,
955 right->operand.typeOperand) == 1)
962 /*-----------------------------------------------------------------*/
963 /* isiCodeEqual - comapres two iCodes are returns true if yes */
964 /*-----------------------------------------------------------------*/
965 int isiCodeEqual (iCode *left, iCode *right)
967 /* if the same pointer */
971 /* if either of them null */
975 /* if operand are the same */
976 if ( left->op == right->op ) {
978 /* compare all the elements depending on type */
979 if (left->op != IFX ) {
980 if (!isOperandEqual(IC_LEFT(left),IC_LEFT(right)))
982 if (!isOperandEqual(IC_RIGHT(left),IC_RIGHT(right)))
986 if (!isOperandEqual(IC_COND(left),IC_COND(right)))
988 if (!isSymbolEqual (IC_TRUE(left),IC_TRUE(right)))
990 if (!isSymbolEqual(IC_FALSE(left),IC_FALSE(right)))
998 /*-----------------------------------------------------------------*/
999 /* newiTempFromOp - create a temp Operand with same attributes */
1000 /*-----------------------------------------------------------------*/
1001 operand *newiTempFromOp (operand *op)
1011 nop = newiTempOperand(operandType(op),TRUE);
1012 nop->isaddr = op->isaddr ;
1013 nop->isvolatile = op->isvolatile ;
1014 nop->isGlobal = op->isGlobal ;
1015 nop->isLiteral= op->isLiteral ;
1016 nop->noSpilLoc= op->noSpilLoc;
1017 nop->usesDefs = op->usesDefs;
1018 nop->isParm = op->isParm;
1019 nop->parmBytes = op->parmBytes;
1023 /*-----------------------------------------------------------------*/
1024 /* operand from operand - creates an operand holder for the type */
1025 /*-----------------------------------------------------------------*/
1026 operand *operandFromOperand (operand *op)
1033 nop->type = op->type;
1034 nop->isaddr = op->isaddr ;
1035 nop->key = op->key ;
1036 nop->isvolatile = op->isvolatile ;
1037 nop->isGlobal = op->isGlobal ;
1038 nop->isLiteral= op->isLiteral ;
1039 nop->noSpilLoc= op->noSpilLoc;
1040 nop->usesDefs = op->usesDefs;
1041 nop->isParm = op->isParm;
1042 nop->parmBytes = op->parmBytes;
1044 switch (nop->type) {
1046 nop->operand.symOperand = op->operand.symOperand ;
1049 nop->operand.valOperand = op->operand.valOperand;
1052 nop->operand.typeOperand = op->operand.typeOperand ;
1059 /*-----------------------------------------------------------------*/
1060 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1061 /*-----------------------------------------------------------------*/
1062 operand *opFromOpWithDU (operand *op, bitVect *defs, bitVect *uses)
1064 operand *nop = operandFromOperand(op);
1066 if (nop->type == SYMBOL) {
1067 OP_SYMBOL(nop)->defs = bitVectCopy(defs);
1068 OP_SYMBOL(nop)->uses = bitVectCopy(uses);
1074 /*-----------------------------------------------------------------*/
1075 /* operandFromSymbol - creates an operand from a symbol */
1076 /*-----------------------------------------------------------------*/
1077 operand *operandFromSymbol (symbol *sym)
1082 /* if the symbol's type is a literal */
1083 /* then it is an enumerator type */
1084 if (IS_LITERAL(sym->etype) && SPEC_ENUM(sym->etype))
1085 return operandFromValue (valFromType(sym->etype));
1088 sym->key = ++operandKey ;
1090 /* if this an implicit variable, means struct/union */
1091 /* member so just return it */
1092 if (sym->implicit || IS_FUNC(sym->type)) {
1095 op->operand.symOperand = sym;
1096 op->key = sym->key ;
1097 op->isvolatile = isOperandVolatile(op,TRUE);
1098 op->isGlobal = isOperandGlobal(op);
1099 op->parmBytes = sym->argStack;
1103 /* under the following conditions create a
1104 register equivalent for a local symbol */
1105 if (sym->level && sym->etype && SPEC_OCLS(sym->etype) &&
1106 (IN_FARSPACE(SPEC_OCLS(sym->etype)) && (!IS_DS390_PORT)) &&
1107 options.stackAuto == 0)
1110 if (!IS_AGGREGATE(sym->type) && /* not an aggregate */
1111 !IS_FUNC(sym->type) && /* not a function */
1112 !sym->_isparm && /* not a parameter */
1113 sym->level && /* is a local variable */
1114 !sym->addrtaken && /* whose address has not been taken */
1115 !sym->reqv && /* does not already have a register euivalence */
1116 !IS_VOLATILE(sym->etype) && /* not declared as volatile */
1117 !IS_STATIC(sym->etype) && /* and not declared static */
1118 !sym->islbl && /* not a label */
1119 ok && /* farspace check */
1120 !IS_BITVAR(sym->etype) /* not a bit variable */
1123 /* we will use it after all optimizations
1124 and before liveRange calculation */
1125 sym->reqv = newiTempOperand(sym->type,0);
1126 sym->reqv->key = sym->key ;
1127 OP_SYMBOL(sym->reqv)->key = sym->key;
1128 OP_SYMBOL(sym->reqv)->isreqv = 1;
1129 OP_SYMBOL(sym->reqv)->islocal = 1;
1130 SPIL_LOC(sym->reqv) = sym;
1133 if (!IS_AGGREGATE(sym->type)) {
1136 op->operand.symOperand = sym;
1139 op->isvolatile = isOperandVolatile(op,TRUE);
1140 op->isGlobal = isOperandGlobal(op);
1141 op->isPtr = IS_PTR(operandType(op));
1142 op->isParm = sym->_isparm ;
1147 /* itemp = &[_symbol] */
1149 ic = newiCode(ADDRESS_OF,newOperand(),NULL);
1150 IC_LEFT(ic)->type = SYMBOL ;
1151 IC_LEFT(ic)->operand.symOperand = sym ;
1152 IC_LEFT(ic)->key = sym->key;
1153 (IC_LEFT(ic))->isvolatile = isOperandVolatile(IC_LEFT(ic),TRUE);
1154 (IC_LEFT(ic))->isGlobal = isOperandGlobal(IC_LEFT(ic));
1155 IC_LEFT(ic)->isPtr = IS_PTR(operandType(IC_LEFT(ic)));
1158 IC_RESULT(ic) = newiTempOperand(sym->type,0);
1159 if (IS_ARRAY(sym->type)) {
1160 IC_RESULT(ic) = geniCodeArray2Ptr (IC_RESULT(ic));
1161 IC_RESULT(ic)->isaddr = 0;
1163 IC_RESULT(ic)->isaddr = (!IS_AGGREGATE(sym->type));
1165 IC_RESULT(ic)->operand.symOperand->args = sym->args;
1169 return IC_RESULT(ic) ;
1172 /*-----------------------------------------------------------------*/
1173 /* operandFromValue - creates an operand from value */
1174 /*-----------------------------------------------------------------*/
1175 operand *operandFromValue (value *val)
1179 /* if this is a symbol then do the symbol thing */
1181 return operandFromSymbol (val->sym);
1183 /* this is not a symbol */
1186 op->operand.valOperand = val ;
1187 op->isLiteral = isOperandLiteral(op);
1191 /*-----------------------------------------------------------------*/
1192 /* operandFromLink - operand from typeChain */
1193 /*-----------------------------------------------------------------*/
1194 operand *operandFromLink (link *type)
1198 /* operand from link */
1204 op->operand.typeOperand = copyLinkChain(type);
1208 /*-----------------------------------------------------------------*/
1209 /* operandFromLit - makes an operand from a literal value */
1210 /*-----------------------------------------------------------------*/
1211 operand *operandFromLit ( float i)
1213 return operandFromValue (valueFromLit (i));
1216 /*-----------------------------------------------------------------*/
1217 /* operandFromAst - creates an operand from an ast */
1218 /*-----------------------------------------------------------------*/
1219 operand *operandFromAst ( ast *tree )
1225 /* depending on type do */
1226 switch (tree->type ) {
1228 return ast2iCode (tree) ;
1232 return operandFromValue(tree->opval.val) ;
1236 return operandFromLink (tree->opval.lnk) ;
1240 /* Just to keep the comiler happy */
1241 return (operand *)0;
1244 /*-----------------------------------------------------------------*/
1245 /* setOperandType - sets the operand's type to the given type */
1246 /*-----------------------------------------------------------------*/
1247 void setOperandType (operand *op, link *type)
1249 /* depending on the type of operand */
1253 op->operand.valOperand->etype =
1254 getSpec( op->operand.valOperand->type =
1255 copyLinkChain (type )) ;
1259 if (op->operand.symOperand->isitmp )
1260 op->operand.symOperand->etype =
1261 getSpec( op->operand.symOperand->type =
1262 copyLinkChain (type )) ;
1264 werror (E_INTERNAL_ERROR,__FILE__,__LINE__,
1265 "attempt to modify type of source");
1269 op->operand.typeOperand = copyLinkChain (type);
1275 /*-----------------------------------------------------------------*/
1276 /* geniCodeValueAtAddress - generate intermeditate code for value */
1278 /*-----------------------------------------------------------------*/
1279 operand *geniCodeRValue (operand *op, bool force)
1282 link *type = operandType(op);
1283 link *etype= getSpec(type);
1285 /* if this is an array & already */
1286 /* an address then return this */
1287 if (IS_AGGREGATE(type) ||
1288 (IS_PTR(type) && !force && !op->isaddr))
1289 return operandFromOperand(op);
1291 /* if this is not an address then must be */
1292 /* rvalue already so return this one */
1296 /* if this is not a temp symbol then */
1297 if (!IS_ITEMP(op) &&
1299 !IN_FARSPACE(SPEC_OCLS(etype))) {
1300 op = operandFromOperand(op);
1305 if (IS_SPEC(type) &&
1306 IS_TRUE_SYMOP(op) &&
1307 !IN_FARSPACE(SPEC_OCLS(etype))) {
1308 op = operandFromOperand(op);
1313 ic = newiCode(GET_VALUE_AT_ADDRESS,op,NULL);
1314 if (IS_PTR(type) && op->isaddr && force)
1317 type = copyLinkChain(type);
1319 IC_RESULT(ic) = newiTempOperand (type,1);
1320 IC_RESULT(ic)->isaddr = 0;
1322 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1324 /* if the right is a symbol */
1325 if (op->type == SYMBOL)
1326 IC_RESULT(ic)->operand.symOperand->args =
1327 op->operand.symOperand->args ;
1330 return IC_RESULT(ic) ;
1333 /*-----------------------------------------------------------------*/
1334 /* geniCodeCast - changes the value from one type to another */
1335 /*-----------------------------------------------------------------*/
1336 operand *geniCodeCast (link *type, operand *op, bool implicit)
1340 link *opetype = getSpec(optype = operandType(op));
1343 /* one of them has size zero then error */
1344 if (IS_VOID(optype)) {
1345 werror(E_CAST_ZERO);
1349 /* if the operand is already the desired type then do nothing */
1350 if ( checkType (type,optype) == 1)
1353 /* if this is a literal then just change the type & return */
1354 if (IS_LITERAL(opetype) && op->type == VALUE && !IS_PTR(type) && !IS_PTR(optype))
1355 return operandFromValue(valCastLiteral(type,
1356 operandLitValue(op)));
1358 /* if casting to some pointer type &&
1359 the destination is not a generic pointer
1360 then give a warning : (only for implicit casts)*/
1361 if (IS_PTR(optype) && implicit &&
1362 (DCL_TYPE(optype) != DCL_TYPE(type)) &&
1364 werror(E_INCOMPAT_CAST);
1365 werror(E_CONTINUE,"from type '");
1366 printTypeChain(optype,stderr);fprintf(stderr,"' to type '");
1367 printTypeChain(type,stderr);fprintf(stderr,"'\n");
1370 /* if they are the same size create an assignment */
1371 if (getSize(type) == getSize(optype) &&
1372 !IS_BITFIELD(type) &&
1374 !IS_FLOAT(optype) &&
1375 ((IS_SPEC(type) && IS_SPEC(optype)) ||
1376 (!IS_SPEC(type) && !IS_SPEC(optype)))) {
1378 ic = newiCode('=',NULL,op);
1379 IC_RESULT(ic) = newiTempOperand(type,0);
1380 SPIL_LOC(IC_RESULT(ic)) =
1381 (IS_TRUE_SYMOP(op) ? OP_SYMBOL(op) : NULL);
1382 IC_RESULT(ic)->isaddr = 0;
1384 ic = newiCode(CAST,operandFromLink(type),
1385 geniCodeRValue(op,FALSE));
1387 IC_RESULT(ic)= newiTempOperand(type,0);
1390 /* preserve the storage class & output class */
1391 /* of the original variable */
1392 restype = getSpec(operandType(IC_RESULT(ic)));
1393 SPEC_SCLS(restype) = SPEC_SCLS(opetype);
1394 SPEC_OCLS(restype) = SPEC_OCLS(opetype);
1397 return IC_RESULT(ic) ;
1400 /*-----------------------------------------------------------------*/
1401 /* geniCodeLabel - will create a Label */
1402 /*-----------------------------------------------------------------*/
1403 void geniCodeLabel (symbol *label)
1407 ic = newiCodeLabelGoto(LABEL,label);
1411 /*-----------------------------------------------------------------*/
1412 /* geniCodeGoto - will create a Goto */
1413 /*-----------------------------------------------------------------*/
1414 void geniCodeGoto (symbol *label)
1418 ic = newiCodeLabelGoto(GOTO,label);
1422 /*-----------------------------------------------------------------*/
1423 /* geniCodeMultiply - gen intermediate code for multiplication */
1424 /*-----------------------------------------------------------------*/
1425 operand *geniCodeMultiply (operand *left, operand *right)
1432 /* if they are both literal then we know the result */
1433 if (IS_LITERAL(letype) && IS_LITERAL(retype))
1434 return operandFromValue (valMult(left->operand.valOperand,
1435 right->operand.valOperand));
1437 resType = computeType (ltype,rtype) ;
1438 left = geniCodeCast(resType,left,TRUE);
1439 right= geniCodeCast(resType,right,TRUE);
1441 /* if the right is a literal & power of 2 */
1442 /* then make it a left shift */
1443 if (IS_LITERAL(retype) && !IS_FLOAT(letype) &&
1444 (p2 = powof2 ((unsigned long)floatFromVal(right->operand.valOperand))))
1445 ic = newiCode(LEFT_OP, left,operandFromLit(p2)); /* left shift */
1447 ic = newiCode('*',left,right); /* normal multiplication */
1448 /* if the size left or right > 1 then support routine */
1449 if (getSize(ltype) > 1 || getSize(rtype) > 1)
1453 IC_RESULT(ic) = newiTempOperand(resType,1);
1456 return IC_RESULT(ic) ;
1459 /*-----------------------------------------------------------------*/
1460 /* geniCodeDivision - gen intermediate code for division */
1461 /*-----------------------------------------------------------------*/
1462 operand *geniCodeDivision (operand *left, operand *right)
1467 link *rtype = operandType(right);
1468 link *retype= getSpec(rtype);
1469 link *ltype = operandType(left);
1470 link *letype= getSpec(ltype);
1472 resType = computeType (ltype,rtype) ;
1473 left = geniCodeCast(resType,left,TRUE);
1474 right= geniCodeCast(resType,right,TRUE);
1476 /* if the right is a literal & power of 2 */
1477 /* then make it a right shift */
1478 if (IS_LITERAL(retype) &&
1479 !IS_FLOAT(letype) &&
1480 (p2 = powof2 ((unsigned long)
1481 floatFromVal(right->operand.valOperand))))
1482 ic = newiCode(RIGHT_OP, left,operandFromLit(p2)); /* right shift */
1484 ic = newiCode('/',left,right); /* normal division */
1485 /* if the size left or right > 1 then support routine */
1486 if (getSize(ltype) > 1 || getSize(rtype) > 1)
1489 IC_RESULT(ic) = newiTempOperand(resType,0);
1492 return IC_RESULT(ic) ;
1494 /*-----------------------------------------------------------------*/
1495 /* geniCodeModulus - gen intermediate code for modulus */
1496 /*-----------------------------------------------------------------*/
1497 operand *geniCodeModulus (operand *left, operand *right)
1503 /* if they are both literal then we know the result */
1504 if (IS_LITERAL(letype) && IS_LITERAL(retype))
1505 return operandFromValue (valMod(left->operand.valOperand,
1506 right->operand.valOperand));
1508 resType = computeType (ltype,rtype) ;
1509 left = geniCodeCast(resType,left,TRUE);
1510 right= geniCodeCast(resType,right,TRUE);
1512 /* now they are the same size */
1513 ic = newiCode('%',left,right);
1515 /* if the size left or right > 1 then support routine */
1516 if (getSize(ltype) > 1 || getSize(rtype) > 1)
1518 IC_RESULT(ic) = newiTempOperand(resType,0);
1521 return IC_RESULT(ic) ;
1524 /*-----------------------------------------------------------------*/
1525 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1526 /*-----------------------------------------------------------------*/
1527 operand *geniCodePtrPtrSubtract (operand *left, operand *right)
1533 /* if they are both literals then */
1534 if (IS_LITERAL(letype) && IS_LITERAL(retype)) {
1535 result = operandFromValue (valMinus(left->operand.valOperand,
1536 right->operand.valOperand));
1540 ic = newiCode('-',left,right);
1542 IC_RESULT(ic) = result = newiTempOperand(newIntLink(),1);
1546 return geniCodeDivision (result,
1547 operandFromLit(getSize(ltype->next)));
1550 /*-----------------------------------------------------------------*/
1551 /* geniCodeSubtract - generates code for subtraction */
1552 /*-----------------------------------------------------------------*/
1553 operand *geniCodeSubtract (operand *left, operand *right)
1560 /* if they both pointers then */
1561 if ((IS_PTR(ltype) || IS_ARRAY(ltype)) &&
1562 (IS_PTR(rtype) || IS_ARRAY(rtype)))
1563 return geniCodePtrPtrSubtract (left,right);
1565 /* if they are both literal then we know the result */
1566 if (IS_LITERAL(letype) && IS_LITERAL(retype)
1567 && left->isLiteral && right->isLiteral)
1568 return operandFromValue (valMinus(left->operand.valOperand,
1569 right->operand.valOperand));
1571 /* if left is an array or pointer */
1572 if ( IS_PTR(ltype) || IS_ARRAY(ltype) ) {
1573 isarray = left->isaddr ;
1574 right = geniCodeMultiply (right,
1575 operandFromLit(getSize(ltype->next)));
1576 resType = copyLinkChain(IS_ARRAY(ltype) ? ltype->next : ltype);
1578 else { /* make them the same size */
1579 resType = computeType (ltype,rtype) ;
1580 left = geniCodeCast(resType,left,TRUE);
1581 right= geniCodeCast(resType,right,TRUE);
1584 ic = newiCode('-',left,right);
1586 IC_RESULT(ic)= newiTempOperand(resType,1);
1587 IC_RESULT(ic)->isaddr = (isarray ? 1 : 0);
1589 /* if left or right is a float */
1590 if (IS_FLOAT(ltype) || IS_FLOAT(rtype))
1594 return IC_RESULT(ic) ;
1597 /*-----------------------------------------------------------------*/
1598 /* geniCodeAdd - generates iCode for addition */
1599 /*-----------------------------------------------------------------*/
1600 operand *geniCodeAdd (operand *left, operand *right )
1608 /* if left is an array then array access */
1609 if (IS_ARRAY(ltype))
1610 return geniCodeArray (left,right);
1612 /* if the right side is LITERAL zero */
1613 /* return the left side */
1614 if (IS_LITERAL(retype) && right->isLiteral && !floatFromVal(valFromType(retype)))
1617 /* if left is literal zero return right */
1618 if (IS_LITERAL(letype) && left->isLiteral && !floatFromVal(valFromType(letype)))
1621 /* if left is an array or pointer then size */
1622 if (IS_PTR(ltype)) {
1624 isarray = left->isaddr;
1626 operandFromLit(getSize(ltype->next));
1627 right = geniCodeMultiply (right ,size);
1628 if (getSize(ltype) > 1)
1629 right = geniCodeCast(INTTYPE,right,TRUE);
1630 resType = copyLinkChain(ltype);
1632 else { /* make them the same size */
1633 resType = computeType (ltype,rtype) ;
1634 left = geniCodeCast(resType,left,TRUE);
1635 right= geniCodeCast(resType,right,TRUE);
1638 /* if they are both literals then we know */
1639 if (IS_LITERAL(letype) && IS_LITERAL(retype)
1640 && left->isLiteral && right->isLiteral)
1641 return operandFromValue (valPlus(valFromType(letype),
1642 valFromType(retype)));
1644 ic = newiCode('+',left,right);
1646 IC_RESULT(ic) = newiTempOperand(resType,1);
1647 IC_RESULT(ic)->isaddr = ( isarray ? 1 : 0);
1649 /* if left or right is a float then support
1651 if (IS_FLOAT(ltype) || IS_FLOAT(rtype))
1656 return IC_RESULT(ic) ;
1660 /*-----------------------------------------------------------------*/
1661 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1662 /*-----------------------------------------------------------------*/
1663 link *aggrToPtr ( link *type, bool force)
1669 if (IS_PTR(type) && !force)
1672 etype = getSpec(type);
1676 /* if the output class is generic */
1677 if ((DCL_TYPE(ptype) = PTR_TYPE(SPEC_OCLS(etype))) == CPOINTER)
1678 DCL_PTR_CONST(ptype) = port->mem.code_ro;
1680 /* if the variable was declared a constant */
1681 /* then the pointer points to a constant */
1682 if (IS_CONSTANT(etype) )
1683 DCL_PTR_CONST(ptype) = 1;
1685 /* the variable was volatile then pointer to volatile */
1686 if (IS_VOLATILE(etype))
1687 DCL_PTR_VOLATILE(ptype) = 1;
1691 /*-----------------------------------------------------------------*/
1692 /* geniCodeArray2Ptr - array to pointer */
1693 /*-----------------------------------------------------------------*/
1694 operand *geniCodeArray2Ptr (operand *op)
1696 link *optype = operandType(op);
1697 link *opetype = getSpec(optype);
1699 /* set the pointer depending on the storage class */
1700 if ((DCL_TYPE(optype) = PTR_TYPE(SPEC_OCLS(opetype))) == CPOINTER)
1701 DCL_PTR_CONST(optype) = port->mem.code_ro;
1704 /* if the variable was declared a constant */
1705 /* then the pointer points to a constant */
1706 if (IS_CONSTANT(opetype) )
1707 DCL_PTR_CONST(optype) = 1;
1709 /* the variable was volatile then pointer to volatile */
1710 if (IS_VOLATILE(opetype))
1711 DCL_PTR_VOLATILE(optype) = 1;
1716 /*-----------------------------------------------------------------*/
1717 /* geniCodeArray - array access */
1718 /*-----------------------------------------------------------------*/
1719 operand *geniCodeArray (operand *left,operand *right)
1722 link *ltype = operandType(left);
1724 if (IS_PTR(ltype)) {
1725 if (IS_PTR(ltype->next) && left->isaddr)
1726 left = geniCodeRValue(left,FALSE);
1727 return geniCodeDerefPtr(geniCodeAdd(left,right));
1731 right = geniCodeMultiply(right,
1732 operandFromLit(getSize(ltype->next)));
1734 /* we can check for limits here */
1735 if (isOperandLiteral(right) &&
1738 (operandLitValue(right)/getSize(ltype->next)) >= DCL_ELEM(ltype)) {
1739 werror(E_ARRAY_BOUND);
1740 right = operandFromLit(0);
1743 ic = newiCode('+',left,right);
1745 IC_RESULT(ic) = newiTempOperand(((IS_PTR(ltype) &&
1746 !IS_AGGREGATE(ltype->next) &&
1747 !IS_PTR(ltype->next))
1748 ? ltype : ltype->next),0);
1750 IC_RESULT(ic)->isaddr = (!IS_AGGREGATE(ltype->next));
1752 return IC_RESULT(ic) ;
1755 /*-----------------------------------------------------------------*/
1756 /* geniCodeStruct - generates intermediate code for structres */
1757 /*-----------------------------------------------------------------*/
1758 operand *geniCodeStruct (operand *left, operand *right, bool islval)
1761 link *type = operandType(left);
1762 link *etype = getSpec(type);
1764 symbol *element = getStructElement(SPEC_STRUCT(etype),
1765 right->operand.symOperand);
1767 /* add the offset */
1768 ic = newiCode('+',left,operandFromLit(element->offset));
1770 IC_RESULT(ic) = newiTempOperand(element->type,0);
1772 /* preserve the storage & output class of the struct */
1773 /* as well as the volatile attribute */
1774 retype = getSpec(operandType(IC_RESULT(ic)));
1775 SPEC_SCLS(retype) = SPEC_SCLS(etype);
1776 SPEC_OCLS(retype) = SPEC_OCLS(etype);
1777 SPEC_VOLATILE(retype) |= SPEC_VOLATILE(etype);
1779 if (IS_PTR(element->type))
1780 setOperandType(IC_RESULT(ic),aggrToPtr(operandType(IC_RESULT(ic)),TRUE));
1782 IC_RESULT(ic)->isaddr = (!IS_AGGREGATE(element->type));
1786 return (islval ? IC_RESULT(ic) : geniCodeRValue(IC_RESULT(ic),TRUE));
1789 /*-----------------------------------------------------------------*/
1790 /* geniCodePostInc - generate int code for Post increment */
1791 /*-----------------------------------------------------------------*/
1792 operand *geniCodePostInc (operand *op)
1796 link *optype = operandType(op);
1798 operand *rv = (IS_ITEMP(op) ?
1799 geniCodeRValue(op,(IS_PTR(optype) ? TRUE : FALSE)) :
1801 link *rvtype = operandType(rv);
1804 /* if this is not an address we have trouble */
1805 if ( ! op->isaddr ) {
1806 werror (E_LVALUE_REQUIRED,"++");
1810 rOp = newiTempOperand(rvtype,0);
1816 geniCodeAssign(rOp,rv,0);
1818 size = (IS_PTR(rvtype) ? getSize(rvtype->next) : 1);
1819 ic = newiCode('+',rv,operandFromLit(size));
1820 IC_RESULT(ic) = result =newiTempOperand(rvtype,0);
1823 geniCodeAssign(op,result,0);
1829 /*-----------------------------------------------------------------*/
1830 /* geniCodePreInc - generate code for preIncrement */
1831 /*-----------------------------------------------------------------*/
1832 operand *geniCodePreInc (operand *op)
1835 link *optype = operandType(op);
1836 operand *rop = (IS_ITEMP(op) ?
1837 geniCodeRValue (op,(IS_PTR(optype) ? TRUE : FALSE)) :
1839 link *roptype = operandType(rop);
1843 if ( ! op->isaddr ) {
1844 werror(E_LVALUE_REQUIRED,"++");
1849 size = (IS_PTR(roptype) ? getSize(roptype->next) : 1);
1850 ic = newiCode('+',rop,operandFromLit(size));
1851 IC_RESULT(ic) = result = newiTempOperand(roptype,0) ;
1855 return geniCodeAssign(op,result,0) ;
1858 /*-----------------------------------------------------------------*/
1859 /* geniCodePostDec - generates code for Post decrement */
1860 /*-----------------------------------------------------------------*/
1861 operand *geniCodePostDec (operand *op)
1865 link *optype = operandType(op);
1867 operand *rv = (IS_ITEMP(op) ?
1868 geniCodeRValue(op,(IS_PTR(optype) ? TRUE : FALSE)) :
1870 link *rvtype = operandType(rv);
1873 /* if this is not an address we have trouble */
1874 if ( ! op->isaddr ) {
1875 werror (E_LVALUE_REQUIRED,"++");
1879 rOp = newiTempOperand(rvtype,0);
1885 geniCodeAssign(rOp,rv,0);
1887 size = (IS_PTR(rvtype) ? getSize(rvtype->next) : 1);
1888 ic = newiCode('-',rv,operandFromLit(size));
1889 IC_RESULT(ic) = result =newiTempOperand(rvtype,0);
1892 geniCodeAssign(op,result,0);
1898 /*-----------------------------------------------------------------*/
1899 /* geniCodePreDec - generate code for pre decrement */
1900 /*-----------------------------------------------------------------*/
1901 operand *geniCodePreDec (operand *op)
1904 link *optype = operandType(op);
1905 operand *rop = (IS_ITEMP(op) ?
1906 geniCodeRValue (op,(IS_PTR(optype) ? TRUE : FALSE)) :
1908 link *roptype = operandType(rop);
1912 if ( ! op->isaddr ) {
1913 werror(E_LVALUE_REQUIRED,"++");
1918 size = (IS_PTR(roptype) ? getSize(roptype->next) : 1);
1919 ic = newiCode('-',rop,operandFromLit(size));
1920 IC_RESULT(ic) = result = newiTempOperand(roptype,0) ;
1924 return geniCodeAssign(op,result,0) ;
1928 /*-----------------------------------------------------------------*/
1929 /* geniCodeBitwise - gen int code for bitWise operators */
1930 /*-----------------------------------------------------------------*/
1931 operand *geniCodeBitwise (operand *left, operand *right,
1932 int oper, link *resType)
1936 left = geniCodeCast(resType,left,TRUE);
1937 right= geniCodeCast(resType,right,TRUE);
1939 ic = newiCode(oper,left,right);
1940 IC_RESULT(ic) = newiTempOperand(resType,0);
1943 return IC_RESULT(ic) ;
1946 /*-----------------------------------------------------------------*/
1947 /* geniCodeAddressOf - gens icode for '&' address of operator */
1948 /*-----------------------------------------------------------------*/
1949 operand *geniCodeAddressOf (operand *op)
1953 link *optype = operandType(op);
1954 link *opetype= getSpec(optype);
1956 /* lvalue check already done in decorateType */
1957 /* this must be a lvalue */
1958 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
1959 /* werror (E_LVALUE_REQUIRED,"&"); */
1964 p->class = DECLARATOR ;
1966 /* set the pointer depending on the storage class */
1967 if ((DCL_TYPE(p) = PTR_TYPE(SPEC_OCLS(opetype))) == CPOINTER)
1968 DCL_PTR_CONST(p) = port->mem.code_ro;
1970 /* make sure we preserve the const & volatile */
1971 if (IS_CONSTANT(opetype))
1972 DCL_PTR_CONST(p) = 1;
1974 if (IS_VOLATILE(opetype))
1975 DCL_PTR_VOLATILE(p) = 1;
1977 p->next = copyLinkChain(optype);
1979 /* if already a temp */
1981 setOperandType (op,p);
1986 /* other wise make this of the type coming in */
1987 ic = newiCode(ADDRESS_OF,op,NULL);
1988 IC_RESULT(ic) = newiTempOperand(p,1);
1989 IC_RESULT(ic)->isaddr = 0;
1991 return IC_RESULT(ic);
1993 /*-----------------------------------------------------------------*/
1994 /* setOClass - sets the output class depending on the pointer type */
1995 /*-----------------------------------------------------------------*/
1996 void setOClass (link *ptr, link *spec)
1998 switch (DCL_TYPE(ptr)) {
2000 SPEC_OCLS(spec) = data ;
2004 SPEC_OCLS(spec) = generic;
2008 SPEC_OCLS(spec) = xdata ;
2012 SPEC_OCLS(spec) = code ;
2016 SPEC_OCLS(spec) = idata;
2020 SPEC_OCLS(spec) = xstack;
2024 SPEC_OCLS(spec) = eeprom;
2033 /*-----------------------------------------------------------------*/
2034 /* geniCodeDerefPtr - dereference pointer with '*' */
2035 /*-----------------------------------------------------------------*/
2036 operand *geniCodeDerefPtr (operand *op)
2038 link *rtype , *retype ;
2039 link *optype = operandType(op);
2041 /* if this is a pointer then generate the rvalue */
2042 if (IS_PTR(optype)) {
2043 if (IS_TRUE_SYMOP(op)) {
2045 op = geniCodeRValue(op,TRUE);
2048 op = geniCodeRValue(op,TRUE);
2051 /* now get rid of the pointer part */
2052 if (lvaluereq && IS_ITEMP(op) )
2054 retype = getSpec(rtype = copyLinkChain(optype)) ;
2058 retype = getSpec(rtype = copyLinkChain(optype->next)) ;
2061 /* if this is a pointer then outputclass needs 2b updated */
2063 setOClass(optype,retype);
2065 op->isGptr = IS_GENPTR(optype);
2067 /* if the pointer was declared as a constant */
2068 /* then we cannot allow assignment to the derefed */
2069 if (IS_PTR_CONST(optype))
2070 SPEC_CONST(retype) = 1;
2072 op->isaddr = (IS_PTR(rtype) ||
2079 op = geniCodeRValue(op,TRUE);
2081 setOperandType(op,rtype);
2086 /*-----------------------------------------------------------------*/
2087 /* geniCodeUnaryMinus - does a unary minus of the operand */
2088 /*-----------------------------------------------------------------*/
2089 operand *geniCodeUnaryMinus (operand *op)
2092 link *optype = operandType(op);
2094 if (IS_LITERAL(optype))
2095 return operandFromLit(- floatFromVal(op->operand.valOperand));
2097 ic = newiCode(UNARYMINUS,op,NULL);
2098 IC_RESULT(ic) = newiTempOperand(optype,0);
2100 return IC_RESULT(ic);
2103 /*-----------------------------------------------------------------*/
2104 /* geniCodeLeftShift - gen i code for left shift */
2105 /*-----------------------------------------------------------------*/
2106 operand *geniCodeLeftShift (operand *left, operand *right)
2109 link *ltype = operandType(left);
2111 ic = newiCode(LEFT_OP,left,right);
2112 IC_RESULT(ic) = newiTempOperand(ltype,0);
2114 return IC_RESULT(ic) ;
2117 /*-----------------------------------------------------------------*/
2118 /* geniCodeRightShift - gen i code for right shift */
2119 /*-----------------------------------------------------------------*/
2120 operand *geniCodeRightShift (operand *left, operand *right)
2123 link *ltype = operandType(left);
2125 ic = newiCode(RIGHT_OP,left,right);
2126 IC_RESULT(ic) = newiTempOperand(ltype,0);
2128 return IC_RESULT(ic) ;
2132 #define LONG_LONG __int64
2134 #define LONG_LONG long long
2137 /*-----------------------------------------------------------------*/
2138 /* geniCodeLogic- logic code */
2139 /*-----------------------------------------------------------------*/
2140 operand *geniCodeLogic (operand *left, operand *right, int op )
2144 link *rtype = operandType(right);
2145 link *ltype = operandType(left);
2147 /* left is integral type and right is literal then
2148 check if the literal value is within bounds */
2149 if (IS_INTEGRAL(ltype) && IS_LITERAL(rtype)) {
2150 int nbits = bitsForType(ltype);
2151 long v = operandLitValue(right);
2153 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2154 werror(W_CONST_RANGE," compare operation ");
2157 ctype = computeType(ltype,rtype);
2158 left = geniCodeCast(ctype,left,TRUE);
2159 right= geniCodeCast(ctype,right,TRUE);
2161 ic = newiCode(op,left,right);
2162 IC_RESULT(ic) = newiTempOperand (newCharLink(),1);
2164 /* if comparing anything greater than one byte
2165 and not a '==' || '!=' || '&&' || '||' (these
2167 if (getSize(ctype) > 1 &&
2175 return IC_RESULT(ic);
2178 /*-----------------------------------------------------------------*/
2179 /* geniCodeUnary - for a a generic unary operation */
2180 /*-----------------------------------------------------------------*/
2181 operand *geniCodeUnary (operand *op, int oper )
2183 iCode *ic = newiCode (oper,op,NULL);
2185 IC_RESULT(ic)= newiTempOperand(operandType(op),0);
2187 return IC_RESULT(ic) ;
2190 /*-----------------------------------------------------------------*/
2191 /* geniCodeConditional - geniCode for '?' ':' operation */
2192 /*-----------------------------------------------------------------*/
2193 operand *geniCodeConditional (ast *tree)
2196 symbol *falseLabel = newiTempLabel(NULL);
2197 symbol *exitLabel = newiTempLabel(NULL);
2198 operand *cond = ast2iCode(tree->left);
2199 operand *true, *false , *result;
2201 ic = newiCodeCondition(geniCodeRValue(cond,FALSE),
2205 true = ast2iCode(tree->right->left);
2207 /* move the value to a new Operand */
2208 result = newiTempOperand(operandType(true),0);
2209 geniCodeAssign(result,geniCodeRValue(true,FALSE),0);
2211 /* generate an unconditional goto */
2212 geniCodeGoto(exitLabel);
2214 /* now for the right side */
2215 geniCodeLabel(falseLabel);
2217 false = ast2iCode(tree->right->right);
2218 geniCodeAssign(result,geniCodeRValue(false,FALSE),0);
2220 /* create the exit label */
2221 geniCodeLabel(exitLabel);
2226 /*-----------------------------------------------------------------*/
2227 /* geniCodeAssign - generate code for assignment */
2228 /*-----------------------------------------------------------------*/
2229 operand *geniCodeAssign (operand *left, operand *right, int nosupdate)
2232 link *ltype = operandType(left);
2233 link *rtype = operandType(right);
2235 if (!left->isaddr && !IS_ITEMP(left)) {
2236 werror(E_LVALUE_REQUIRED,"assignment");
2240 /* left is integral type and right is literal then
2241 check if the literal value is within bounds */
2242 if (IS_INTEGRAL(ltype) && right->type == VALUE && IS_LITERAL(rtype)) {
2243 int nbits = bitsForType(ltype);
2244 long v = operandLitValue(right);
2246 if (v > ((LONG_LONG)1 << nbits) && v > 0)
2247 werror(W_CONST_RANGE," = operation");
2250 /* if the left & right type don't exactly match */
2251 /* if pointer set then make sure the check is
2252 done with the type & not the pointer */
2253 /* then cast rights type to left */
2255 /* first check the type for pointer assignement */
2256 if (left->isaddr && IS_PTR(ltype) && IS_ITEMP(left) &&
2257 checkType(ltype,rtype)<0) {
2258 if (checkType(ltype->next,rtype) < 0)
2259 right = geniCodeCast(ltype->next,right,TRUE);
2261 if (checkType(ltype,rtype) < 0 )
2262 right = geniCodeCast(ltype,right,TRUE);
2264 /* if left is a true symbol & ! volatile
2265 create an assignment to temporary for
2266 the right & then assign this temporary
2267 to the symbol this is SSA . isn't it simple
2268 and folks have published mountains of paper on it */
2269 if (IS_TRUE_SYMOP(left) &&
2270 !isOperandVolatile(left,FALSE) &&
2271 isOperandGlobal(left)) {
2274 if (IS_TRUE_SYMOP(right))
2275 sym = OP_SYMBOL(right);
2276 ic = newiCode('=',NULL,right);
2277 IC_RESULT(ic) = right = newiTempOperand(ltype,0);
2278 SPIL_LOC(right) = sym ;
2282 ic = newiCode('=',NULL,right);
2283 IC_RESULT(ic) = left;
2286 /* if left isgptr flag is set then support
2287 routine will be required */
2291 ic->nosupdate = nosupdate;
2295 /*-----------------------------------------------------------------*/
2296 /* geniCodeSEParms - generate code for side effecting fcalls */
2297 /*-----------------------------------------------------------------*/
2298 static void geniCodeSEParms (ast *parms)
2303 if (parms->type == EX_OP && parms->opval.op == PARAM) {
2304 geniCodeSEParms (parms->left) ;
2305 geniCodeSEParms (parms->right);
2309 /* hack don't like this but too lazy to think of
2311 if (IS_ADDRESS_OF_OP(parms))
2312 parms->left->lvalue = 1;
2314 if (IS_CAST_OP(parms) &&
2315 IS_PTR(parms->ftype) &&
2316 IS_ADDRESS_OF_OP(parms->right))
2317 parms->right->left->lvalue = 1;
2319 parms->opval.oprnd =
2320 geniCodeRValue(ast2iCode (parms),FALSE);
2322 parms->type = EX_OPERAND ;
2325 /*-----------------------------------------------------------------*/
2326 /* geniCodeParms - generates parameters */
2327 /*-----------------------------------------------------------------*/
2328 static void geniCodeParms ( ast *parms , int *stack, link *fetype, symbol *func)
2336 /* if this is a param node then do the left & right */
2337 if (parms->type == EX_OP && parms->opval.op == PARAM) {
2338 geniCodeParms (parms->left, stack,fetype,func) ;
2339 geniCodeParms (parms->right, stack,fetype,func);
2343 /* get the parameter value */
2344 if (parms->type == EX_OPERAND)
2345 pval = parms->opval.oprnd ;
2347 /* maybe this else should go away ?? */
2348 /* hack don't like this but too lazy to think of
2350 if (IS_ADDRESS_OF_OP(parms))
2351 parms->left->lvalue = 1;
2353 if (IS_CAST_OP(parms) &&
2354 IS_PTR(parms->ftype) &&
2355 IS_ADDRESS_OF_OP(parms->right))
2356 parms->right->left->lvalue = 1;
2358 pval = geniCodeRValue(ast2iCode (parms),FALSE);
2361 /* if register parm then make it a send */
2362 if (((parms->argSym && IS_REGPARM(parms->argSym->etype)) ||
2363 IS_REGPARM(parms->etype)) && !func->hasVargs ) {
2364 ic = newiCode(SEND,pval,NULL);
2367 /* now decide whether to push or assign */
2368 if (!(options.stackAuto || IS_RENT(fetype))) {
2371 operand *top = operandFromSymbol(parms->argSym);
2372 geniCodeAssign(top,pval,1);
2375 link *p = operandType(pval);
2377 ic = newiCode(IPUSH,pval,NULL);
2379 /* update the stack adjustment */
2380 *stack += getSize(IS_AGGREGATE(p)? aggrToPtr(p,FALSE):p);
2387 /*-----------------------------------------------------------------*/
2388 /* geniCodeCall - generates temp code for calling */
2389 /*-----------------------------------------------------------------*/
2390 operand *geniCodeCall (operand *left, ast *parms)
2397 /* take care of parameters with side-effecting
2398 function calls in them, this is required to take care
2399 of overlaying function parameters */
2400 geniCodeSEParms ( parms );
2402 /* first the parameters */
2403 geniCodeParms ( parms , &stack , getSpec(operandType(left)), OP_SYMBOL(left));
2405 /* now call : if symbol then pcall */
2407 ic = newiCode(PCALL,left,NULL);
2409 ic = newiCode(CALL,left,NULL);
2411 IC_ARGS(ic) = left->operand.symOperand->args ;
2412 type = copyLinkChain(operandType(left)->next);
2413 etype = getSpec(type);
2414 SPEC_EXTR(etype) = 0;
2415 IC_RESULT(ic) = result = newiTempOperand(type,1);
2419 /* stack adjustment after call */
2420 left->parmBytes = stack;
2425 /*-----------------------------------------------------------------*/
2426 /* geniCodeReceive - generate intermediate code for "receive" */
2427 /*-----------------------------------------------------------------*/
2428 static void geniCodeReceive (value *args)
2430 /* for all arguments that are passed in registers */
2433 if (IS_REGPARM(args->etype)) {
2434 operand *opr = operandFromValue(args);
2436 symbol *sym = OP_SYMBOL(opr);
2439 /* we will use it after all optimizations
2440 and before liveRange calculation */
2441 if (!sym->addrtaken && !IS_VOLATILE(sym->etype)) {
2443 if (IN_FARSPACE(SPEC_OCLS(sym->etype)) &&
2444 options.stackAuto == 0 &&
2447 opl = newiTempOperand(args->type,0);
2449 sym->reqv->key = sym->key ;
2450 OP_SYMBOL(sym->reqv)->key = sym->key;
2451 OP_SYMBOL(sym->reqv)->isreqv = 1;
2452 OP_SYMBOL(sym->reqv)->islocal= 0;
2453 SPIL_LOC(sym->reqv) = sym;
2457 ic = newiCode(RECEIVE,NULL,NULL);
2458 currFunc->recvSize = getSize(sym->etype);
2459 IC_RESULT(ic) = opr;
2467 /*-----------------------------------------------------------------*/
2468 /* geniCodeFunctionBody - create the function body */
2469 /*-----------------------------------------------------------------*/
2470 void geniCodeFunctionBody (ast *tree)
2477 /* reset the auto generation */
2483 func = ast2iCode(tree->left);
2484 fetype = getSpec(operandType(func));
2486 savelineno = lineno;
2487 lineno = OP_SYMBOL(func)->lineDef;
2488 /* create an entry label */
2489 geniCodeLabel(entryLabel);
2490 lineno = savelineno;
2492 /* create a proc icode */
2493 ic = newiCode(FUNCTION,func,NULL);
2494 /* if the function has parmas then */
2495 /* save the parameters information */
2496 ic->argLabel.args = tree->values.args ;
2497 ic->lineno = OP_SYMBOL(func)->lineDef;
2501 /* for all parameters that are passed
2502 on registers add a "receive" */
2503 geniCodeReceive( tree->values.args );
2505 /* generate code for the body */
2506 ast2iCode(tree->right);
2508 /* create a label for return */
2509 geniCodeLabel(returnLabel);
2511 /* now generate the end proc */
2512 ic = newiCode(ENDFUNCTION,func,NULL);
2517 /*-----------------------------------------------------------------*/
2518 /* geniCodeReturn - gen icode for 'return' statement */
2519 /*-----------------------------------------------------------------*/
2520 void geniCodeReturn (operand *op)
2524 /* if the operand is present force an rvalue */
2526 op = geniCodeRValue(op,FALSE);
2528 ic = newiCode(RETURN,op,NULL);
2532 /*-----------------------------------------------------------------*/
2533 /* geniCodeIfx - generates code for extended if statement */
2534 /*-----------------------------------------------------------------*/
2535 void geniCodeIfx (ast *tree)
2538 operand *condition = ast2iCode(tree->left);
2541 /* if condition is null then exit */
2545 condition = geniCodeRValue(condition,FALSE);
2547 cetype = getSpec(operandType(condition));
2548 /* if the condition is a literal */
2549 if (IS_LITERAL(cetype)) {
2550 if (floatFromVal(condition->operand.valOperand)) {
2551 if (tree->trueLabel)
2552 geniCodeGoto(tree->trueLabel);
2557 if (tree->falseLabel)
2558 geniCodeGoto (tree->falseLabel);
2565 if ( tree->trueLabel ) {
2566 ic = newiCodeCondition(condition,
2571 if ( tree->falseLabel)
2572 geniCodeGoto(tree->falseLabel);
2575 ic = newiCodeCondition (condition,
2582 ast2iCode(tree->right);
2585 /*-----------------------------------------------------------------*/
2586 /* geniCodeJumpTable - tries to create a jump table for switch */
2587 /*-----------------------------------------------------------------*/
2588 int geniCodeJumpTable (operand *cond, value *caseVals, ast *tree)
2590 int min = 0 ,max = 0, t, cnt = 0;
2595 set *labels = NULL ;
2597 if (!tree || !caseVals)
2600 /* the criteria for creating a jump table is */
2601 /* all integer numbers between the maximum & minimum must */
2602 /* be present , the maximum value should not exceed 255 */
2603 min = max = (int)floatFromVal(vch = caseVals);
2604 sprintf(buffer,"_case_%d_%d",
2605 tree->values.switchVals.swNum,
2607 addSet(&labels,newiTempLabel(buffer));
2609 /* if there is only one case value then no need */
2610 if (!(vch = vch->next ))
2614 if (((t = (int)floatFromVal(vch)) - max) != 1)
2616 sprintf(buffer,"_case_%d_%d",
2617 tree->values.switchVals.swNum,
2619 addSet(&labels,newiTempLabel(buffer));
2625 /* if the number of case statements <= 2 then */
2626 /* it is not economical to create the jump table */
2627 /* since two compares are needed for boundary conditions */
2628 if ((! optimize.noJTabBoundary && cnt <= 2) || max > (255/3))
2631 if ( tree->values.switchVals.swDefault )
2632 sprintf (buffer,"_default_%d",tree->values.switchVals.swNum);
2634 sprintf (buffer,"_swBrk_%d",tree->values.switchVals.swNum );
2636 falseLabel = newiTempLabel (buffer);
2638 /* so we can create a jumptable */
2639 /* first we rule out the boundary conditions */
2640 /* if only optimization says so */
2641 if ( ! optimize.noJTabBoundary ) {
2642 link *cetype = getSpec(operandType(cond));
2643 /* no need to check the lower bound if
2644 the condition is unsigned & minimum value is zero */
2645 if (!( min == 0 && SPEC_USIGN(cetype))) {
2646 boundary = geniCodeLogic (cond,operandFromLit(min),'<');
2647 ic = newiCodeCondition (boundary,falseLabel,NULL);
2651 /* now for upper bounds */
2652 boundary = geniCodeLogic(cond,operandFromLit(max),'>');
2653 ic = newiCodeCondition (boundary,falseLabel,NULL);
2657 /* if the min is not zero then we no make it zero */
2659 cond = geniCodeSubtract(cond,operandFromLit(min));
2660 setOperandType(cond, UCHARTYPE);
2663 /* now create the jumptable */
2664 ic = newiCode(JUMPTABLE,NULL,NULL);
2665 IC_JTCOND(ic) = cond;
2666 IC_JTLABELS(ic) = labels;
2671 /*-----------------------------------------------------------------*/
2672 /* geniCodeSwitch - changes a switch to a if statement */
2673 /*-----------------------------------------------------------------*/
2674 void geniCodeSwitch (ast *tree)
2677 operand *cond = geniCodeRValue(ast2iCode (tree->left),FALSE);
2678 value *caseVals = tree->values.switchVals.swVals ;
2679 symbol *trueLabel , *falseLabel;
2681 /* if we can make this a jump table */
2682 if ( geniCodeJumpTable (cond,caseVals,tree) )
2683 goto jumpTable ; /* no need for the comparison */
2685 /* for the cases defined do */
2688 operand *compare = geniCodeLogic (cond,
2689 operandFromValue(caseVals),
2692 sprintf(buffer,"_case_%d_%d",
2693 tree->values.switchVals.swNum,
2694 (int) floatFromVal(caseVals));
2695 trueLabel = newiTempLabel(buffer);
2697 ic = newiCodeCondition(compare,trueLabel,NULL);
2699 caseVals = caseVals->next;
2704 /* if default is present then goto break else break */
2705 if ( tree->values.switchVals.swDefault )
2706 sprintf (buffer,"_default_%d",tree->values.switchVals.swNum);
2708 sprintf (buffer,"_swBrk_%d",tree->values.switchVals.swNum );
2710 falseLabel = newiTempLabel (buffer);
2711 geniCodeGoto(falseLabel);
2714 ast2iCode(tree->right);
2717 /*-----------------------------------------------------------------*/
2718 /* geniCodeInline - intermediate code for inline assembler */
2719 /*-----------------------------------------------------------------*/
2720 static void geniCodeInline (ast *tree)
2724 ic = newiCode(INLINEASM,NULL,NULL);
2725 IC_INLINE(ic) = tree->values.inlineasm;
2729 /*-----------------------------------------------------------------*/
2730 /* ast2iCode - creates an icodeList from an ast */
2731 /*-----------------------------------------------------------------*/
2732 operand *ast2iCode (ast *tree)
2734 operand *left = NULL;
2735 operand *right= NULL;
2740 /* set the global variables for filename & line number */
2741 if ( tree->filename )
2742 filename = tree->filename ;
2744 lineno = tree->lineno ;
2746 block = tree->block ;
2748 scopeLevel = tree->level;
2750 if (tree->type == EX_VALUE )
2751 return operandFromValue(tree->opval.val);
2753 if (tree->type == EX_LINK )
2754 return operandFromLink (tree->opval.lnk);
2756 /* if we find a nullop */
2757 if (tree->type == EX_OP &&
2758 ( tree->opval.op == NULLOP ||
2759 tree->opval.op == BLOCK )) {
2760 ast2iCode (tree->left);
2761 ast2iCode (tree->right);
2765 /* special cases for not evaluating */
2766 if ( tree->opval.op != ':' &&
2767 tree->opval.op != '?' &&
2768 tree->opval.op != CALL &&
2769 tree->opval.op != IFX &&
2770 tree->opval.op != LABEL &&
2771 tree->opval.op != GOTO &&
2772 tree->opval.op != SWITCH &&
2773 tree->opval.op != FUNCTION &&
2774 tree->opval.op != INLINEASM ) {
2776 if (IS_ASSIGN_OP(tree->opval.op) ||
2777 IS_DEREF_OP(tree) ||
2778 (tree->opval.op == '&' && !tree->right) ||
2779 tree->opval.op == PTR_OP) {
2781 if ((IS_ARRAY_OP(tree->left) && IS_ARRAY_OP(tree->left->left)) ||
2782 (IS_DEREF_OP(tree) && IS_ARRAY_OP(tree->left)))
2784 int olvr = lvaluereq ;
2786 left = operandFromAst(tree->left);
2787 lvaluereq = olvr - 1;
2789 left = operandFromAst(tree->left);
2792 if (IS_DEREF_OP(tree) && IS_DEREF_OP(tree->left))
2793 left = geniCodeRValue(left,TRUE);
2795 left = operandFromAst(tree->left);
2797 if (tree->opval.op == INC_OP ||
2798 tree->opval.op == DEC_OP) {
2800 right= operandFromAst(tree->right);
2803 right= operandFromAst(tree->right);
2807 /* now depending on the type of operand */
2808 /* this will be a biggy */
2809 switch (tree->opval.op) {
2811 case '[' : /* array operation */
2813 link *ltype = operandType(left);
2814 left= geniCodeRValue (left,IS_PTR(ltype->next) ? TRUE : FALSE);
2815 right=geniCodeRValue (right,TRUE);
2818 return geniCodeArray (left,right);
2820 case '.' : /* structure dereference */
2821 if (IS_PTR(operandType(left)))
2822 left = geniCodeRValue(left,TRUE);
2824 left = geniCodeRValue(left,FALSE);
2826 return geniCodeStruct (left,right,tree->lvalue);
2828 case PTR_OP: /* structure pointer dereference */
2831 pType = operandType(left);
2832 left = geniCodeRValue(left,TRUE);
2834 setOClass (pType,getSpec(operandType(left)));
2837 return geniCodeStruct (left, right,tree->lvalue);
2839 case INC_OP: /* increment operator */
2841 return geniCodePostInc (left);
2843 return geniCodePreInc (right);
2845 case DEC_OP: /* decrement operator */
2847 return geniCodePostDec (left);
2849 return geniCodePreDec (right);
2851 case '&' : /* bitwise and or address of operator */
2852 if ( right ) { /* this is a bitwise operator */
2853 left= geniCodeRValue(left,FALSE);
2854 right= geniCodeRValue(right,FALSE);
2855 return geniCodeBitwise (left,right,BITWISEAND,tree->ftype);
2857 return geniCodeAddressOf (left);
2859 case '|': /* bitwise or & xor */
2861 return geniCodeBitwise (geniCodeRValue(left,FALSE),
2862 geniCodeRValue(right,FALSE),
2867 return geniCodeDivision (geniCodeRValue(left,FALSE),
2868 geniCodeRValue(right,FALSE));
2871 return geniCodeModulus (geniCodeRValue(left,FALSE),
2872 geniCodeRValue(right,FALSE));
2875 return geniCodeMultiply (geniCodeRValue(left,FALSE),
2876 geniCodeRValue(right,FALSE));
2878 return geniCodeDerefPtr (geniCodeRValue(left,FALSE));
2882 return geniCodeSubtract (geniCodeRValue(left,FALSE),
2883 geniCodeRValue(right,FALSE));
2885 return geniCodeUnaryMinus (geniCodeRValue(left,FALSE));
2889 return geniCodeAdd (geniCodeRValue(left,FALSE),
2890 geniCodeRValue(right,FALSE));
2892 return geniCodeRValue(left,FALSE) ; /* unary '+' has no meaning */
2895 return geniCodeLeftShift (geniCodeRValue(left,FALSE),
2896 geniCodeRValue(right,FALSE));
2899 return geniCodeRightShift (geniCodeRValue(left,FALSE),
2900 geniCodeRValue(right,FALSE));
2902 return geniCodeCast (operandType(left),
2903 geniCodeRValue(right,FALSE),FALSE);
2909 return geniCodeUnary (geniCodeRValue(left,FALSE),tree->opval.op);
2913 operand *op = geniCodeUnary (geniCodeRValue(left,FALSE),tree->opval.op);
2914 setOperandType(op, UCHARTYPE);
2925 return geniCodeLogic (geniCodeRValue(left,FALSE),
2926 geniCodeRValue(right,FALSE),
2929 return geniCodeConditional (tree);
2932 return operandFromLit(getSize(tree->right->ftype));
2936 link *rtype = operandType(right);
2937 link *ltype = operandType(left);
2938 if (IS_PTR(rtype) && IS_ITEMP(right)
2939 && right->isaddr && checkType(rtype->next,ltype)==1)
2940 right = geniCodeRValue(right,TRUE);
2942 right = geniCodeRValue(right,FALSE);
2944 geniCodeAssign (left,right,0);
2949 geniCodeAssign(left,
2950 geniCodeMultiply(geniCodeRValue (operandFromOperand(left),
2952 geniCodeRValue(right,FALSE)),0);
2956 geniCodeAssign(left,
2957 geniCodeDivision(geniCodeRValue(operandFromOperand(left),
2959 geniCodeRValue(right,FALSE)),0);
2962 geniCodeAssign(left,
2963 geniCodeModulus(geniCodeRValue(operandFromOperand(left),
2965 geniCodeRValue(right,FALSE)),0);
2968 link *rtype = operandType(right);
2969 link *ltype = operandType(left);
2970 if (IS_PTR(rtype) && IS_ITEMP(right)
2971 && right->isaddr && checkType(rtype->next,ltype)==1)
2972 right = geniCodeRValue(right,TRUE);
2974 right = geniCodeRValue(right,FALSE);
2977 return geniCodeAssign(left,
2978 geniCodeAdd (geniCodeRValue(operandFromOperand(left),
2984 link *rtype = operandType(right);
2985 link *ltype = operandType(left);
2986 if (IS_PTR(rtype) && IS_ITEMP(right)
2987 && right->isaddr && checkType(rtype->next,ltype)==1) {
2988 right = geniCodeRValue(right,TRUE);
2991 right = geniCodeRValue(right,FALSE);
2994 geniCodeAssign (left,
2995 geniCodeSubtract(geniCodeRValue(operandFromOperand(left),
3001 geniCodeAssign (left,
3002 geniCodeLeftShift(geniCodeRValue(operandFromOperand(left)
3004 geniCodeRValue(right,FALSE)),0);
3007 geniCodeAssign(left,
3008 geniCodeRightShift(geniCodeRValue(operandFromOperand(left)
3010 geniCodeRValue(right,FALSE)),0);
3013 geniCodeAssign (left,
3014 geniCodeBitwise(geniCodeRValue(operandFromOperand(left),
3016 geniCodeRValue(right,FALSE),
3018 operandType(left)),0);
3021 geniCodeAssign (left,
3022 geniCodeBitwise (geniCodeRValue(operandFromOperand(left),
3024 geniCodeRValue(right,FALSE),
3026 operandType(left)),0);
3029 geniCodeAssign (left,
3030 geniCodeBitwise (geniCodeRValue(operandFromOperand(left)
3032 geniCodeRValue(right,FALSE),
3034 operandType(left)),0);
3036 return geniCodeRValue(right,FALSE);
3039 return geniCodeCall (ast2iCode(tree->left),
3042 geniCodeLabel(ast2iCode(tree->left)->operand.symOperand);
3043 return ast2iCode (tree->right);
3046 geniCodeGoto (ast2iCode(tree->left)->operand.symOperand);
3047 return ast2iCode (tree->right);
3050 geniCodeFunctionBody ( tree );
3054 geniCodeReturn (right);
3062 geniCodeSwitch (tree);
3066 geniCodeInline (tree);
3073 /*-----------------------------------------------------------------*/
3074 /* reverseICChain - gets from the list and creates a linkedlist */
3075 /*-----------------------------------------------------------------*/
3076 iCode *reverseiCChain ()
3078 iCode *loop = NULL ;
3079 iCode *prev = NULL ;
3081 while ((loop = getSet(&iCodeChain))) {
3092 /*-----------------------------------------------------------------*/
3093 /* iCodeFromAst - given an ast will convert it to iCode */
3094 /*-----------------------------------------------------------------*/
3095 iCode *iCodeFromAst ( ast *tree )
3097 returnLabel = newiTempLabel("_return");
3098 entryLabel = newiTempLabel("_entry") ;
3100 return reverseiCChain ();