divert(-1) dnl ************************ start of Cexec file ************************* dnl (c)INRIA 1997aug26 contact: syndex-support@inria.fr dnl SynDEx v4.3 include file for C define(`Cexec')dnl marks that this file has been included. dnl ************************ comments ************************* dnl comment{comments with balanced curly braces}comment define(`comment_', `changequote({,}){/* $1 */}changequote') define(`comment', `pushdef(`comment',`changequote)`'popdef(`comment')')changequote({,})comment_(') dnl Use this defining macro to generate a trace in the output: dnl define(`def', `define(`$1', dnl /* changequote({,}){`$}{0($}{*)'}changequote */ dnl `$2')') dnl Use this one if no trace is wanted in the output: define(`def', `define(`$1', `$2')') dnl processor_(name) ; place holder for future extensions def(`processor_', `undivert') dnl insert here eventual diverted I/O support dnl ******************** Memory allocation ******************** dnl Data buffers for temporary signals, delays, windows and constants, dnl are declared as global variables. dnl -------------------- allocate ------------------- dnl logical_(label,items) ; allocate items booleans def(`logical_', `int $1[$2];') dnl integer_(label,items) ; allocate items integers def(`integer_', `int $1[$2];') dnl real_(label,items) ; allocate items reals def(`real_', `float $1[$2];') dnl dpreal_(label,items) ; allocate items reals def(`dpreal_', `double $1[$2];') dnl -------------------- reallocate ------------------- dnl cell_alias_(newlabel,oldlabel,offset) ; newlabel=oldlabel+offset define(`cell_alias_', `define(`$1', `($2+$3)')') dnl logical_alias_(newlabel,oldlabel,offset) ; newlabel=oldlabel+offset def(`logical_alias_', `cell_alias_($@)') dnl integer_alias_(newlabel,oldlabel,offset) ; newlabel=oldlabel+offset def(`integer_alias_', `cell_alias_($@)') dnl real_alias_(newlable,oldlabel,offset) ; newlabel=oldlabel+offset def(`real_alias_', `cell_alias_($@)') dnl dpreal_alias_(newlable,oldlabel,offset) ; newlabel=oldlabel+offset def(`dpreal_alias_', `cell_alias_($@)') dnl -------------------- initialize ------------------- dnl cell_ini_(value,label,offset {,repeat,step}[,repeat]) ; initialize an array dnl iteration repeat and step are 1 by default. define(`cell_ini_', `ifelse($#,2,`$2[0]=$1;', $#,3,`$2[$3]=$1;', `{int i=$3; pushdef(`cell_1_ini_', `$2[i]=$1; i+=$'`1;') cell__ini_(shift(shift(shift($@))))popdef(`cell_1_ini_') }')') define(`cell__ini_', `{int n=$1; while(n--){ ifelse($#,1, `cell_1_ini_(1)', $#,2, `cell_1_ini_($2)', `cell__ini_(shift(shift($@))) i+=eval($2-$3ifelse($#,3,,*$4));')}}') dnl logical_ini_(label,offset,value, iter...) ; initialize an array of booleans define(`true', `1') define(`false', `0') def(`logical_ini_', `cell_ini_($@)') dnl integer_ini_(label,offset,value, iter...) ; initialize an array of integers def(`integer_ini_', `cell_ini_($@)') dnl real_ini_(label,offset,value, iter...) ; initialize an array of reals def(`real_ini_', `cell_ini_($@)') dnl dpreal_ini_(label,offset,value, iter...) ; initialize an array of dpreals def(`dpreal_ini_', `cell_ini_($@)') dnl -------------------- copy ------------------- dnl cell_copy_(dstlabel,scelabel,items) ; copy an array of cells define(`cell_copy_', `ifelse(eval($3==1),1, `$1[0]=$2[0];', `{ int i=$3; while(i--) $1[i]=$2[i]; }')') dnl logical_copy_(dstlabel,scelabel,items) def(`logical_copy_', `cell_copy_($@)') dnl integer_copy_(dstlabel,scelabel,items) def(`integer_copy_', `cell_copy_($@)') dnl real_copy_(dstlabel,scelabel,items) def(`real_copy_', `cell_copy_($@)') dnl dpreal_copy_(dstlabel,scelabel,items) def(`dpreal_copy_', `cell_copy_($@)') dnl -------------------- slidding windows ------------------- dnl Slidding windows: samples array, oldest item first, newest last. dnl Update: items-1 first items are "left"-shifted one item in memory, dnl before the last item is updated (not here). dnl Each item may be an array of itemsize elements of the basic type. dnl | 1 | 2 | 3 |...|n-1| n | before dnl | 2 | 3 | 4 |...| n | n | after dnl ^to ^fr <--->itemsize dnl cell_window_(itemsize,items,base) def(`cell_window_', `dnl dnl memcpy($3, $3+$1, eval(($2-1)*$1)*sizeof($3[0])); dnl memcpy is not garanteed to work properly in this case dnl because the source and destination memory areas are overlapping { int i; for(i=0; i res[0] = my_fun(arg1,arg2[0]); define(`Ccall_', `ifelse($1,void,,`Cargs_($1) = ')dnl `$2('ifelse($#,2,,`Cargs_(shift(shift($@)))')`);'') define(`Cargs_', `ifelse(index($1,`*'),-1, `substr($1,incr(index($1,` ')))[0]', `substr($1,incr(index($1,`*')))')`'ifelse($#,1,, `,Cargs_(shift($@))')') dnl printf_(`hello %d', int x) define(`printf_', `Ccall_(void,`printf',char*"$1\n",shift($@))') dnl -------------------------------------------------- dnl old versions as described in research report dnl define(`args_', `') dnl define(`addarg_', `define(`args_', $1`'ifelse(args_,,,`;args_'))') dnl define(`arg_addr_', `addarg_(`$1')') dnl define(`arg_logical_' `addarg_(`$1[0]')') dnl define(`arg_integer_', `addarg_(`$1[0]')') dnl define(`arg_real_', `addarg_(`$1[0]')') dnl define(`arg_dpreal_', `addarg_(`$1[0]')') dnl define(`call_args_', ``$1'(patsubst(args_,`;',`,'));define(`args_',`')') dnl dnl printf_(`string') dnl define(`printf_', `addarg_("$1\n")call_args_(`printf')') dnl ******************** Chronometric functions ******************** dnl assumed declarations: dnl tree_up_(x) ; link connected to parent, -1 (=none) for root processor dnl tree_dn_(y) ; link connected to descendant dnl tree_dn_(z) ; link connected to descendant dnl ... dnl tree_dn_end() ; marks end of links list dnl tree_up_(i) ; link connected to parent, don't care for root processor def(`tree_up_', `int tree__[]={$1, dnl ifelse($1,-1,define(`SynDExRoot'))dnl') dnl tree_dn_(i) ; link connected to descendant def(`tree_dn_', `$1, dnl') dnl tree_dn_end() ; marks end of descendant list def(`tree_dn_end', `-1};') define(`Chronometric_functions_', `` extern int GetTime(void); /* return system clock current time (microseconds) */ extern void SendInt(int commport, int value); /* send int to commport */ extern int RecvInt(int commport); /* receive int from commport */'') define(`Chronometric_functions_', `` /* Chronometric functions */ #include int GetTime(void) { /* return system clock current time (microseconds) */ struct timeval t; gettimeofday(&t,(void*)0); return (int)(1000000*t.tv_sec+t.tv_usec); } void SendInt(int id, int value) {/* send int to procr id */ int n = htonl(value); write(sd[id], &n, 4); } int RecvInt(int id) { /* receive int from procr id */ int n; read(sd[id], &n, 4); return ntohl(n); }'') dnl Chronos_(size) ; size=number of (label,date) records def(`Chronos_', `` /* Chronometric data */ typedef struct{int label, date;} Chrono_record_; #define Chrono_size_ $1*3 Chrono_record_ Chrono_base_[Chrono_size_]={}; /* zeroed by ANSI C */ Chrono_record_ *Chrono_current_=Chrono_base_; 'Chronometric_functions_()` void Chrono_lap_(int label) /* record current date with label */ { Chrono_current_->label=label; Chrono_current_->date=GetTime(); if(++Chrono_current_==Chrono_base_+Chrono_size_) Chrono_current_=Chrono_base_; }' ifdef(`SynDExRoot', `` #include #define Chrono_overhead_ 19 void Chrono_store_(Chrono_record_ *p) { /* store one chronometric record */ static int date=0; /* display label, date, delta */ if(date==0) printf("label=%d date=%d dt=date-datePrec-%d (microseconds)\n", p->label, p->date, Chrono_overhead_); else printf("%d %d %d\n", p->label, p->date, p->date-date-Chrono_overhead_); date=p->date; }'', `` void Chrono_store_(Chrono_record_ *p) { /* forward one chronometric record */ SendInt(tree__[0], p->label); SendInt(tree__[0], p->date); /* RecvInt(tree__[0]); /* synchro */ }'')') dnl Chrono_ini_() def(`Chrono_ini_', `') dnl Chrono_lap_(label) ; record label with current date def(`Chrono_lap_', ``$0($1);'') dnl Chrono_end_() ; dump Chronos def(`Chrono_end_', `` { /* dump all chronometric records */ Chrono_record_* p=Chrono_current_; int* descendant=tree__;'ifdef(`SynDExRoot',, ` int dt, t; RecvInt(tree__[0]); /* wait parent ready for clock sync */ t=GetTime(); SendInt(tree__[0], t); dt=RecvInt(tree__[0]); dt+=(t-GetTime())/2;')` if(p->label != 0) do Chrono_store_(p); while(++p != Chrono_base_+Chrono_size_); for(p=Chrono_base_; p!=Chrono_current_; p++) Chrono_store_(p); while(*++descendant != -1) { SendInt(*descendant, 0); /* signal ready for clock sync */ p->date=RecvInt(*descendant); /* wait for descendant clock */ SendInt(*descendant, p->date-GetTime()); /* return delta */ while((p->label=RecvInt(*descendant)) != 0) { p->date=RecvInt(*descendant)'ifdef(`SynDExRoot',,`+dt')`; Chrono_store_(p); /* SendInt(*descendant, 0); /* synchro */ } }'ifdef(`SynDExRoot',,` SendInt(tree__[0],0); /* dump end marker */')` }'') dnl ******************** User operations ******************** dnl The following sets of macroes may be extended at the user's convenience. dnl Other user macro-operations must be given in the "application.inc" file. dnl ------------------- ALU operations ------------------ dnl logNot(s1,dst) ; dst=!s1 def(`logNot', `$2[0]=!$1[0];') dnl logAnd(s1,s2,dst) ; dst=s1&s2 def(`logAnd', `$3[0]=$1[0]&$2[0];') dnl logOr(s1,s2,dst) ; dst=s1|s2 def(`logOr', `$3[0]=$1[0]|$2[0];') dnl intEqu(s1,s2,dst) ; dst=s1==s2 def(`intEqu', `$3[0]=$1[0]==$2[0];') def(`realEqu', `intEqu($*)') dnl intNeq(s1,s2,dst) ; dst=s1!=s2 def(`intNeq', `$3[0]=$1[0]!=$2[0];') def(`realNeq', `intNeq($*)') dnl intGeq(s1,s2,dst) ; dst=s1>=s2 def(`intGeq', `$3[0]=$1[0]>=$2[0];') def(`realGeq', `intGeq($*)') dnl intNge(s1,s2,dst) ; dst=s1