home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / CLISP-2.LHA / CLISP960530-ki.lha / ffcall / vacall / vacall-mips.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-15  |  2.9 KB  |  84 lines

  1. /* vacall function for mips CPU */
  2.  
  3. /*
  4.  * Copyright 1995 Bruno Haible, <haible@ma2s2.mathematik.uni-karlsruhe.de>
  5.  *
  6.  * This is free software distributed under the GNU General Public Licence
  7.  * described in the file COPYING. Contact the author if you don't have this
  8.  * or can't live with it. There is ABSOLUTELY NO WARRANTY, explicit or implied,
  9.  * on this software.
  10.  */
  11.  
  12. #include "vacall.h.in"
  13.  
  14. typedef void (*func_pointer)(va_alist);
  15. register func_pointer t9 __asm__("$25");
  16. register float    farg1    __asm__("$f12");
  17. register float    farg2    __asm__("$f14");
  18. register double    darg1    __asm__("$f12");
  19. register double    darg2    __asm__("$f14");
  20. register int    iret    __asm__("$2");
  21. register float    fret    __asm__("$f0");
  22. register double    dret    __asm__("$f0");
  23.  
  24. void /* the return type is variable, not void! */
  25. vacall (__vaword word1, __vaword word2, __vaword word3, __vaword word4,
  26.         __vaword firstword)
  27. {
  28.   __va_alist list;
  29.   /* gcc-2.6.3 source says: When a parameter is passed in a register,
  30.    * stack space is still allocated for it.
  31.    */
  32.   /* Move the arguments passed in registers to their stack locations. */
  33.   (&firstword)[-4] = word1;
  34.   (&firstword)[-3] = word2;
  35.   (&firstword)[-2] = word3;
  36.   (&firstword)[-1] = word4;
  37.   list.darg[0] = darg1;
  38.   list.darg[1] = darg2;
  39.   list.farg[0] = farg1;
  40.   list.farg[1] = farg2;
  41.   /* Prepare the va_alist. */
  42.   list.flags = 0;
  43.   list.aptr = (long)(&firstword - 4);
  44.   list.raddr = (void*)0;
  45.   list.rtype = __VAvoid;
  46.   list.memargptr = (long)&firstword;
  47.   list.anum = 0;
  48.   /* Call vacall_function. The macros do all the rest. */
  49.   (*(t9 = vacall_function)) (&list);
  50.   /* Put return value into proper register. */
  51.   switch (list.rtype)
  52.     {
  53.       case __VAvoid:    break;
  54.       case __VAchar:    iret = list.tmp._char; break;
  55.       case __VAschar:    iret = list.tmp._schar; break;
  56.       case __VAuchar:    iret = list.tmp._uchar; break;
  57.       case __VAshort:    iret = list.tmp._short; break;
  58.       case __VAushort:    iret = list.tmp._ushort; break;
  59.       case __VAint:    iret = list.tmp._int; break;
  60.       case __VAuint:    iret = list.tmp._uint; break;
  61.       case __VAlong:    iret = list.tmp._long; break;
  62.       case __VAulong:    iret = list.tmp._ulong; break;
  63.       case __VAfloat:    fret = list.tmp._float; break;
  64.       case __VAdouble:    dret = list.tmp._double; break;
  65.       case __VAvoidp:    iret = (long)list.tmp._ptr; break;
  66.       case __VAstruct:
  67.         if (list.flags & __VA_PCC_STRUCT_RETURN)
  68.           { /* pcc struct return convention */
  69.             iret = (long) list.raddr;
  70.           }
  71.         else
  72.           { /* normal struct return convention */
  73.             if (list.flags & __VA_SMALL_STRUCT_RETURN)
  74.               switch (list.rsize)
  75.                 { case sizeof(char):  iret = *(unsigned char *) list.raddr; break;
  76.                   case sizeof(short): iret = *(unsigned short *) list.raddr; break;
  77.                   case sizeof(int):   iret = *(unsigned int *) list.raddr; break;
  78.                   default:            break;
  79.                 }
  80.           }
  81.         break;
  82.     }
  83. }
  84.