Many signedness and type propagation fixes
[fw/sdcc] / src / SDCCicode.h
index 62ea5b41bdaa7643e823585f4fbee8a67d410277..1822f79ff548c01c5ae1a28ce6e32fe86d094b88 100644 (file)
 #ifndef SDCCICODE_H
 #define SDCCICODE_H 1
 
-extern symbol *returnLabel ;
-extern symbol *entryLabel  ;
-extern int iCodeKey ;
-extern int operandKey ;
-
-enum {
-       CONDITIONAL = 0 ,
-        EXPRESSION      ,
-        STATEMENT       ,
-        LEAF            };
-
-typedef enum {
-  SYMBOL    =1,
-  VALUE       ,
-  TYPE      
-} OPTYPE;
+extern symbol *returnLabel;
+extern symbol *entryLabel;
+extern int iCodeKey;
+extern int operandKey;
+
+enum
+  {
+    CONDITIONAL = 0,
+    EXPRESSION,
+    STATEMENT,
+    LEAF
+  };
+
+typedef enum
+  {
+    SYMBOL = 1,
+    VALUE,
+    TYPE
+  }
+OPTYPE;
 
 #define IS_SYMOP(op) (op && op->type == SYMBOL)
+#define IS_VALOP(op) (op && op->type == VALUE)
+#define IS_TYPOP(op) (op && op->type == TYPE)
+
 #define ADDTOCHAIN(x) addSetHead(&iCodeChain,x)
 
 #define LRFTYPE       sym_link *ltype = operandType(left), \
@@ -60,114 +67,142 @@ typedef enum {
 #define IS_OP_GLOBAL(op)   (IS_SYMOP(op) && op->isGlobal)
 #define IS_OP_POINTER(op)  (IS_SYMOP(op) && op->isPtr)
 #define IS_OP_PARM(op)     (IS_SYMOP(op) && op->isParm)
-#define OP_SYMBOL(op)      op->operand.symOperand
-#define OP_SYM_TYPE(op)    op->operand.symOperand->type
-#define OP_SYM_ETYPE(op)   op->operand.symOperand->etype
-#define SPIL_LOC(op)       op->operand.symOperand->usl.spillLoc
-#define OP_LIVEFROM(op)    op->operand.symOperand->liveFrom
-#define OP_LIVETO(op)      op->operand.symOperand->liveTo
-#define OP_REQV(op)        op->operand.symOperand->reqv
 #define OP_ISLIVE_FCALL(op) (IS_ITEMP(op) && OP_SYMBOL(op)->isLiveFcall)
+#define SYM_SPIL_LOC(sym)  sym->usl.spillLoc
 
 /* typedef for operand */
-typedef struct operand {
-    OPTYPE type;                /* type of operand */
-    unsigned int  isaddr : 1;    /* is an address   */
-    unsigned int  isvolatile: 1; /* is a volatile operand */
-    unsigned int  isGlobal :1 ;  /* is a global operand */
-    unsigned int  isPtr    :1 ;  /* is assigned a pointer */
-    unsigned int  isGptr   :1 ;  /* is a generic pointer  */
-    unsigned int  isParm   :1 ;  /* is a parameter        */
-    unsigned int  isLiteral:1 ;  /* operand is literal    */
-    unsigned int  noSpilLoc:1 ;  /* cannot be assigned a spil location */
-
-    unsigned key ;
-    int      parmBytes;
-    union {
-       struct symbol *symOperand ; /* operand is of type symbol */
-       struct value  *valOperand ; /* operand is of type value  */
-       struct sym_link *typeOperand; /* operand is of type typechain */
-    } operand ;
-    
-    bitVect *usesDefs;             /* which definitions are used by this */
-    struct  asmop *aop      ;      /* asm op for this operand */
-} operand ;
-
-/* definition for intermediate code */ 
-#define IC_RESULT(x) x->ulrrcnd.lrr.result
-#define IC_LEFT(x)   x->ulrrcnd.lrr.left
-#define IC_RIGHT(x)  x->ulrrcnd.lrr.right
-#define IC_COND(x)   x->ulrrcnd.cnd.condition
-#define IC_TRUE(x)   x->ulrrcnd.cnd.trueLabel
-#define IC_FALSE(x)  x->ulrrcnd.cnd.falseLabel
-#define IC_LABEL(x)  x->argLabel.label
-#define IC_ARGS(x)   x->argLabel.args
-#define IC_JTCOND(x) x->ulrrcnd.jmpTab.condition
-#define IC_JTLABELS(x) x->ulrrcnd.jmpTab.labels
-#define IC_INLINE(x) x->inlineAsm
-
-typedef struct iCode 
-{
-    unsigned int op ;              /* operation defined */
-    int key ;                      /* running key for this iCode */
-    int seq ;                      /* sequence number within routine */
-    short depth ;                  /* loop depth of this iCode */
-    short level ;                  /* scope level */
-    short block ;                  /* sequential block number */
-    unsigned nosupdate:1;          /* don't update spillocation with this */
-    unsigned generated:1;          /* code generated for this one */   
-    unsigned parmPush :1;          /* parameter push Vs spill push */
-    unsigned supportRtn:1;         /* will cause a call to a support routine */
-    unsigned regsSaved:1 ;         /* registers have been saved */
-    unsigned bankSaved:1 ;         /* register bank has been saved */
-    
-    struct iCode *next ;           /* next in chain */
-    struct iCode *prev ;           /* previous in chain */
-    set          *movedFrom;       /* if this iCode gets moved to another block */
-    bitVect *rlive ;               /* ranges that are live at this point */
-    int    defKey  ;               /* key for the operand being defined  */
-    bitVect *uses  ;               /* vector of key of used symbols      */
-    bitVect *rUsed ;               /* registers used by this instruction */
-    bitVect *rMask ;               /* registers in use during this instruction */
-    union {
-       struct {
-           operand *left      ;           /* left if any   */
-           operand *right     ;           /* right if any  */
-           operand *result    ;           /* result of this op */
-       } lrr ;
-
-       struct {
-           operand *condition ;           /* if this is a conditional */
-           symbol  *trueLabel ;           /* true for conditional     */
-           symbol  *falseLabel;           /* false for conditional    */
-       } cnd;
-
-       struct {
-           operand *condition ;           /* condition for the jump */
-           set     *labels    ;           /* ordered set of labels  */
-       } jmpTab ;
-
-    } ulrrcnd;
-
-    union {
-       symbol  *label ;           /* for a goto statement     */
-       value   *args  ;
-    } argLabel ;
+typedef struct operand
+  {
+    OPTYPE type;               /* type of operand */
+    unsigned int isaddr:1;     /* is an address   */
+    unsigned int isvolatile:1; /* is a volatile operand */
+    unsigned int isGlobal:1;   /* is a global operand */
+    unsigned int isPtr:1;      /* is assigned a pointer */
+    unsigned int isGptr:1;     /* is a generic pointer  */
+    unsigned int isParm:1;     /* is a parameter        */
+    unsigned int isLiteral:1;  /* operand is literal    */
+
+    unsigned key;
+    union
+      {
+       struct symbol *symOperand;      /* operand is of type symbol */
+       struct value *valOperand;       /* operand is of type value  */
+       struct sym_link *typeOperand;   /* operand is of type typechain */
+      }
+    operand;
+
+    bitVect *usesDefs;         /* which definitions are used by this */
+    struct asmop *aop;         /* asm op for this operand */
+  }
+operand;
+
+extern operand *validateOpType(operand                 *op, 
+                              const char       *macro,
+                              const char       *args,
+                              OPTYPE           type,
+                              const char       *file, 
+                              unsigned         line);
+
+#define OP_SYMBOL(op) validateOpType(op, "OP_SYMBOL", #op, SYMBOL, __FILE__, __LINE__)->operand.symOperand
+#define OP_VALUE(op)  validateOpType(op, "OP_VALUE", #op, VALUE, __FILE__, __LINE__)->operand.valOperand
+#define OP_SYM_TYPE(op)    validateOpType(op, "OP_SYM_TYPE", #op, SYMBOL, __FILE__, __LINE__)->operand.symOperand->type
+#define OP_SYM_ETYPE(op)   validateOpType(op, "OP_SYM_ETYPE", #op, SYMBOL, __FILE__, __LINE__)->operand.symOperand->etype
+#define SPIL_LOC(op)       validateOpType(op, "SPIL_LOC", #op, SYMBOL, __FILE__, __LINE__)->operand.symOperand->usl.spillLoc
+#define OP_LIVEFROM(op)    validateOpType(op, "OP_LIVEFROM", #op, SYMBOL, __FILE__, __LINE__)->operand.symOperand->liveFrom
+#define OP_LIVETO(op)      validateOpType(op, "OP_LIVETO", #op, SYMBOL, __FILE__, __LINE__)->operand.symOperand->liveTo
+#define OP_REQV(op)        validateOpType(op, "OP_REQV", #op, SYMBOL, __FILE__, __LINE__)->operand.symOperand->reqv
+
+/* definition for intermediate code */
+#define IC_RESULT(x) (x)->ulrrcnd.lrr.result
+#define IC_LEFT(x)   (x)->ulrrcnd.lrr.left
+#define IC_RIGHT(x)  (x)->ulrrcnd.lrr.right
+#define IC_COND(x)   (x)->ulrrcnd.cnd.condition
+#define IC_TRUE(x)   (x)->ulrrcnd.cnd.trueLabel
+#define IC_FALSE(x)  (x)->ulrrcnd.cnd.falseLabel
+#define IC_LABEL(x)  (x)->label
+#define IC_JTCOND(x) (x)->ulrrcnd.jmpTab.condition
+#define IC_JTLABELS(x) (x)->ulrrcnd.jmpTab.labels
+#define IC_INLINE(x) (x)->inlineAsm
+#define IC_ARRAYILIST(x) (x)->arrayInitList
+
+typedef struct iCode
+  {
+    unsigned int op;           /* operation defined */
+    int key;                   /* running key for this iCode */
+    int seq;                   /* sequence number within routine */
+    int seqPoint;              /* sequence point */
+    short depth;               /* loop depth of this iCode */
+    short level;               /* scope level */
+    short block;               /* sequential block number */
+    unsigned nosupdate:1;      /* don't update spillocation with this */
+    unsigned generated:1;      /* code generated for this one */
+    unsigned parmPush:1;       /* parameter push Vs spill push */
+    unsigned supportRtn:1;     /* will cause a call to a support routine */
+    unsigned regsSaved:1;      /* registers have been saved */
+    unsigned bankSaved:1;      /* register bank has been saved */
+    unsigned builtinSEND:1;     /* SEND for parameter of builtin function */
+
+    struct iCode *next;                /* next in chain */
+    struct iCode *prev;                /* previous in chain */
+    set *movedFrom;            /* if this iCode gets moved to another block */
+    bitVect *rlive;            /* ranges that are live at this point */
+    int defKey;                        /* key for the operand being defined  */
+    bitVect *uses;             /* vector of key of used symbols      */
+    bitVect *rUsed;            /* registers used by this instruction */
+    bitVect *rMask;            /* registers in use during this instruction */
+    union
+      {
+       struct
+         {
+           operand *left;      /* left if any   */
+           operand *right;     /* right if any  */
+           operand *result;    /* result of this op */
+         }
+       lrr;
+
+       struct
+         {
+           operand *condition; /* if this is a conditional */
+           symbol *trueLabel;  /* true for conditional     */
+           symbol *falseLabel; /* false for conditional    */
+         }
+       cnd;
+
+       struct
+         {
+           operand *condition; /* condition for the jump */
+           set *labels;        /* ordered set of labels  */
+         }
+       jmpTab;
+
+      }
+    ulrrcnd;
+
+    symbol *label;             /* for a goto statement     */
+
+    char *inlineAsm;           /* pointer to inline assembler code */
+    literalList *arrayInitList; /* point to array initializer list. */
+
+    int lineno;                        /* file & lineno for debug information */
+    char *filename;
     
-    char        *inlineAsm ;           /* pointer to inline assembler code */
-
-    int     lineno      ;           /* file & lineno for debug information */
-    char   *filename    ;         
-} iCode ;
+    int parmBytes;             /* if call/pcall, count of parameter bytes 
+                                  on stack */
+    int argreg;                        /* argument regno for SEND/RECEIVE */
+    int eBBlockNum;             /* belongs to which eBBlock */
+    char riu;                  /* after ralloc, the registers in use */
+  }
+iCode;
 
 /* various functions associated to iCode */
-typedef struct icodeFuncTable 
-{
-    int icode ;
-    char *printName ;
-    void (*iCodePrint)(FILE *,iCode *,char *) ;
-    iCode * (*iCodeCopy)(iCode *) ;
-} iCodeTable ;
+typedef struct icodeFuncTable
+  {
+    int icode;
+    char *printName;
+    void (*iCodePrint) (FILE *, iCode *, char *);
+    iCode *(*iCodeCopy) (iCode *);
+  }
+iCodeTable;
 
 /* useful macros */
 #define SKIP_IC2(x)  (x->op == GOTO     ||     \
@@ -184,8 +219,12 @@ typedef struct icodeFuncTable
                       x->op == IPOP     ||     \
                       x->op == JUMPTABLE ||    \
                       x->op == RECEIVE  ||     \
+                     x->op == ARRAYINIT ||    \
                      SKIP_IC1(x)||  \
-                     x->op == SEND         ) 
+                     x->op == SEND         )
+
+#define SKIP_IC3(x) (SKIP_IC2(x) ||    \
+                    x->op == JUMPTABLE )
 
 #define IS_CONDITIONAL(x) (x->op == EQ_OP || \
                           x->op == '<'   || \
@@ -236,49 +275,54 @@ typedef struct icodeFuncTable
 #define ASSIGNMENT_TO_SELF(ic) (!POINTER_SET(ic) && !POINTER_GET(ic) && \
                                ic->op == '=' && IC_RESULT(ic)->key == IC_RIGHT(ic)->key )
 
+#define IS_CAST_ICODE(ic) (ic && ic->op == CAST)
 #define SET_ISADDR(op,v) {op = operandFromOperand(op); op->isaddr = v;}
 #define SET_RESULT_RIGHT(ic) {SET_ISADDR(IC_RIGHT(ic),0); SET_ISADDR(IC_RESULT(ic),0);}
+#define IS_ASSIGN_ICODE(ic) (ASSIGNMENT(ic) && !POINTER_SET(ic))
 
-#define OP_DEFS(op) op->operand.symOperand->defs
-#define OP_USES(op) op->operand.symOperand->uses
+#define OP_DEFS(op) validateOpType(op, "OP_DEFS", #op, SYMBOL, __FILE__, __LINE__)->operand.symOperand->defs
+#define OP_USES(op) validateOpType(op, "OP_USES", #op, SYMBOL, __FILE__, __LINE__)->operand.symOperand->uses
 /*-----------------------------------------------------------------*/
 /* forward references for functions                                */
 /*-----------------------------------------------------------------*/
-iCode   *reverseiCChain     (      );
-bool     isOperandOnStack   (operand *);
-int      isOperandVolatile  (operand *,bool);
-int      isOperandGlobal    (operand *);
-void     printiCChain    ( iCode * , FILE *);
-operand *ast2iCode          ( ast *);
-operand *geniCodeCast       ( sym_link *, operand *,bool);
+iCode *reverseiCChain ();
+bool isOperandOnStack (operand *);
+int isOperandVolatile (operand *, bool);
+int isOperandGlobal (operand *);
+void printiCChain (iCode *, FILE *);
+operand *ast2iCode (ast *,int);
 operand *geniCodePtrPtrSubtract (operand *, operand *);
-void     initiCode          ();
-iCode   *iCodeFromAst   ( ast * );
-int      isiCodeEqual   ( iCode *,iCode *) ;
-int      isOperandEqual ( operand *, operand *);
-iCodeTable *getTableEntry (int  );
-int      isOperandLiteral (operand *);
-operand *operandOperation (operand *,operand *,int,sym_link *);
-double   operandLitValue ( operand * );
-operand *operandFromLit (float);
-operand *operandFromOperand(operand *);
-int      isParameterToCall (value *,operand *);
-iCode   *newiCodeLabelGoto (int , symbol *);
-symbol  *newiTemp(char *);
-symbol  *newiTempLabel (char *);
-symbol  *newiTempPreheaderLabel ();
-iCode   *newiCode (int, operand *, operand *);
-sym_link *operandType(operand *);
+void initiCode ();
+iCode *iCodeFromAst (ast *);
+int isiCodeEqual (iCode *, iCode *);
+int isOperandEqual (operand *, operand *);
+iCodeTable *getTableEntry (int);
+int isOperandLiteral (operand *);
+operand *operandOperation (operand *, operand *, int, sym_link *);
+double operandLitValue (operand *);
+operand *operandFromLit (double);
+operand *operandFromOperand (operand *);
+int isParameterToCall (value *, operand *);
+iCode *newiCodeLabelGoto (int, symbol *);
+symbol *newiTemp (char *);
+symbol *newiTempLabel (char *);
+symbol *newiTempPreheaderLabel ();
+iCode *newiCode (int, operand *, operand *);
+sym_link *operandType (operand *);
 operand *operandFromValue (value *);
-operand *operandFromSymbol(symbol *);
-sym_link *aggrToPtr ( sym_link *, bool);
-int      piCode (void *, FILE * );
-int      printOperand (operand *,FILE *);
-void     setOperandType (operand *, sym_link *);
-bool     isOperandInFarSpace (operand *);
-operand *opFromOpWithDU (operand *,bitVect *,bitVect *);
-iCode   *copyiCode (iCode *);
-operand *newiTempFromOp( operand *);
+operand *operandFromSymbol (symbol *);
+operand *operandFromLink (sym_link *);
+sym_link *aggrToPtr (sym_link *, bool);
+int piCode (void *, FILE *);
+int printOperand (operand *, FILE *);
+void setOperandType (operand *, sym_link *);
+bool isOperandInFarSpace (operand *);
+bool isOperandInDirSpace (operand *);
+bool isOperandInCodeSpace (operand *);
+operand *opFromOpWithDU (operand *, bitVect *, bitVect *);
+iCode *copyiCode (iCode *);
+operand *newiTempFromOp (operand *);
+iCode *getBuiltinParms (iCode *,int *, operand **);
 /*-----------------------------------------------------------------*/
 /* declaration of exported variables                               */
 /*-----------------------------------------------------------------*/