Go to the first, previous, next, last section, table of contents.

I/O for specific target architectures

Before you can use the Cygnus Developer's Kit to build your programs for IDT boards, you need a C library and C run-time initialization code. Unless you already have suitable libraries of your own, you must integrate the Cygnus C libraries with low-level code supplied by IDT. This low-level code initializes the C run-time environment, and describes the hardware interface to the Cygnus C libraries.

To begin with, make sure you have the following C and assembly source files from IDT:

C source files:
drv_8254.c         sys.c           
idt_int_hand.c     syscalls.c      
idtfpip.c          timer_int_hand.c
sbrk.c

C header files:
dpac.h             idtio.h         
excepthdr.h        idtmon.h        
fpip.h             iregdef.h       
i8254.h            saunder.h       
idt_entrypt.h      setjmp.h        
idtcpu.h        

Assembler files:
idt_csu.S          lnkexit.S   
idt_except.S       lnkhelp.S   
idtfpreg.S         lnkinstal.S 
idtmem.S           lnkio.S     
idttlb.S           lnkioctl.S  
idtwbf.S           lnkjmp.S    
lnkatb.S           lnkmem.S    
lnkcach.S          lnknimp.S   
lnkchar.S          lnkprint.S  
lnkcio.S           lnksbrk.S   
lnkcli.S           lnkstr.S    

Then follow these steps to integrate the low-level IDT code with your Cygnus Developer's Kit:

  1. IDT supplies the C run-time initialization code in the file `idt_csu.S'. Since GNU CC expects to find the initialization module under the name crt0.o, rename the source file to match:
    $ mv idt_csu.S crt0.S
    
  2. Edit the contents of `crt0.S'. A few more instructions are needed to ensure correct initialization, and to ensure that your programs exit cleanly. At the end of the file (after a comment including the text `END I/O initialization'), look for these lines:
            jal     main
    
    ENDFRAME(start)
    
    Insert `move ra,zero' before `jal main' to mark the top of the stack for the debugger, and add two lines after the call to main to call the exit routine (before the `ENDFRAME(start)'), so that the end of the file looks like this:
            move    ra,zero
            jal     main
    
            move    a0,v0
            jal     exit
    
    ENDFRAME(start)
    
  3. Edit `syscalls.c', the interface to the low-level routines required by the C library, to remove the leading underbar from two identifiers:
    1. Rename _kill to kill;
    2. Rename _getpid to getpid.
  4. Edit `lnksbrk.S' to remove the definition of _init_sbrk; this definition is not needed, since it is available in `sbrk.c'. Delete the lines marked with `-' at the left margin below:
            .text
     
    -FRAME(_init_sbrk,sp,0,ra)
    -       j       ra
    -ENDFRAME(_init_sbrk)
    -
    -
    -
     FRAME(_init_file,sp,0,ra)
            j       ra
     ENDFRAME(_init_file)
    
  5. Use your Cygnus Developer's Kit to assemble the `.S' files, like this (use the compiler driver gcc to permit C preprocessing). For concreteness, these example commands assume the mips (big-endian) variant of the configuration; if you ordered tools configured for little-endian object code, type `mipsel' wherever the examples show `mips'.
    $ mips-idt-ecoff-gcc -g -c *.S
    
  6. Compile the `.c' files. One particular C source file, `drv_8254.c' requires two special preprocessor symbol definitions: `-DCLANGUAGE -DTADD=0xBF800000'. Be careful to type the constant value for `TADD' accurately; the correct value is essential to allow the IDT board to communicate over its serial port. The two special preprocessor definitions make no difference to the other C source files, so you can compile them all with one call to the compiler, like this:
    $ mips-idt-ecoff-gcc -g -O \
       -DCLANGUAGE -DTADD=0xBF800000 -c *.c
    
    (The example is split across two lines simply due to formatting constraints; you can type it on a single line instead of two lines linked by a `\', of course.)
  7. Add the new object files to the C library archive, `libc.a', from your Cygnus Developer's Kit. Assuming you installed the Kit in `/usr/cygnus/' as we recommend:
    $ mips-idt-ecoff-ar rvs /usr/cygnus/progressive-94q1/\
    H-host/mips-idt-ecoff/lib/libc.a *.o 
    
    As before, you can omit the `\' and type a single line. `H-host' stands for the string that identifies your host configuration; for example, on a SPARC computer running SunOS 4.1.3, you'd actually type `H-sparc-sun-sunos4.1.3'.

Linking with the GOFAST library

The GOFAST library is available with two interfaces; GCC `-msoft-float' output places all arguments in registers, which (for subroutines using double arguments) is compatible with the interface identified as "Interface 1: all arguments in registers" in the GOFAST documentation. For full compatibility with all GOFAST subroutines, you need to make a slight modification to some of the subroutines in the GOFAST library.

details.

If you purchase and install the GOFAST library, you can link your code to that library in a number of different ways, depending on where and how you install the library.

To focus on the issue of linking, the following examples assume you've already built object modules with appropriate options (including `-msoft-float').

This is the simplest case; it assumes that you've installed the GOFAST library as the file `fp.a' in the same directory where you do development, as shown in the GOFAST documentation:

$ mips-idt-ecoff-gcc -o prog prog.o ... -lc fp.a

In a shared development environment, this example may be more realistic; it assumes you've installed the GOFAST library as `ussdir/libgofast.a', where ussdir is any convenient directory on your development system.

$ mips-idt-ecoff-gcc -o program program.o ... \
  -lc -Lussdir -lgofast

Finally, you can eliminate the need for a `-L' option with a little more setup, using an environment variable like this (the example assumes you use a command shell compatible with the Bourne shell):

$ LIBRARY_PATH=ussdir; export LIBRARY_PATH

$ mips-idt-ecoff-gcc -o program program.o ... -lc -lgofast

As for the previous example, the GOFAST library here is installed in `ussdir/libgofast.a'. The environment variable LIBRARY_PATH instructs GCC to look for the library in ussdir. (The syntax shown here for setting the environment variable is the Unix Bourne Shell (`/bin/sh') syntax; adjust as needed for your system.)

Notice that all the variations on linking with the GOFAST library explicitly include `-lc' before the GOFAST library. `-lc' is the standard C subroutine library; normally, you don't have to specify this, since linking with that library is automatic.

When you link with an alternate software floating-point library, however, the order of linking is important. In this situation, specify `-lc' to the left of the GOFAST library, to ensure that standard library subroutines also use the GOFAST floating-point code.

Full compatibility with the GOFAST library

The GCC calling convention for functions whose first and second arguments have type float is not completely compatible with the definitions of those functions in the GOFAST library, as shipped.

These functions are affected:

fpcmp   fpadd   fpsub   fpmul   fpdiv   fpfmod
fpacos  fpasin  fpatan  fpatan2 fppow

Since the GOFAST library is normally shipped with source, you can make these functions compatible with the GCC convention by adding this instruction to the beginning of each affected function, then rebuilding the library:

        move    $5,$6


Go to the first, previous, next, last section, table of contents.