1 /*-------------------------------------------------------------------------
3 SDCCicode.h - 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 -------------------------------------------------------------------------*/
30 extern symbol *returnLabel;
31 extern symbol *entryLabel;
33 extern int operandKey;
51 #define IS_SYMOP(op) (op && op->type == SYMBOL)
52 #define IS_VALOP(op) (op && op->type == VALUE)
53 #define ADDTOCHAIN(x) addSetHead(&iCodeChain,x)
55 #define LRFTYPE sym_link *ltype = operandType(left), \
56 *rtype = operandType(right) ;
57 #define LRETYPE sym_link *letype= getSpec(ltype) , \
58 *retype= getSpec(rtype);
59 #define LRTYPE LRFTYPE LRETYPE
60 #define IS_ITEMP(op) (IS_SYMOP(op) && op->operand.symOperand->isitmp == 1)
61 #define IS_PARM(op) (IS_SYMOP(op) && op->operand.symOperand->_isparm)
62 #define IS_ITEMPLBL(op) (IS_ITEMP(op) && op->operand.symOperand->isilbl == 1);
63 #define IS_OP_VOLATILE(op) (IS_SYMOP(op) && op->isvolatile)
64 #define IS_OP_LITERAL(op) (op && op->isLiteral)
65 #define IS_OP_GLOBAL(op) (IS_SYMOP(op) && op->isGlobal)
66 #define IS_OP_POINTER(op) (IS_SYMOP(op) && op->isPtr)
67 #define IS_OP_PARM(op) (IS_SYMOP(op) && op->isParm)
68 #define OP_SYMBOL(op) op->operand.symOperand
69 #define OP_SYM_TYPE(op) op->operand.symOperand->type
70 #define OP_SYM_ETYPE(op) op->operand.symOperand->etype
71 #define OP_VALUE(op) op->operand.valOperand
72 #define SPIL_LOC(op) op->operand.symOperand->usl.spillLoc
73 #define OP_LIVEFROM(op) op->operand.symOperand->liveFrom
74 #define OP_LIVETO(op) op->operand.symOperand->liveTo
75 #define OP_REQV(op) op->operand.symOperand->reqv
76 #define OP_ISLIVE_FCALL(op) (IS_ITEMP(op) && OP_SYMBOL(op)->isLiveFcall)
77 #define SYM_SPIL_LOC(sym) sym->usl.spillLoc
79 /* typedef for operand */
80 typedef struct operand
82 OPTYPE type; /* type of operand */
83 unsigned int isaddr:1; /* is an address */
84 unsigned int isvolatile:1; /* is a volatile operand */
85 unsigned int isGlobal:1; /* is a global operand */
86 unsigned int isPtr:1; /* is assigned a pointer */
87 unsigned int isGptr:1; /* is a generic pointer */
88 unsigned int isParm:1; /* is a parameter */
89 unsigned int isLiteral:1; /* operand is literal */
94 struct symbol *symOperand; /* operand is of type symbol */
95 struct value *valOperand; /* operand is of type value */
96 struct sym_link *typeOperand; /* operand is of type typechain */
100 bitVect *usesDefs; /* which definitions are used by this */
101 struct asmop *aop; /* asm op for this operand */
105 /* definition for intermediate code */
106 #define IC_RESULT(x) (x)->ulrrcnd.lrr.result
107 #define IC_LEFT(x) (x)->ulrrcnd.lrr.left
108 #define IC_RIGHT(x) (x)->ulrrcnd.lrr.right
109 #define IC_COND(x) (x)->ulrrcnd.cnd.condition
110 #define IC_TRUE(x) (x)->ulrrcnd.cnd.trueLabel
111 #define IC_FALSE(x) (x)->ulrrcnd.cnd.falseLabel
112 #define IC_LABEL(x) (x)->argLabel.label
113 // jwk #define IC_ARGS(x) (x)->argLabel.args
114 #define IC_JTCOND(x) (x)->ulrrcnd.jmpTab.condition
115 #define IC_JTLABELS(x) (x)->ulrrcnd.jmpTab.labels
116 #define IC_INLINE(x) (x)->inlineAsm
117 #define IC_ARRAYILIST(x) (x)->arrayInitList
121 unsigned int op; /* operation defined */
122 int key; /* running key for this iCode */
123 int seq; /* sequence number within routine */
124 short depth; /* loop depth of this iCode */
125 short level; /* scope level */
126 short block; /* sequential block number */
127 unsigned nosupdate:1; /* don't update spillocation with this */
128 unsigned generated:1; /* code generated for this one */
129 unsigned parmPush:1; /* parameter push Vs spill push */
130 unsigned supportRtn:1; /* will cause a call to a support routine */
131 unsigned regsSaved:1; /* registers have been saved */
132 unsigned bankSaved:1; /* register bank has been saved */
134 struct iCode *next; /* next in chain */
135 struct iCode *prev; /* previous in chain */
136 set *movedFrom; /* if this iCode gets moved to another block */
137 bitVect *rlive; /* ranges that are live at this point */
138 int defKey; /* key for the operand being defined */
139 bitVect *uses; /* vector of key of used symbols */
140 bitVect *rUsed; /* registers used by this instruction */
141 bitVect *rMask; /* registers in use during this instruction */
146 operand *left; /* left if any */
147 operand *right; /* right if any */
148 operand *result; /* result of this op */
154 operand *condition; /* if this is a conditional */
155 symbol *trueLabel; /* true for conditional */
156 symbol *falseLabel; /* false for conditional */
162 operand *condition; /* condition for the jump */
163 set *labels; /* ordered set of labels */
172 symbol *label; /* for a goto statement */
173 // jwk value *args; /* for a function */
177 char *inlineAsm; /* pointer to inline assembler code */
178 literalList *arrayInitList; /* point to array initializer list. */
180 int lineno; /* file & lineno for debug information */
183 int parmBytes; /* if call/pcall, count of parameter bytes
185 int eBBlockNum; /* belongs to which eBBlock */
189 /* various functions associated to iCode */
190 typedef struct icodeFuncTable
194 void (*iCodePrint) (FILE *, iCode *, char *);
195 iCode *(*iCodeCopy) (iCode *);
200 #define SKIP_IC2(x) (x->op == GOTO || \
202 x->op == FUNCTION || \
203 x->op == INLINEASM || \
204 x->op == ENDFUNCTION )
206 #define SKIP_IC1(x) (x->op == CALL || \
209 #define SKIP_IC(x) (x->op == PCALL || \
212 x->op == JUMPTABLE || \
213 x->op == RECEIVE || \
214 x->op == ARRAYINIT || \
218 #define IS_CONDITIONAL(x) (x->op == EQ_OP || \
225 #define IS_TRUE_SYMOP(op) (op && IS_SYMOP(op) && !IS_ITEMP(op))
227 #define POINTER_SET(ic) ( ic && ic->op == '=' \
228 && IS_ITEMP(IC_RESULT(ic)) \
229 && IC_RESULT(ic)->isaddr )
231 #define POINTER_GET(ic) ( ic && ic->op == GET_VALUE_AT_ADDRESS \
232 && (IS_ITEMP(IC_LEFT(ic)) || IS_OP_LITERAL(IC_LEFT(ic)))\
233 && IC_LEFT(ic)->isaddr )
235 #define IS_ARITHMETIC_OP(x) (x && (x->op == '+' || \
240 #define IS_BITWISE_OP(x) (x && (x->op == BITWISEAND || \
244 #define ASSIGNMENT(ic) ( ic && ic->op == '=')
246 #define ASSIGN_SYM_TO_ITEMP(ic) (ic && ic->op == '=' && \
247 IS_TRUE_SYMOP(IC_RIGHT(ic)) && \
248 IS_ITEMP(IC_RESULT(ic)))
250 #define ASSIGN_ITEMP_TO_SYM(ic) (ic && ic->op == '=' && \
251 IS_TRUE_SYMOP(IC_RESULT(ic)) && \
252 IS_ITEMP(IC_RIGHT(ic)))
254 #define ASSIGN_ITEMP_TO_ITEMP(ic) (ic && ic->op == '=' &&\
256 IS_ITEMP(IC_RIGHT(ic)) &&\
257 IS_ITEMP(IC_RESULT(ic)))
259 #define ADD_SUBTRACT_ITEMP(ic) (ic && (ic->op == '+' || ic->op == '-') && \
260 IS_ITEMP(IC_RESULT(ic)) && \
261 ( ( IS_ITEMP(IC_LEFT(ic)) ) || ( IS_SYMOP(IC_LEFT(ic)) ) ) && \
262 IS_OP_LITERAL(IC_RIGHT(ic)))
264 #define ASSIGNMENT_TO_SELF(ic) (!POINTER_SET(ic) && !POINTER_GET(ic) && \
265 ic->op == '=' && IC_RESULT(ic)->key == IC_RIGHT(ic)->key )
267 #define IS_CAST_ICODE(ic) (ic && ic->op == CAST)
268 #define SET_ISADDR(op,v) {op = operandFromOperand(op); op->isaddr = v;}
269 #define SET_RESULT_RIGHT(ic) {SET_ISADDR(IC_RIGHT(ic),0); SET_ISADDR(IC_RESULT(ic),0);}
270 #define IS_ASSIGN_ICODE(ic) (ASSIGNMENT(ic) && !POINTER_SET(ic))
272 #define OP_DEFS(op) op->operand.symOperand->defs
273 #define OP_USES(op) op->operand.symOperand->uses
274 /*-----------------------------------------------------------------*/
275 /* forward references for functions */
276 /*-----------------------------------------------------------------*/
277 iCode *reverseiCChain ();
278 bool isOperandOnStack (operand *);
279 int isOperandVolatile (operand *, bool);
280 int isOperandGlobal (operand *);
281 void printiCChain (iCode *, FILE *);
282 operand *ast2iCode (ast *,int);
283 operand *geniCodeCast (sym_link *, operand *, bool);
284 operand *geniCodePtrPtrSubtract (operand *, operand *);
286 iCode *iCodeFromAst (ast *);
287 int isiCodeEqual (iCode *, iCode *);
288 int isOperandEqual (operand *, operand *);
289 iCodeTable *getTableEntry (int);
290 int isOperandLiteral (operand *);
291 operand *operandOperation (operand *, operand *, int, sym_link *);
292 double operandLitValue (operand *);
293 operand *operandFromLit (double);
294 operand *operandFromOperand (operand *);
295 int isParameterToCall (value *, operand *);
296 iCode *newiCodeLabelGoto (int, symbol *);
297 symbol *newiTemp (char *);
298 symbol *newiTempLabel (char *);
299 symbol *newiTempPreheaderLabel ();
300 iCode *newiCode (int, operand *, operand *);
301 sym_link *operandType (operand *);
302 operand *operandFromValue (value *);
303 operand *operandFromSymbol (symbol *);
304 sym_link *aggrToPtr (sym_link *, bool);
305 int piCode (void *, FILE *);
306 int printOperand (operand *, FILE *);
307 void setOperandType (operand *, sym_link *);
308 bool isOperandInFarSpace (operand *);
309 operand *opFromOpWithDU (operand *, bitVect *, bitVect *);
310 iCode *copyiCode (iCode *);
311 operand *newiTempFromOp (operand *);
312 /*-----------------------------------------------------------------*/
313 /* declaration of exported variables */
314 /*-----------------------------------------------------------------*/
315 extern char *filename;