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 IS_TYPOP(op) (op && op->type == TYPE)
55 #define ADDTOCHAIN(x) addSetHead(&iCodeChain,x)
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_SYMBOL(op) op->operand.symOperand
71 #define OP_SYM_TYPE(op) op->operand.symOperand->type
72 #define OP_SYM_ETYPE(op) op->operand.symOperand->etype
73 #define OP_VALUE(op) op->operand.valOperand
74 #define SPIL_LOC(op) op->operand.symOperand->usl.spillLoc
75 #define OP_LIVEFROM(op) op->operand.symOperand->liveFrom
76 #define OP_LIVETO(op) op->operand.symOperand->liveTo
77 #define OP_REQV(op) op->operand.symOperand->reqv
78 #define OP_ISLIVE_FCALL(op) (IS_ITEMP(op) && OP_SYMBOL(op)->isLiveFcall)
79 #define SYM_SPIL_LOC(sym) sym->usl.spillLoc
81 /* typedef for operand */
82 typedef struct operand
84 OPTYPE type; /* type of operand */
85 unsigned int isaddr:1; /* is an address */
86 unsigned int isvolatile:1; /* is a volatile operand */
87 unsigned int isGlobal:1; /* is a global operand */
88 unsigned int isPtr:1; /* is assigned a pointer */
89 unsigned int isGptr:1; /* is a generic pointer */
90 unsigned int isParm:1; /* is a parameter */
91 unsigned int isLiteral:1; /* operand is literal */
96 struct symbol *symOperand; /* operand is of type symbol */
97 struct value *valOperand; /* operand is of type value */
98 struct sym_link *typeOperand; /* operand is of type typechain */
102 bitVect *usesDefs; /* which definitions are used by this */
103 struct asmop *aop; /* asm op for this operand */
107 /* definition for intermediate code */
108 #define IC_RESULT(x) (x)->ulrrcnd.lrr.result
109 #define IC_LEFT(x) (x)->ulrrcnd.lrr.left
110 #define IC_RIGHT(x) (x)->ulrrcnd.lrr.right
111 #define IC_COND(x) (x)->ulrrcnd.cnd.condition
112 #define IC_TRUE(x) (x)->ulrrcnd.cnd.trueLabel
113 #define IC_FALSE(x) (x)->ulrrcnd.cnd.falseLabel
114 #define IC_LABEL(x) (x)->argLabel.label
115 // jwk #define IC_ARGS(x) (x)->argLabel.args
116 #define IC_JTCOND(x) (x)->ulrrcnd.jmpTab.condition
117 #define IC_JTLABELS(x) (x)->ulrrcnd.jmpTab.labels
118 #define IC_INLINE(x) (x)->inlineAsm
119 #define IC_ARRAYILIST(x) (x)->arrayInitList
123 unsigned int op; /* operation defined */
124 int key; /* running key for this iCode */
125 int seq; /* sequence number within routine */
126 short depth; /* loop depth of this iCode */
127 short level; /* scope level */
128 short block; /* sequential block number */
129 unsigned nosupdate:1; /* don't update spillocation with this */
130 unsigned generated:1; /* code generated for this one */
131 unsigned parmPush:1; /* parameter push Vs spill push */
132 unsigned supportRtn:1; /* will cause a call to a support routine */
133 unsigned regsSaved:1; /* registers have been saved */
134 unsigned bankSaved:1; /* register bank has been saved */
135 unsigned builtinSEND:1; /* SEND for parameter of builtin function */
137 struct iCode *next; /* next in chain */
138 struct iCode *prev; /* previous in chain */
139 set *movedFrom; /* if this iCode gets moved to another block */
140 bitVect *rlive; /* ranges that are live at this point */
141 int defKey; /* key for the operand being defined */
142 bitVect *uses; /* vector of key of used symbols */
143 bitVect *rUsed; /* registers used by this instruction */
144 bitVect *rMask; /* registers in use during this instruction */
149 operand *left; /* left if any */
150 operand *right; /* right if any */
151 operand *result; /* result of this op */
157 operand *condition; /* if this is a conditional */
158 symbol *trueLabel; /* true for conditional */
159 symbol *falseLabel; /* false for conditional */
165 operand *condition; /* condition for the jump */
166 set *labels; /* ordered set of labels */
175 symbol *label; /* for a goto statement */
176 // jwk value *args; /* for a function */
180 char *inlineAsm; /* pointer to inline assembler code */
181 literalList *arrayInitList; /* point to array initializer list. */
183 int lineno; /* file & lineno for debug information */
186 int parmBytes; /* if call/pcall, count of parameter bytes
188 int argreg; /* argument regno for SEND/RECEIVE */
189 int eBBlockNum; /* belongs to which eBBlock */
193 /* various functions associated to iCode */
194 typedef struct icodeFuncTable
198 void (*iCodePrint) (FILE *, iCode *, char *);
199 iCode *(*iCodeCopy) (iCode *);
204 #define SKIP_IC2(x) (x->op == GOTO || \
206 x->op == FUNCTION || \
207 x->op == INLINEASM || \
208 x->op == ENDFUNCTION )
210 #define SKIP_IC1(x) (x->op == CALL || \
213 #define SKIP_IC(x) (x->op == PCALL || \
216 x->op == JUMPTABLE || \
217 x->op == RECEIVE || \
218 x->op == ARRAYINIT || \
222 #define SKIP_IC3(x) (SKIP_IC2(x) || \
225 #define IS_CONDITIONAL(x) (x->op == EQ_OP || \
232 #define IS_TRUE_SYMOP(op) (op && IS_SYMOP(op) && !IS_ITEMP(op))
234 #define POINTER_SET(ic) ( ic && ic->op == '=' \
235 && IS_ITEMP(IC_RESULT(ic)) \
236 && IC_RESULT(ic)->isaddr )
238 #define POINTER_GET(ic) ( ic && ic->op == GET_VALUE_AT_ADDRESS \
239 && (IS_ITEMP(IC_LEFT(ic)) || IS_OP_LITERAL(IC_LEFT(ic)))\
240 && IC_LEFT(ic)->isaddr )
242 #define IS_ARITHMETIC_OP(x) (x && (x->op == '+' || \
247 #define IS_BITWISE_OP(x) (x && (x->op == BITWISEAND || \
251 #define ASSIGNMENT(ic) ( ic && ic->op == '=')
253 #define ASSIGN_SYM_TO_ITEMP(ic) (ic && ic->op == '=' && \
254 IS_TRUE_SYMOP(IC_RIGHT(ic)) && \
255 IS_ITEMP(IC_RESULT(ic)))
257 #define ASSIGN_ITEMP_TO_SYM(ic) (ic && ic->op == '=' && \
258 IS_TRUE_SYMOP(IC_RESULT(ic)) && \
259 IS_ITEMP(IC_RIGHT(ic)))
261 #define ASSIGN_ITEMP_TO_ITEMP(ic) (ic && ic->op == '=' &&\
263 IS_ITEMP(IC_RIGHT(ic)) &&\
264 IS_ITEMP(IC_RESULT(ic)))
266 #define ADD_SUBTRACT_ITEMP(ic) (ic && (ic->op == '+' || ic->op == '-') && \
267 IS_ITEMP(IC_RESULT(ic)) && \
268 ( ( IS_ITEMP(IC_LEFT(ic)) ) || ( IS_SYMOP(IC_LEFT(ic)) ) ) && \
269 IS_OP_LITERAL(IC_RIGHT(ic)))
271 #define ASSIGNMENT_TO_SELF(ic) (!POINTER_SET(ic) && !POINTER_GET(ic) && \
272 ic->op == '=' && IC_RESULT(ic)->key == IC_RIGHT(ic)->key )
274 #define IS_CAST_ICODE(ic) (ic && ic->op == CAST)
275 #define SET_ISADDR(op,v) {op = operandFromOperand(op); op->isaddr = v;}
276 #define SET_RESULT_RIGHT(ic) {SET_ISADDR(IC_RIGHT(ic),0); SET_ISADDR(IC_RESULT(ic),0);}
277 #define IS_ASSIGN_ICODE(ic) (ASSIGNMENT(ic) && !POINTER_SET(ic))
279 #define OP_DEFS(op) op->operand.symOperand->defs
280 #define OP_USES(op) op->operand.symOperand->uses
281 /*-----------------------------------------------------------------*/
282 /* forward references for functions */
283 /*-----------------------------------------------------------------*/
284 iCode *reverseiCChain ();
285 bool isOperandOnStack (operand *);
286 int isOperandVolatile (operand *, bool);
287 int isOperandGlobal (operand *);
288 void printiCChain (iCode *, FILE *);
289 operand *ast2iCode (ast *,int);
290 operand *geniCodeCast (sym_link *, operand *, bool);
291 operand *geniCodePtrPtrSubtract (operand *, operand *);
293 iCode *iCodeFromAst (ast *);
294 int isiCodeEqual (iCode *, iCode *);
295 int isOperandEqual (operand *, operand *);
296 iCodeTable *getTableEntry (int);
297 int isOperandLiteral (operand *);
298 operand *operandOperation (operand *, operand *, int, sym_link *);
299 double operandLitValue (operand *);
300 operand *operandFromLit (double);
301 operand *operandFromOperand (operand *);
302 int isParameterToCall (value *, operand *);
303 iCode *newiCodeLabelGoto (int, symbol *);
304 symbol *newiTemp (char *);
305 symbol *newiTempLabel (char *);
306 symbol *newiTempPreheaderLabel ();
307 iCode *newiCode (int, operand *, operand *);
308 sym_link *operandType (operand *);
309 operand *operandFromValue (value *);
310 operand *operandFromSymbol (symbol *);
311 sym_link *aggrToPtr (sym_link *, bool);
312 int piCode (void *, FILE *);
313 int printOperand (operand *, FILE *);
314 void setOperandType (operand *, sym_link *);
315 bool isOperandInFarSpace (operand *);
316 bool isOperandInDirSpace (operand *);
317 bool isOperandInCodeSpace (operand *);
318 operand *opFromOpWithDU (operand *, bitVect *, bitVect *);
319 iCode *copyiCode (iCode *);
320 operand *newiTempFromOp (operand *);
321 iCode *getBuiltinParms (iCode *,int *, operand **);
322 /*-----------------------------------------------------------------*/
323 /* declaration of exported variables */
324 /*-----------------------------------------------------------------*/
325 extern char *filename;