Portability In C
by James Metzger and William Wright

Listing One
(a)
double sharc_dtime();  /* version of dtime() for the SHARC DSP */ 

(b)
#ifdef SHARC
 millis = sharc_dtime();
#else
 millis = dtime();
#endif

(c)
gcc -DSHARC main.c

(d)
#ifdef SHARC
  millis = sharc_dtime();
#else if defined(VxWorks) && defined(X86)
  millis = read_386_counter();
#else if defined(VxWorks) && defined(MC68000)
  millis = read_moto_counter();
#else if defined(WIN_32)
  millis = read_windows_timer();
#endif


Listing Two
(a)
#define VxWorks /* Target is VxWorks OS, any processor      */
#define X86     /* Processor is Intel 386 or higher, any OS */
#define unix    /* Any UNIX, any processor                  */
#define linux   /* linux UNIX, any processor                */

(b)
#if defined(VxWorks) && defined(X86)
/* Pentium and VxWorks-specific code */
#endif

(c)
% gcc -v main.c
gcc version 2.8.1
 /usr/local/lib/gcc-lib/sparc-sun-solaris2.6/2.8.1/cpp -lang-c -v 
      -undef -D__GNUC__=2 -D__GNUC_MINOR__=8 -Dsparc -Dsun -Dunix 
      -D__svr4__ -D__SVR4 -D__sparc__ -D__sun__ -D__unix__ -D__svr4__ 
      -D__SVR4 -D__sparc -D__sun -D__unix -D__GCC_NEW_VARARGS__ main.c

(d)
C:\> g21k -v main.c
gcc version rel3.3 21k/SHARC 3.3:
c:\adi_dsp\21k\etc\cpp.exe -lang-c -v -undef -D__GNUC__=2 -D__ADSP21000__ 
    -DADSP21000 -D__21K__ -D__ADSP21020__ 
    -DADSP21020 -D__DOUBLES_ARE_FLOATS__ main.c

(e)
#ifdef NEW
  millis = new_dtime();
#if !defined(BOB) || defined(SHARC)
  millis += bobs_counter();
#else if defined(VxWorks) && !defined(WIN_32)
  millis = who_knows_what();
#endif /* what! */
#if defined(WIN_32)
  millis = read_windows_timer();
#endif
#endif


Listing Three
(a)
void vsmul(float *invec, int j, float scalar, 
float *outvec, int k, int n);
{
for(i=0;i<n;i++)
        outvec[i*k] = scalar*invec[i*j];
}

(b)
/* SKY Standard Math Library */
vsmul(float *invec, int j, float scalar, 
float *outvec, int k, int n);

/* SKYvec library does not support strides and uses a global */
/* variable for the vector length */
_skyvec = n;
v$_rsvt0(float scalar, float *invec, float *outvec);

/* Wideband Computers Inc (SHARC) */
vsmul(float *invec, int j, float scalar, 
float *outvec, int k, int n);

/* Alacron i860 */
vsmul(float *invec, int j, float scalar, 
float *outvec, int k, int n);

/* Alacron SHARC(passes scalar by reference)  */
vsmul(float *invec, int j, float *scalar, 
float *outvec, int k, int n);

/* Intel Native Signal Processing (NSP)for Pentium   */
/* Operation done in place. Does not support stride  */
nspsbMpy1(float scalar, float *outvec, int n);}

/* Mercury Computers(passes scalar by reference) */
vsmul(float *invec, int j, float *scalar, 
float *outvec, int k, int n);

(c)
#if defined(SKY)

#include <mathlib.h>
#endif /* SKY */

#if defined(WIN32)
#define nsp_UsesAll
#include <nsp.h>
#endif /* WIN32 */
  /* etc */
my_processing_module()
{
  /* code */
#ifdef SKY
    /* other vector calls */
    scalar = 2.0;
vsmul(invec, 1, scalar, outvec, 1, n);
/* even more vector calls */
#endif /* SKY */

#if defined(WIN32)
    /* previous vector calls */
    scalar = 2.0;
    nspsbCopy(invec,outvec,n); 
nspsbMpy1(scalar,outvec,n);
/* subsequent vector calls */
#endif /* WIN32 */
    /* other architectures, etc. */
}

(d)
vsmul(float *invec, int j, float scalar, float *outvec, int k, int n);

(e)
vsmul_sys(float *invec, int j, float scalar, float *outvec, int k, int n);

(f)
#include<myvec.h>
my_processing_module()
{
vsmul_sys(invec, j, scalar, outvec, k, n);
}

(g)
#if defined(SKY)
#include <veclib.h>
#define vsmul_sys vsmul
#endif /* SKY */

#if defined(WIN32)
#define nsp_UsesAll
#include <nsp.h>
#define vassrt(i,j,k) assert(i==1 && j==1 && k==1)
#define vsmul_sys(a,i,b,c,k,n) \
{vassrt(i,1,k); nspsbCopy(a,c,n); nspsbMpy1(b,c,n);}
#endif /* WIN32 */

Listing Four 
(a)
#define vsmul_sys(a,i,b,c,k,n) \
{vassrt(i,1,k); nspsbCopy(a,c,n); nspsbMpy1(b,c,n);}

(b)
#include <myvec.h>
my_processing_module()
{
    if(scalar != 0.0)
vsmul_sys(invec, j, scalar, outvec, k, n);
}

(c)
#include <myvec.h>
my_processing_module()
{
    if(scalar != 0.0)
        vassrt(i,1,k); 
nspsbCopy(invec,outvec,n); /* wrong */
nspsbMpy1(scalar,outvec,n); /* wrong */
}
(d)
n=10;
vsmul_sys(invec, j, scalar, outvec, k, n++);
/* Now n equals 12 for the WIN32 target!!!!  */

(e)
#define vsmul_sys(a,i,b,c,k,n)  vecscalmul(b,a,i,c,k,n)


Listing Five
#include "dtime.h"
#include <21020.h>
double dtime() /* no longer called "sharc_dtime()" */ 
{
  unsigned long stimer;
  asm volatile("%0=TCOUNT;": "=d"(stimer));
  asm volatile("BIT CLR MODE2 32;");
  asm volatile("TPERIOD=0xFFFFFFFF;TCOUNT=0xFFFFFFFF;" );
  asm volatile("BIT SET MODE2 32;" );
  return (0xFFFFFFFF - stimer) / 40000.0;
}

Listing Six
(a)
if (probe_for_clock())
  millis = high_res_time();
else
  millis = sharc_dtime();

(b)
#include "dtime.h"
double (*dtime)() = 0;
void initialize() 
{
  extern double high_res_time();
  extern double sharc_dtime();
  if (probe_for_clock())
    dtime = high_res_time;
  else
    dtime = sharc_dtime;
}



4

