Implementaion of builtin functions
authorsandeep <sandeep@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 18 Nov 2001 18:56:30 +0000 (18:56 +0000)
committersandeep <sandeep@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 18 Nov 2001 18:56:30 +0000 (18:56 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1616 4a8a32a2-be11-0410-ad9d-d568d2c75423

src/SDCCast.c
src/SDCCast.h
src/SDCCicode.c
src/SDCCicode.h
src/SDCCmain.c
src/SDCCsymt.c
src/SDCCsymt.h
src/port.h

index 6ef760961a1a52d082bbe1ee85d401221cabcb27..dc1c8f9494c3672f38ec4fefc5103c66f0a4541b 100644 (file)
@@ -574,6 +574,46 @@ funcOfType (char *name, sym_link * type, sym_link * argType,
 
 }
 
+/*-----------------------------------------------------------------*/
+/* funcOfTypeVarg :- function of type with name and argtype        */
+/*-----------------------------------------------------------------*/
+symbol *
+funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
+{
+  
+    symbol *sym;
+    int i ;
+    /* create the symbol */
+    sym = newSymbol (name, 0);
+    
+    /* setup return value */
+    sym->type = newLink ();
+    DCL_TYPE (sym->type) = FUNCTION;
+    sym->type->next = typeFromStr(rtype);
+    sym->etype = getSpec (sym->type);
+    
+    /* if arguments required */
+    if (nArgs) {
+       value *args;
+       args = FUNC_ARGS(sym->type) = newValue ();
+       
+       for ( i = 0 ; i < nArgs ; i++ ) {
+           args->type = typeFromStr(atypes[i]);
+           args->etype = getSpec (args->type);
+           SPEC_EXTR(args->etype)=1;
+           if ((i + 1) == nArgs) break;
+           args = args->next = newValue ();
+       }
+    }
+    
+    /* save it */
+    addSymChain (sym);
+    sym->cdef = 1;
+    allocVariables (sym);
+    return sym;
+
+}
+
 /*-----------------------------------------------------------------*/
 /* reverseParms - will reverse a parameter tree                    */
 /*-----------------------------------------------------------------*/
index 3e5f763231dd49cd9c1f7c316b97c5e0a8f4b29c..1504f69e54eb2ae32562aa02e989d2e4dbf00d75 100644 (file)
@@ -199,6 +199,7 @@ ast *createFor (symbol *, symbol *, symbol *, symbol *, ast *, ast *, ast *, ast
 void eval2icode (ast *);
 value *constExprValue (ast *, int);
 symbol *funcOfType (char *, sym_link *, sym_link *, int, int);
+symbol * funcOfTypeVarg (char *, char * , int , char **);
 ast *initAggregates (symbol *, initList *, ast *);
 bool hasSEFcalls (ast *);
 void addSymToBlock (symbol *, ast *);
index 7a9cdd7fea9d394794b8786483f169eb6dd90f81..59bcf886fc8610efcaf5f2ff3a8c2891dbc26187 100644 (file)
@@ -916,6 +916,31 @@ operandLitValue (operand * op)
   return floatFromVal (op->operand.valOperand);
 }
 
+/*-----------------------------------------------------------------*/
+/* getBuiltInParms - returns parameters to a builtin functions     */
+/*-----------------------------------------------------------------*/
+iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
+{
+    sym_link *ftype;
+
+    *pcount = 0;
+    /* builtin functions uses only SEND for parameters */
+    while (ic->op != CALL) {
+       assert(ic->op == SEND && ic->builtinSEND);
+       ic->generated = 1;    /* mark the icode as generated */
+       parms[*pcount] = IC_LEFT(ic);
+       ic = ic->next;
+       (*pcount)++;
+    }
+    
+    ic->generated = 1;
+    /* make sure this is a builtin function call */
+    assert(IS_SYMOP(IC_LEFT(ic)));
+    ftype = operandType(IC_LEFT(ic));
+    assert(IFFUNC_ISBUILTIN(ftype));
+    return ic;
+}
+
 /*-----------------------------------------------------------------*/
 /* operandOperation - perforoms operations on operands             */
 /*-----------------------------------------------------------------*/
@@ -2732,9 +2757,11 @@ geniCodeParms (ast * parms, value *argVals, int *stack,
     }
 
   /* if register parm then make it a send */
-  if (IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type))
+  if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
+      IFFUNC_ISBUILTIN(func->type))
     {
       ic = newiCode (SEND, pval, NULL);
+      ic->builtinSEND = FUNC_ISBUILTIN(func->type);
       ADDTOCHAIN (ic);
     }
   else
index aca2f5ce7afa49457e44642813e1ae0ec42d8c84..bd467419e492003d2ff04724826f554e2ad7b856 100644 (file)
@@ -130,6 +130,7 @@ typedef struct iCode
     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 */
@@ -215,6 +216,9 @@ iCodeTable;
                      SKIP_IC1(x)||  \
                      x->op == SEND         )
 
+#define SKIP_IC3(x) (SKIP_IC2(x) ||    \
+                    x->op == JUMPTABLE )
+
 #define IS_CONDITIONAL(x) (x->op == EQ_OP || \
                           x->op == '<'   || \
                           x->op == '>'   || \
@@ -309,6 +313,7 @@ bool isOperandInFarSpace (operand *);
 operand *opFromOpWithDU (operand *, bitVect *, bitVect *);
 iCode *copyiCode (iCode *);
 operand *newiTempFromOp (operand *);
+iCode *getBuiltinParms (iCode *,int *, operand **);
 /*-----------------------------------------------------------------*/
 /* declaration of exported variables                               */
 /*-----------------------------------------------------------------*/
index 371d33b7e0bb4a9981113750eae1bbe42b0f96ea..2c1363c054db0a76264caca23b1a48a7fae7e571 100644 (file)
@@ -1527,6 +1527,7 @@ main (int argc, char **argv, char **envp)
       initSymt ();
       initiCode ();
       initCSupport ();
+      initBuiltIns();
       initPeepHole ();
 
       if (options.verbose)
index c6cd281a0e6c778db6792c74ba383fa2d00ff002..ec3386e24631b84aabe8d8fa5954275a2bb19d53 100644 (file)
@@ -1943,7 +1943,7 @@ printTypeChain (sym_link * start, FILE * of)
          switch (DCL_TYPE (type))
            {
            case FUNCTION:
-             fprintf (of, "function ");
+             fprintf (of, "function %s", (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "));
              break;
            case GPOINTER:
              if (DCL_PTR_CONST (type))
@@ -2327,6 +2327,100 @@ _mangleFunctionName(char *in)
     }
 }
 
+/*-----------------------------------------------------------------*/
+/* typeFromStr - create a typechain from an encoded string         */
+/* basic types -       'c' - char                                 */
+/*                     's' - short                                */
+/*                     'i' - int                                  */
+/*                     'l' - long                                 */
+/*                      'f' - float                               */
+/*                      'v' - void                                */
+/*                      '*' - pointer - default (GPOINTER)        */
+/* modifiers -          'u' - unsigned                             */
+/* pointer modifiers -  'g' - generic                              */
+/*                      'x' - xdata                                */
+/*                      'p' - code                                 */
+/*                      'd' - data                                 */                     
+/* examples : "ig*" - generic int *                               */
+/*            "cx*" - char xdata *                                 */
+/*            "ui" -  unsigned int                                 */
+/*-----------------------------------------------------------------*/
+sym_link *typeFromStr (char *s)
+{
+    sym_link *r = newLink();
+    int usign = 0;
+
+    do {
+       sym_link *nr;
+       switch (*s) {
+       case 'u' : 
+           usign = 1;
+           s++;
+           continue ;
+           break ;
+       case 'c':
+           r->class = SPECIFIER;
+           SPEC_NOUN(r) = V_CHAR;
+           break;
+       case 's':
+       case 'i':
+           r->class = SPECIFIER;
+           SPEC_NOUN(r) = V_INT;
+           break;
+       case 'l':
+           r->class = SPECIFIER;
+           SPEC_NOUN(r) = V_INT;
+           SPEC_LONG(r) = 1;
+           break;
+       case 'f':
+           r->class = SPECIFIER;
+           SPEC_NOUN(r) = V_FLOAT;
+           break;
+       case 'v':
+           r->class = SPECIFIER;
+           SPEC_NOUN(r) = V_VOID;
+           break;
+       case '*':
+           DCL_TYPE(r) = GPOINTER;
+           break;
+       case 'g':
+       case 'x':
+       case 'p':
+       case 'd':
+           assert(*(s+1)=='*');
+           nr = newLink();
+           nr->next = r;
+           r = nr;
+           r->class = DECLARATOR ;
+           switch (*s) {
+           case 'g':
+               DCL_TYPE(r) = GPOINTER;
+               break;
+           case 'x':
+               DCL_TYPE(r) = FPOINTER;
+               break;
+           case 'p':
+               DCL_TYPE(r) = CPOINTER;
+               break;
+           case 'd':
+               DCL_TYPE(r) = POINTER;
+               break;
+           }
+           s++;
+           break;
+       default:
+           werror(E_INTERNAL_ERROR,"typeFromStr");
+           break;
+       }
+       if (IS_SPEC(r) && usign) {
+           SPEC_USIGN(r) = 1;
+           usign = 0;
+       }
+       s++;
+    } while (*s);
+    return r;
+}
+
 /*-----------------------------------------------------------------*/
 /* initCSupport - create functions for C support routines          */
 /*-----------------------------------------------------------------*/
@@ -2444,3 +2538,20 @@ initCSupport ()
        }
     }
 }
+
+/*-----------------------------------------------------------------*/
+/* initBuiltIns - create prototypes for builtin functions          */
+/*-----------------------------------------------------------------*/
+void initBuiltIns()
+{
+    int i;
+    symbol *sym;
+
+    if (!port->builtintable) return ;
+
+    for (i = 0 ; port->builtintable[i].name ; i++) {
+       sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
+                            port->builtintable[i].nParms,port->builtintable[i].parm_types);
+       FUNC_ISBUILTIN(sym->type) = 1;
+    }
+}
index 9b72775c22a91f24107be7dd842baf0cb09a3be4..bf0544bcb5150ea2c3c7e9b341af13ead7d2d13a 100644 (file)
@@ -185,6 +185,7 @@ typedef struct sym_link
       unsigned rbank:1;                /* seperate register bank     */
       unsigned intno;          /* 1=Interrupt svc routine    */
       unsigned regbank;                /* register bank 2b used      */
+      unsigned builtin;                /* is a builtin function      */
     } funcAttrs;
 
     struct sym_link *next;     /* next element on the chain  */
@@ -313,6 +314,8 @@ symbol;
 #define IFFUNC_BANKED(x) (IS_FUNC(x) && FUNC_BANKED(x))
 #define FUNC_ISCRITICAL(x) (x->funcAttrs.critical)
 #define IFFUNC_ISCRITICAL(x) (IS_FUNC(x) && FUNC_ISCRITICAL(x))
+#define FUNC_ISBUILTIN(x) (x->funcAttrs.builtin)
+#define IFFUNC_ISBUILTIN(x) (IS_FUNC(x) && FUNC_ISBUILTIN(x))
 
 // jwk: I am not sure about this
 #define IFFUNC_ISBANKEDCALL(x) (!IFFUNC_NONBANKED(x) && \
@@ -476,6 +479,7 @@ int isSymbolEqual (symbol *, symbol *);
 int powof2 (unsigned long);
 void printTypeChain (sym_link *, FILE *);
 void initCSupport ();
+void initBuiltIns ();
 void pointerTypes (sym_link *, sym_link *);
 void cdbTypeInfo (sym_link *, FILE *);
 void cdbSymbol (symbol *, FILE *, int, int);
@@ -489,6 +493,8 @@ void *findSymWithLevel (bucket **, struct symbol *);
 void *findSymWithBlock (bucket **, struct symbol *, int);
 void changePointer (symbol * sym);
 void checkTypeSanity(sym_link *etype, char *name);
+sym_link *typeFromStr (char *) ;
+
 
 extern char *nounName(sym_link *); /* noun strings */
 extern void printFromToType (sym_link *, sym_link *);
index 38aee26d50ed4679a60273a219c397032bb4d0e9..2e1bab4b8a4bf1da40a594215b3167862532c185 100644 (file)
 #define TARGET_IS_I186 (port->id==TARGET_ID_I186)
 #define TARGET_IS_TCLS900H (port->id==TARGET_ID_TCLS900H)
 
+#define MAX_BUILTIN_ARGS       16
+/* definition of builtin functions */
+typedef struct builtins
+{
+    char *name ;               /* name of builtin function */
+    char *rtype;               /* return type as string : see typefromStr */
+    int  nParms;               /* number of parms : max 8 */
+    char *parm_types[MAX_BUILTIN_ARGS]; /* each parm type as string : see typeFromStr */
+} builtins ;
+
 /* Processor specific names */
 typedef struct
   {
@@ -228,6 +238,7 @@ typedef struct
     bool arrayInitializerSuppported;  
     
     bool (*cseOk) (iCode *ic, iCode *pdic);
+    builtins *builtintable;    /* table of builtin functions */
 #define PORT_MAGIC 0xAC32
 /** Used at runtime to detect if this structure has been completly filled in. */
     int magic;