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