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

信息检索与抽取

开发平台:

Unix_Linux

  1. #ifndef _avcall_m88k_c /*-*- C -*-*/
  2. #define _avcall_m88k_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 -fno-omit-frame-pointer !!!
  13.   Foreign function interface for a M88000 with gcc.
  14.   This calls a C function with an argument list built up using macros
  15.   defined in av_call.h.
  16.   M88k Argument Passing Conventions:
  17.   All arguments, except the non-structs among the first 8 words, are passed
  18.   on the stack with word alignment. Doubles take two words and force double
  19.   alignment. Scalars among the first 8 words are passed in registers.
  20.   Structure args are are passed as true structures embedded in the argument
  21.   stack.
  22.   To return a structure, the called function copies the return value to the
  23.   address supplied in register "r12".
  24.   Compile this routine with gcc -O (or -O2 -fno-omit-frame-pointer or -g -O)
  25.   to get the right register variables. For other compilers use the
  26.   pre-compiled assembler version.
  27.   ----------------------------------------------------------------------*/
  28. #include "avcall.h.in"
  29. #define RETURN(TYPE,VAL) (*(TYPE*)l->raddr = (TYPE)(VAL))
  30. register __avword* sret __asm__("r12");  /* structure return pointer */
  31. int
  32. __builtin_avcall(av_alist* l)
  33. {
  34.   register __avword* sp __asm__("r31"); /* C names for registers */
  35. /*register __avword iret __asm__("r2"); */
  36.   register __avword iret2 __asm__("r3");
  37.   register float fret __asm__("r2");
  38.   register double dret __asm__("r2");
  39.   __avword* argframe = (sp -= __AV_ALIST_WORDS); /* make room for argument list */
  40.   int arglen = l->aptr - l->args;
  41.   __avword i;
  42.   for (i = 0; i < arglen; i++) /* push function args onto stack */
  43.     argframe[i] = l->args[i];
  44.   if (l->rtype == __AVstruct) /* pass struct return address */
  45.     sret = l->raddr;
  46. /* call function, pass 8 args in registers */
  47.   i = (*l->func)(l->args[0], l->args[1], l->args[2], l->args[3],
  48.  l->args[4], l->args[5], l->args[6], l->args[7]);
  49.   /* save return value */
  50.   if (l->rtype == __AVvoid) {
  51.   } else
  52.   if (l->rtype == __AVword) {
  53.     RETURN(__avword, i);
  54.   } else
  55.   if (l->rtype == __AVchar) {
  56.     RETURN(char, i);
  57.   } else
  58.   if (l->rtype == __AVschar) {
  59.     RETURN(signed char, i);
  60.   } else
  61.   if (l->rtype == __AVuchar) {
  62.     RETURN(unsigned char, i);
  63.   } else
  64.   if (l->rtype == __AVshort) {
  65.     RETURN(short, i);
  66.   } else
  67.   if (l->rtype == __AVushort) {
  68.     RETURN(unsigned short, i);
  69.   } else
  70.   if (l->rtype == __AVint) {
  71.     RETURN(int, i);
  72.   } else
  73.   if (l->rtype == __AVuint) {
  74.     RETURN(unsigned int, i);
  75.   } else
  76.   if (l->rtype == __AVlong) {
  77.     RETURN(long, i);
  78.   } else
  79.   if (l->rtype == __AVulong) {
  80.     RETURN(unsigned long, i);
  81.   } else
  82.   if (l->rtype == __AVlonglong || l->rtype == __AVulonglong) {
  83.     ((__avword*)l->raddr)[0] = i;
  84.     ((__avword*)l->raddr)[1] = iret2;
  85.   } else
  86.   if (l->rtype == __AVfloat) {
  87.     RETURN(float, fret);
  88.   } else
  89.   if (l->rtype == __AVdouble) {
  90.     RETURN(double, dret);
  91.   } else
  92.   if (l->rtype == __AVvoidp) {
  93.     RETURN(void*, i);
  94.   } else
  95.   if (l->rtype == __AVstruct) {
  96.     if (l->flags & __AV_PCC_STRUCT_RETURN) {
  97.       /* pcc struct return convention: need a  *(TYPE*)l->raddr = *(TYPE*)i;  */
  98.       if (l->rsize == sizeof(char)) {
  99.         RETURN(char, *(char*)i);
  100.       } else
  101.       if (l->rsize == sizeof(short)) {
  102.         RETURN(short, *(short*)i);
  103.       } else
  104.       if (l->rsize == sizeof(int)) {
  105.         RETURN(int, *(int*)i);
  106.       } else
  107.       if (l->rsize == sizeof(double)) {
  108.         ((int*)l->raddr)[0] = ((int*)i)[0];
  109.         ((int*)l->raddr)[1] = ((int*)i)[1];
  110.       } else {
  111.         int n = (l->rsize + sizeof(__avword)-1)/sizeof(__avword);
  112.         while (--n >= 0)
  113.           ((__avword*)l->raddr)[n] = ((__avword*)i)[n];
  114.       }
  115.     } else {
  116.       /* normal struct return convention */
  117.       if (l->flags & __AV_SMALL_STRUCT_RETURN) {
  118.         if (l->rsize == sizeof(char)) {
  119.           RETURN(char, i);
  120.         } else
  121.         if (l->rsize == sizeof(short)) {
  122.           RETURN(short, i);
  123.         } else
  124.         if (l->rsize == sizeof(int)) {
  125.           RETURN(int, i);
  126.         }
  127.       }
  128.     }
  129.   }
  130.   sp += __AV_ALIST_WORDS;
  131.   return 0;
  132. }
  133. #endif /*_avcall_m88k_c */