avcall-convex.c
上传用户:shenzhenrh
上传日期:2013-05-12
资源大小:2904k
文件大小:4k
源码类别:

信息检索与抽取

开发平台:

Unix_Linux

  1. #ifndef _avcall_convex_c /*-*- C -*-*/
  2. #define _avcall_convex_c
  3. /**
  4.   Copyright 1993 Bill Triggs, <Bill.Triggs@inrialpes.fr>
  5.   Copyright 1995-1999 Bruno Haible, <haible@clisp.cons.org>
  6.   This is free software distributed under the GNU General Public
  7.   Licence described in the file COPYING. Contact the author if
  8.   you don't have this or can't live with it. There is ABSOLUTELY
  9.   NO WARRANTY, explicit or implied, on this software.
  10. **/
  11. /*----------------------------------------------------------------------
  12.   !!! THIS ROUTINE MUST BE COMPILED gcc -O !!!
  13.   Foreign function interface for a Convex C2 with gcc.
  14.   This calls a C function with an argument list built up using macros
  15.   defined in av_call.h.
  16.   Convex Argument Passing Conventions:
  17.   All arguments are passed on the stack with word alignment. Doubles take
  18.   two words. Structure args are passed as true structures embedded in the
  19.   argument stack. To return a structure, the -fpcc-struct-return convention
  20.   is used.
  21.   Compile this routine with gcc -O (or -O2 or -g -O) to get the right
  22.   register variables, or use the assembler version.
  23.   ----------------------------------------------------------------------*/
  24. #include "avcall.h.in"
  25. #define RETURN(TYPE,VAL) (*(TYPE*)l->raddr = (TYPE)(VAL))
  26. int
  27. __builtin_avcall(av_alist* l)
  28. {
  29.   register __avword* sp __asm__("sp");  /* C names for registers */
  30.   register long long llret __asm__("s0");
  31.   register float fret __asm__("s0");
  32.   register double dret __asm__("s0");
  33.   __avword space[__AV_ALIST_WORDS]; /* space for callee's stack frame */
  34.   __avword* argframe = sp; /* stack offset for argument list */
  35.   int arglen = l->aptr - l->args;
  36.   __avword i;
  37.   {
  38.     int i;
  39.     for (i = 0; i < arglen; i++) /* push function args onto stack */
  40.       argframe[i] = l->args[i];
  41.   }
  42.   i = (*l->func)(); /* call function */
  43.   /* save return value */
  44.   if (l->rtype == __AVvoid) {
  45.   } else
  46.   if (l->rtype == __AVword) {
  47.     RETURN(__avword, i);
  48.   } else
  49.   if (l->rtype == __AVchar) {
  50.     RETURN(char, i);
  51.   } else
  52.   if (l->rtype == __AVschar) {
  53.     RETURN(signed char, i);
  54.   } else
  55.   if (l->rtype == __AVuchar) {
  56.     RETURN(unsigned char, i);
  57.   } else
  58.   if (l->rtype == __AVshort) {
  59.     RETURN(short, i);
  60.   } else
  61.   if (l->rtype == __AVushort) {
  62.     RETURN(unsigned short, i);
  63.   } else
  64.   if (l->rtype == __AVint) {
  65.     RETURN(int, i);
  66.   } else
  67.   if (l->rtype == __AVuint) {
  68.     RETURN(unsigned int, i);
  69.   } else
  70.   if (l->rtype == __AVlong) {
  71.     RETURN(long, i);
  72.   } else
  73.   if (l->rtype == __AVulong) {
  74.     RETURN(unsigned long, i);
  75.   } else
  76.   if (l->rtype == __AVlonglong) {
  77.     RETURN(long long, llret);
  78.   } else
  79.   if (l->rtype == __AVulonglong) {
  80.     RETURN(unsigned long long, llret);
  81.   } else
  82.   if (l->rtype == __AVfloat) {
  83.     RETURN(float, fret);
  84.   } else
  85.   if (l->rtype == __AVdouble) {
  86.     RETURN(double, dret);
  87.   } else
  88.   if (l->rtype == __AVvoidp) {
  89.     RETURN(void*, i);
  90.   } else
  91.   if (l->rtype == __AVstruct) {
  92.     if (l->flags & __AV_PCC_STRUCT_RETURN) {
  93.       /* pcc struct return convention: need a  *(TYPE*)l->raddr = *(TYPE*)i;  */
  94.       if (l->rsize == sizeof(char)) {
  95.         RETURN(char, *(char*)i);
  96.       } else
  97.       if (l->rsize == sizeof(short)) {
  98.         RETURN(short, *(short*)i);
  99.       } else
  100.       if (l->rsize == sizeof(int)) {
  101.         RETURN(int, *(int*)i);
  102.       } else
  103.       if (l->rsize == sizeof(double)) {
  104.         ((int*)l->raddr)[0] = ((int*)i)[0];
  105.         ((int*)l->raddr)[1] = ((int*)i)[1];
  106.       } else {
  107.         int n = (l->rsize + sizeof(__avword)-1)/sizeof(__avword);
  108.         while (--n >= 0)
  109.           ((__avword*)l->raddr)[n] = ((__avword*)i)[n];
  110.       }
  111.     } else {
  112.       /* normal struct return convention */
  113.       if (l->flags & __AV_REGISTER_STRUCT_RETURN) {
  114.         if (l->rsize == sizeof(char)) {
  115.           RETURN(char, i);
  116.         } else
  117.         if (l->rsize == sizeof(short)) {
  118.           RETURN(short, i);
  119.         } else
  120.         if (l->rsize == sizeof(int)) {
  121.           RETURN(int, i);
  122.         } else
  123.         if (l->rsize == 2*sizeof(__avword)) {
  124.           RETURN(long long, llret);
  125.         }
  126.       }
  127.     }
  128.   }
  129.   return 0;
  130. }
  131. #endif /*_avcall_convex_c */