From 1a01e92b433e6a5bc464a5aae4c3d3696db559d0 Mon Sep 17 00:00:00 2001 From: sandeep Date: Sun, 18 Nov 2001 18:56:30 +0000 Subject: [PATCH] Implementaion of builtin functions git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1616 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- src/SDCCast.c | 40 +++++++++++++++++ src/SDCCast.h | 1 + src/SDCCicode.c | 29 ++++++++++++- src/SDCCicode.h | 5 +++ src/SDCCmain.c | 1 + src/SDCCsymt.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++- src/SDCCsymt.h | 6 +++ src/port.h | 11 +++++ 8 files changed, 204 insertions(+), 2 deletions(-) diff --git a/src/SDCCast.c b/src/SDCCast.c index 6ef76096..dc1c8f94 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -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 */ /*-----------------------------------------------------------------*/ diff --git a/src/SDCCast.h b/src/SDCCast.h index 3e5f7632..1504f69e 100644 --- a/src/SDCCast.h +++ b/src/SDCCast.h @@ -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 *); diff --git a/src/SDCCicode.c b/src/SDCCicode.c index 7a9cdd7f..59bcf886 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -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 diff --git a/src/SDCCicode.h b/src/SDCCicode.h index aca2f5ce..bd467419 100644 --- a/src/SDCCicode.h +++ b/src/SDCCicode.h @@ -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 */ /*-----------------------------------------------------------------*/ diff --git a/src/SDCCmain.c b/src/SDCCmain.c index 371d33b7..2c1363c0 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -1527,6 +1527,7 @@ main (int argc, char **argv, char **envp) initSymt (); initiCode (); initCSupport (); + initBuiltIns(); initPeepHole (); if (options.verbose) diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index c6cd281a..ec3386e2 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -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; + } +} diff --git a/src/SDCCsymt.h b/src/SDCCsymt.h index 9b72775c..bf0544bc 100644 --- a/src/SDCCsymt.h +++ b/src/SDCCsymt.h @@ -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 *); diff --git a/src/port.h b/src/port.h index 38aee26d..2e1bab4b 100644 --- a/src/port.h +++ b/src/port.h @@ -29,6 +29,16 @@ #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; -- 2.30.2