* Changed limit on 256$ to > 256
[fw/sdcc] / src / SDCCicode.h
1 /*-------------------------------------------------------------------------
2
3   SDCCicode.h - intermediate code generation etc.                 
4                 Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5
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
9    later version.
10    
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.
15    
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.
19    
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 -------------------------------------------------------------------------*/
24 #include "SDCCbitv.h"
25 #include "SDCCset.h"
26
27 #ifndef SDCCICODE_H
28 #define SDCCICODE_H 1
29
30 extern symbol *returnLabel ;
31 extern symbol *entryLabel  ;
32 extern int iCodeKey ;
33 extern int operandKey ;
34
35 enum {
36         CONDITIONAL = 0 ,
37         EXPRESSION      ,
38         STATEMENT       ,
39         LEAF            };
40
41 typedef enum {
42   SYMBOL    =1,
43   VALUE       ,
44   TYPE      
45 } OPTYPE;
46
47 #define IS_SYMOP(op) (op && op->type == SYMBOL)
48 #define ADDTOCHAIN(x) addSetHead(&iCodeChain,x)
49
50 #define LRFTYPE       link *ltype = operandType(left), \
51                            *rtype = operandType(right) ;
52 #define LRETYPE       link *letype= getSpec(ltype)   , \
53                            *retype= getSpec(rtype);
54 #define LRTYPE        LRFTYPE LRETYPE
55 #define IS_ITEMP(op)       (IS_SYMOP(op) && op->operand.symOperand->isitmp == 1)
56 #define IS_PARM(op)        (IS_SYMOP(op) && op->operand.symOperand->_isparm)
57 #define IS_ITEMPLBL(op)    (IS_ITEMP(op) && op->operand.symOperand->isilbl == 1);
58 #define IS_OP_VOLATILE(op) (IS_SYMOP(op) && op->isvolatile)
59 #define IS_OP_LITERAL(op)  (op && op->isLiteral)
60 #define IS_OP_GLOBAL(op)   (IS_SYMOP(op) && op->isGlobal)
61 #define IS_OP_POINTER(op)  (IS_SYMOP(op) && op->isPtr)
62 #define IS_OP_PARM(op)     (IS_SYMOP(op) && op->isParm)
63 #define OP_SYMBOL(op)      op->operand.symOperand
64 #define OP_SYM_TYPE(op)    op->operand.symOperand->type
65 #define OP_SYM_ETYPE(op)   op->operand.symOperand->etype
66 #define SPIL_LOC(op)       op->operand.symOperand->usl.spillLoc
67 #define OP_LIVEFROM(op)    op->operand.symOperand->liveFrom
68 #define OP_LIVETO(op)      op->operand.symOperand->liveTo
69 #define OP_REQV(op)        op->operand.symOperand->reqv
70
71 /* typedef for operand */
72 typedef struct operand {
73     OPTYPE type;                 /* type of operand */
74     unsigned int  isaddr : 1;    /* is an address   */
75     unsigned int  isvolatile: 1; /* is a volatile operand */
76     unsigned int  isGlobal :1 ;  /* is a global operand */
77     unsigned int  isPtr    :1 ;  /* is assigned a pointer */
78     unsigned int  isGptr   :1 ;  /* is a generic pointer  */
79     unsigned int  isParm   :1 ;  /* is a parameter        */
80     unsigned int  isLiteral:1 ;  /* operand is literal    */
81     unsigned int  noSpilLoc:1 ;  /* cannot be assigned a spil location */
82     
83     unsigned key ;
84     int      parmBytes;
85     union {
86         struct symbol *symOperand ; /* operand is of type symbol */
87         struct value  *valOperand ; /* operand is of type value  */
88         struct link   *typeOperand; /* operand is of type typechain */
89     } operand ;
90     
91     bitVect *usesDefs;             /* which definitions are used by this */
92     struct  asmop *aop      ;      /* asm op for this operand */
93 } operand ;
94
95 /* definition for intermediate code */ 
96 #define IC_RESULT(x) x->ulrrcnd.lrr.result
97 #define IC_LEFT(x)   x->ulrrcnd.lrr.left
98 #define IC_RIGHT(x)  x->ulrrcnd.lrr.right
99 #define IC_COND(x)   x->ulrrcnd.cnd.condition
100 #define IC_TRUE(x)   x->ulrrcnd.cnd.trueLabel
101 #define IC_FALSE(x)  x->ulrrcnd.cnd.falseLabel
102 #define IC_LABEL(x)  x->argLabel.label
103 #define IC_ARGS(x)   x->argLabel.args
104 #define IC_JTCOND(x) x->ulrrcnd.jmpTab.condition
105 #define IC_JTLABELS(x) x->ulrrcnd.jmpTab.labels
106 #define IC_INLINE(x) x->inlineAsm
107
108 typedef struct iCode 
109 {
110     unsigned int op ;              /* operation defined */
111     int key ;                      /* running key for this iCode */
112     int seq ;                      /* sequence number within routine */
113     short depth ;                  /* loop depth of this iCode */
114     short level ;                  /* scope level */
115     short block ;                  /* sequential block number */
116     unsigned nosupdate:1;          /* don't update spillocation with this */
117     unsigned generated:1;          /* code generated for this one */   
118     unsigned parmPush :1;          /* parameter push Vs spill push */
119     unsigned supportRtn:1;         /* will cause a call to a support routine */
120     unsigned regsSaved:1 ;         /* registers have been saved */
121     unsigned bankSaved:1 ;         /* register bank has been saved */
122     
123     struct iCode *next ;           /* next in chain */
124     struct iCode *prev ;           /* previous in chain */
125     set          *movedFrom;       /* if this iCode gets moved to another block */
126     bitVect *rlive ;               /* ranges that are live at this point */
127     int    defKey  ;               /* key for the operand being defined  */
128     bitVect *uses  ;               /* vector of key of used symbols      */
129     bitVect *rUsed ;               /* registers used by this instruction */
130     bitVect *rMask ;               /* registers in use during this instruction */
131     union {
132         struct {
133             operand *left      ;           /* left if any   */
134             operand *right     ;           /* right if any  */
135             operand *result    ;           /* result of this op */
136         } lrr ;
137
138         struct {
139             operand *condition ;           /* if this is a conditional */
140             symbol  *trueLabel ;           /* true for conditional     */
141             symbol  *falseLabel;           /* false for conditional    */
142         } cnd;
143
144         struct {
145             operand *condition ;           /* condition for the jump */
146             set     *labels    ;           /* ordered set of labels  */
147         } jmpTab ;
148
149     } ulrrcnd;
150
151     union {
152         symbol  *label ;           /* for a goto statement     */
153         value   *args  ;
154     } argLabel ;
155     
156     char        *inlineAsm ;           /* pointer to inline assembler code */
157
158     int     lineno      ;           /* file & lineno for debug information */
159     char   *filename    ;         
160 } iCode ;
161
162 /* various functions associated to iCode */
163 typedef struct icodeFuncTable 
164 {
165     int icode ;
166     char *printName ;
167     void (*iCodePrint)(FILE *,iCode *,char *) ;
168     iCode * (*iCodeCopy)(iCode *) ;
169 } iCodeTable ;
170
171 /* useful macros */
172 #define SKIP_IC2(x)  (x->op == GOTO     ||     \
173                       x->op == LABEL    ||     \
174                       x->op == FUNCTION ||     \
175                       x->op == INLINEASM ||    \
176                       x->op == ENDFUNCTION   )
177
178 #define SKIP_IC1(x)  (x->op == CALL     ||     \
179                       SKIP_IC2(x) )
180
181 #define SKIP_IC(x)   (x->op == PCALL    ||     \
182                       x->op == IPUSH    ||     \
183                       x->op == IPOP     ||     \
184                       x->op == JUMPTABLE ||    \
185                       x->op == RECEIVE  ||     \
186                       SKIP_IC1(x)||  \
187                       x->op == SEND         ) 
188
189 #define IS_CONDITIONAL(x) (x->op == EQ_OP || \
190                            x->op == '<'   || \
191                            x->op == '>'   || \
192                            x->op == LE_OP || \
193                            x->op == GE_OP || \
194                            x->op == NE_OP )
195
196 #define IS_TRUE_SYMOP(op) (op && IS_SYMOP(op) && !IS_ITEMP(op))
197
198 #define POINTER_SET(ic) ( ic && ic->op == '='           \
199                              && IS_ITEMP(IC_RESULT(ic)) \
200                              && IC_RESULT(ic)->isaddr )
201
202 #define POINTER_GET(ic) ( ic && ic->op == GET_VALUE_AT_ADDRESS  \
203                              &&  (IS_ITEMP(IC_LEFT(ic)) || IS_OP_LITERAL(IC_LEFT(ic)))\
204                              &&  IC_LEFT(ic)->isaddr )
205
206 #define IS_ARITHMETIC_OP(x) (x && (x->op == '+' || \
207                                    x->op == '-' || \
208                                    x->op == '/' || \
209                                    x->op == '*' || \
210                                    x->op == '%'))
211 #define IS_BITWISE_OP(x) (x && (x->op == BITWISEAND || \
212                                 x->op == '|'        || \
213                                 x->op == '^'))
214
215 #define ASSIGNMENT(ic) ( ic && ic->op == '=')
216
217 #define ASSIGN_SYM_TO_ITEMP(ic) (ic && ic->op == '=' && \
218                              IS_TRUE_SYMOP(IC_RIGHT(ic)) && \
219                              IS_ITEMP(IC_RESULT(ic)))
220
221 #define ASSIGN_ITEMP_TO_SYM(ic) (ic && ic->op == '=' && \
222                              IS_TRUE_SYMOP(IC_RESULT(ic)) && \
223                              IS_ITEMP(IC_RIGHT(ic)))
224
225 #define ASSIGN_ITEMP_TO_ITEMP(ic) (ic && ic->op == '=' &&\
226                                    !POINTER_SET(ic)    &&\
227                                    IS_ITEMP(IC_RIGHT(ic)) &&\
228                                    IS_ITEMP(IC_RESULT(ic)))
229
230 #define ADD_SUBTRACT_ITEMP(ic) (ic && (ic->op == '+' || ic->op == '-') && \
231                                 IS_ITEMP(IC_RESULT(ic)) && \
232                                 ( ( IS_ITEMP(IC_LEFT(ic)) ) ||  ( IS_SYMOP(IC_LEFT(ic)) ) ) && \
233                                   IS_OP_LITERAL(IC_RIGHT(ic)))
234
235 #define ASSIGNMENT_TO_SELF(ic) (!POINTER_SET(ic) && !POINTER_GET(ic) && \
236                                 ic->op == '=' && IC_RESULT(ic)->key == IC_RIGHT(ic)->key )
237
238 #define SET_ISADDR(op,v) {op = operandFromOperand(op); op->isaddr = v;}
239 #define SET_RESULT_RIGHT(ic) {SET_ISADDR(IC_RIGHT(ic),0); SET_ISADDR(IC_RESULT(ic),0);}
240
241 #define OP_DEFS(op) op->operand.symOperand->defs
242 #define OP_USES(op) op->operand.symOperand->uses
243 /*-----------------------------------------------------------------*/
244 /* forward references for functions                                */
245 /*-----------------------------------------------------------------*/
246 iCode   *reverseiCChain     (      );
247 int      isOperandVolatile  (operand *,bool);
248 int      isOperandGlobal    (operand *);
249 void     printiCChain    ( iCode * , FILE *);
250 operand *ast2iCode          ( ast *);
251 operand *geniCodeCast       ( link *, operand *,bool);
252 operand *geniCodePtrPtrSubtract (operand *, operand *);
253 void     initiCode          ();
254 iCode   *iCodeFromAst   ( ast * );
255 int      isiCodeEqual   ( iCode *,iCode *) ;
256 int      isOperandEqual ( operand *, operand *);
257 iCodeTable *getTableEntry (int  );
258 int      isOperandLiteral (operand *);
259 operand *operandOperation (operand *,operand *,int,link *);
260 double   operandLitValue ( operand * );
261 operand *operandFromLit (float);
262 operand *operandFromOperand(operand *);
263 int      isParameterToCall (value *,operand *);
264 iCode   *newiCodeLabelGoto (int , symbol *);
265 symbol  *newiTemp(char *);
266 symbol  *newiTempLabel (char *);
267 symbol  *newiTempPreheaderLabel ();
268 iCode   *newiCode (int, operand *, operand *);
269 link    *operandType(operand *);
270 operand *operandFromValue (value *);
271 operand *operandFromSymbol(symbol *);
272 link    *aggrToPtr ( link *, bool);
273 int      piCode (void *, FILE * );
274 int      printOperand (operand *,FILE *);
275 void     setOperandType (operand *, link *);
276 bool     isOperandInFarSpace (operand *);
277 operand *opFromOpWithDU (operand *,bitVect *,bitVect *);
278 iCode   *copyiCode (iCode *);
279 operand *newiTempFromOp( operand *);
280 #endif