Change struct link to struct sym_link to avoid conflict with struct link in unistd.h
[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       sym_link *ltype = operandType(left), \
51                            *rtype = operandType(right) ;
52 #define LRETYPE       sym_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 #define OP_ISLIVE_FCALL(op) (IS_ITEMP(op) && OP_SYMBOL(op)->isLiveFcall)
71
72 /* typedef for operand */
73 typedef struct operand {
74     OPTYPE type;                 /* type of operand */
75     unsigned int  isaddr : 1;    /* is an address   */
76     unsigned int  isvolatile: 1; /* is a volatile operand */
77     unsigned int  isGlobal :1 ;  /* is a global operand */
78     unsigned int  isPtr    :1 ;  /* is assigned a pointer */
79     unsigned int  isGptr   :1 ;  /* is a generic pointer  */
80     unsigned int  isParm   :1 ;  /* is a parameter        */
81     unsigned int  isLiteral:1 ;  /* operand is literal    */
82     unsigned int  noSpilLoc:1 ;  /* cannot be assigned a spil location */
83
84     unsigned key ;
85     int      parmBytes;
86     union {
87         struct symbol *symOperand ; /* operand is of type symbol */
88         struct value  *valOperand ; /* operand is of type value  */
89         struct sym_link *typeOperand; /* operand is of type typechain */
90     } operand ;
91     
92     bitVect *usesDefs;             /* which definitions are used by this */
93     struct  asmop *aop      ;      /* asm op for this operand */
94 } operand ;
95
96 /* definition for intermediate code */ 
97 #define IC_RESULT(x) x->ulrrcnd.lrr.result
98 #define IC_LEFT(x)   x->ulrrcnd.lrr.left
99 #define IC_RIGHT(x)  x->ulrrcnd.lrr.right
100 #define IC_COND(x)   x->ulrrcnd.cnd.condition
101 #define IC_TRUE(x)   x->ulrrcnd.cnd.trueLabel
102 #define IC_FALSE(x)  x->ulrrcnd.cnd.falseLabel
103 #define IC_LABEL(x)  x->argLabel.label
104 #define IC_ARGS(x)   x->argLabel.args
105 #define IC_JTCOND(x) x->ulrrcnd.jmpTab.condition
106 #define IC_JTLABELS(x) x->ulrrcnd.jmpTab.labels
107 #define IC_INLINE(x) x->inlineAsm
108
109 typedef struct iCode 
110 {
111     unsigned int op ;              /* operation defined */
112     int key ;                      /* running key for this iCode */
113     int seq ;                      /* sequence number within routine */
114     short depth ;                  /* loop depth of this iCode */
115     short level ;                  /* scope level */
116     short block ;                  /* sequential block number */
117     unsigned nosupdate:1;          /* don't update spillocation with this */
118     unsigned generated:1;          /* code generated for this one */   
119     unsigned parmPush :1;          /* parameter push Vs spill push */
120     unsigned supportRtn:1;         /* will cause a call to a support routine */
121     unsigned regsSaved:1 ;         /* registers have been saved */
122     unsigned bankSaved:1 ;         /* register bank has been saved */
123     
124     struct iCode *next ;           /* next in chain */
125     struct iCode *prev ;           /* previous in chain */
126     set          *movedFrom;       /* if this iCode gets moved to another block */
127     bitVect *rlive ;               /* ranges that are live at this point */
128     int    defKey  ;               /* key for the operand being defined  */
129     bitVect *uses  ;               /* vector of key of used symbols      */
130     bitVect *rUsed ;               /* registers used by this instruction */
131     bitVect *rMask ;               /* registers in use during this instruction */
132     union {
133         struct {
134             operand *left      ;           /* left if any   */
135             operand *right     ;           /* right if any  */
136             operand *result    ;           /* result of this op */
137         } lrr ;
138
139         struct {
140             operand *condition ;           /* if this is a conditional */
141             symbol  *trueLabel ;           /* true for conditional     */
142             symbol  *falseLabel;           /* false for conditional    */
143         } cnd;
144
145         struct {
146             operand *condition ;           /* condition for the jump */
147             set     *labels    ;           /* ordered set of labels  */
148         } jmpTab ;
149
150     } ulrrcnd;
151
152     union {
153         symbol  *label ;           /* for a goto statement     */
154         value   *args  ;
155     } argLabel ;
156     
157     char        *inlineAsm ;           /* pointer to inline assembler code */
158
159     int     lineno      ;           /* file & lineno for debug information */
160     char   *filename    ;         
161 } iCode ;
162
163 /* various functions associated to iCode */
164 typedef struct icodeFuncTable 
165 {
166     int icode ;
167     char *printName ;
168     void (*iCodePrint)(FILE *,iCode *,char *) ;
169     iCode * (*iCodeCopy)(iCode *) ;
170 } iCodeTable ;
171
172 /* useful macros */
173 #define SKIP_IC2(x)  (x->op == GOTO     ||     \
174                       x->op == LABEL    ||     \
175                       x->op == FUNCTION ||     \
176                       x->op == INLINEASM ||    \
177                       x->op == ENDFUNCTION   )
178
179 #define SKIP_IC1(x)  (x->op == CALL     ||     \
180                       SKIP_IC2(x) )
181
182 #define SKIP_IC(x)   (x->op == PCALL    ||     \
183                       x->op == IPUSH    ||     \
184                       x->op == IPOP     ||     \
185                       x->op == JUMPTABLE ||    \
186                       x->op == RECEIVE  ||     \
187                       SKIP_IC1(x)||  \
188                       x->op == SEND         ) 
189
190 #define IS_CONDITIONAL(x) (x->op == EQ_OP || \
191                            x->op == '<'   || \
192                            x->op == '>'   || \
193                            x->op == LE_OP || \
194                            x->op == GE_OP || \
195                            x->op == NE_OP )
196
197 #define IS_TRUE_SYMOP(op) (op && IS_SYMOP(op) && !IS_ITEMP(op))
198
199 #define POINTER_SET(ic) ( ic && ic->op == '='           \
200                              && IS_ITEMP(IC_RESULT(ic)) \
201                              && IC_RESULT(ic)->isaddr )
202
203 #define POINTER_GET(ic) ( ic && ic->op == GET_VALUE_AT_ADDRESS  \
204                              &&  (IS_ITEMP(IC_LEFT(ic)) || IS_OP_LITERAL(IC_LEFT(ic)))\
205                              &&  IC_LEFT(ic)->isaddr )
206
207 #define IS_ARITHMETIC_OP(x) (x && (x->op == '+' || \
208                                    x->op == '-' || \
209                                    x->op == '/' || \
210                                    x->op == '*' || \
211                                    x->op == '%'))
212 #define IS_BITWISE_OP(x) (x && (x->op == BITWISEAND || \
213                                 x->op == '|'        || \
214                                 x->op == '^'))
215
216 #define ASSIGNMENT(ic) ( ic && ic->op == '=')
217
218 #define ASSIGN_SYM_TO_ITEMP(ic) (ic && ic->op == '=' && \
219                              IS_TRUE_SYMOP(IC_RIGHT(ic)) && \
220                              IS_ITEMP(IC_RESULT(ic)))
221
222 #define ASSIGN_ITEMP_TO_SYM(ic) (ic && ic->op == '=' && \
223                              IS_TRUE_SYMOP(IC_RESULT(ic)) && \
224                              IS_ITEMP(IC_RIGHT(ic)))
225
226 #define ASSIGN_ITEMP_TO_ITEMP(ic) (ic && ic->op == '=' &&\
227                                    !POINTER_SET(ic)    &&\
228                                    IS_ITEMP(IC_RIGHT(ic)) &&\
229                                    IS_ITEMP(IC_RESULT(ic)))
230
231 #define ADD_SUBTRACT_ITEMP(ic) (ic && (ic->op == '+' || ic->op == '-') && \
232                                 IS_ITEMP(IC_RESULT(ic)) && \
233                                 ( ( IS_ITEMP(IC_LEFT(ic)) ) ||  ( IS_SYMOP(IC_LEFT(ic)) ) ) && \
234                                   IS_OP_LITERAL(IC_RIGHT(ic)))
235
236 #define ASSIGNMENT_TO_SELF(ic) (!POINTER_SET(ic) && !POINTER_GET(ic) && \
237                                 ic->op == '=' && IC_RESULT(ic)->key == IC_RIGHT(ic)->key )
238
239 #define SET_ISADDR(op,v) {op = operandFromOperand(op); op->isaddr = v;}
240 #define SET_RESULT_RIGHT(ic) {SET_ISADDR(IC_RIGHT(ic),0); SET_ISADDR(IC_RESULT(ic),0);}
241
242 #define OP_DEFS(op) op->operand.symOperand->defs
243 #define OP_USES(op) op->operand.symOperand->uses
244 /*-----------------------------------------------------------------*/
245 /* forward references for functions                                */
246 /*-----------------------------------------------------------------*/
247 iCode   *reverseiCChain     (      );
248 bool     isOperandOnStack   (operand *);
249 int      isOperandVolatile  (operand *,bool);
250 int      isOperandGlobal    (operand *);
251 void     printiCChain    ( iCode * , FILE *);
252 operand *ast2iCode          ( ast *);
253 operand *geniCodeCast       ( sym_link *, operand *,bool);
254 operand *geniCodePtrPtrSubtract (operand *, operand *);
255 void     initiCode          ();
256 iCode   *iCodeFromAst   ( ast * );
257 int      isiCodeEqual   ( iCode *,iCode *) ;
258 int      isOperandEqual ( operand *, operand *);
259 iCodeTable *getTableEntry (int  );
260 int      isOperandLiteral (operand *);
261 operand *operandOperation (operand *,operand *,int,sym_link *);
262 double   operandLitValue ( operand * );
263 operand *operandFromLit (float);
264 operand *operandFromOperand(operand *);
265 int      isParameterToCall (value *,operand *);
266 iCode   *newiCodeLabelGoto (int , symbol *);
267 symbol  *newiTemp(char *);
268 symbol  *newiTempLabel (char *);
269 symbol  *newiTempPreheaderLabel ();
270 iCode   *newiCode (int, operand *, operand *);
271 sym_link *operandType(operand *);
272 operand *operandFromValue (value *);
273 operand *operandFromSymbol(symbol *);
274 sym_link *aggrToPtr ( sym_link *, bool);
275 int      piCode (void *, FILE * );
276 int      printOperand (operand *,FILE *);
277 void     setOperandType (operand *, sym_link *);
278 bool     isOperandInFarSpace (operand *);
279 operand *opFromOpWithDU (operand *,bitVect *,bitVect *);
280 iCode   *copyiCode (iCode *);
281 operand *newiTempFromOp( operand *);
282 /*-----------------------------------------------------------------*/
283 /* declaration of exported variables                               */
284 /*-----------------------------------------------------------------*/
285 extern char *filename;
286 extern int lineno;
287 #endif