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