}
+/*-----------------------------------------------------------------*/
+/* 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 */
/*-----------------------------------------------------------------*/
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 *);
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 */
/*-----------------------------------------------------------------*/
}
/* 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
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 */
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 == '>' || \
operand *opFromOpWithDU (operand *, bitVect *, bitVect *);
iCode *copyiCode (iCode *);
operand *newiTempFromOp (operand *);
+iCode *getBuiltinParms (iCode *,int *, operand **);
/*-----------------------------------------------------------------*/
/* declaration of exported variables */
/*-----------------------------------------------------------------*/
initSymt ();
initiCode ();
initCSupport ();
+ initBuiltIns();
initPeepHole ();
if (options.verbose)
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))
}
}
+/*-----------------------------------------------------------------*/
+/* 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 */
/*-----------------------------------------------------------------*/
}
}
}
+
+/*-----------------------------------------------------------------*/
+/* 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;
+ }
+}
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 */
#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) && \
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);
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 *);
#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
{
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;