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

信息检索与抽取

开发平台:

Unix_Linux

  1. #ifndef _avcall_ia64_c /*-*- C -*-*/
  2. #define _avcall_ia64_c
  3. /**
  4.   Copyright 1993 Bill Triggs, <Bill.Triggs@inrialpes.fr>
  5.   Copyright 1995-2001 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 Intel IA-64 in little-endian mode with gcc.
  14.   This calls a C function with an argument list built up using macros
  15.   defined in av_call.h.
  16.   IA-64 64-bit Argument Passing Conventions:
  17.   The argument sequence is mapped linearly on the registers r32,...,r39,
  18.   and continued on the stack, in [r12+16], [r12+24], ...
  19.   Items in this sequence are word-aligned. Structures larger than a single
  20.   word are even two-word-aligned.
  21.   Integer/pointer arguments are passed in the allocated slots (registers
  22.   or stack slots). The first 8 float/double arguments are passed in
  23.   registers f8,...,f15 instead, but their slots are kept allocated.
  24.   Structure args are passed like multiple integer arguments; except that
  25.   structures consisting only of floats or only of doubles are passed like
  26.   multiple float arguments or multiple double arguments, respectively.
  27.   Integers and pointers are returned in r8, floats and doubles in f8.
  28.   Structures consisting only of at most 8 floats or only of at most 8 doubles
  29.   are returned in f8,...,f15. Other than that, structures of size <= 32 bytes
  30.   are returned in r8,...,r11, as if these were 4 contiguous words in memory.
  31.   Larger structures are returned in memory; the caller passes the address
  32.   of the target memory area in r8, and it is returned unmodified in r8.
  33.   ----------------------------------------------------------------------*/
  34. #include "avcall.h.in"
  35. #define RETURN(TYPE,VAL) (*(TYPE*)l->raddr = (TYPE)(VAL))
  36. register __avword* sret __asm__("r8");  /* structure return pointer */
  37. register __avword iret __asm__("r8");
  38. register __avword iret2 __asm__("r9");
  39. register __avword iret3 __asm__("r10");
  40. register __avword iret4 __asm__("r11");
  41. /*register float fret __asm__("f8");*/
  42. /*register double dret __asm__("f8");*/
  43. register double farg1 __asm__("f8");
  44. register double farg2 __asm__("f9");
  45. register double farg3 __asm__("f10");
  46. register double farg4 __asm__("f11");
  47. register double farg5 __asm__("f12");
  48. register double farg6 __asm__("f13");
  49. register double farg7 __asm__("f14");
  50. register double farg8 __asm__("f15");
  51. int
  52. __builtin_avcall(av_alist* l)
  53. {
  54.   register __avword* sp __asm__("r12"); /* C names for registers */
  55.   __avword* argframe = (sp -= __AV_ALIST_WORDS) + 2; /* make room for argument list */
  56.   int arglen = l->aptr - l->args;
  57.   int farglen = l->faptr - l->fargs;
  58.   __avword i;
  59.   for (i = 8; i < arglen; i++) /* push function args onto stack */
  60.     argframe[i-8] = l->args[i];
  61.   /* struct return address */
  62.   if (l->rtype == __AVstruct)
  63.     sret = l->raddr;
  64.   /* put max. 8 double args in registers */
  65.   if (farglen > 0) {
  66.     farg1 = l->fargs[0];
  67.     if (farglen > 1) {
  68.       farg2 = l->fargs[1];
  69.       if (farglen > 2) {
  70.         farg3 = l->fargs[2];
  71.         if (farglen > 3) {
  72.           farg4 = l->fargs[3];
  73.           if (farglen > 4) {
  74.             farg5 = l->fargs[4];
  75.             if (farglen > 5) {
  76.               farg6 = l->fargs[5];
  77.               if (farglen > 6) {
  78.                 farg7 = l->fargs[6];
  79.                 if (farglen > 7)
  80.                   farg8 = l->fargs[7];
  81.               }
  82.             }
  83.           }
  84.         }
  85.       }
  86.     }
  87.   }
  88.   /* call function, pass 8 integer and 8 double args in registers */
  89.   if (l->rtype == __AVfloat) {
  90.     *(float*)l->raddr = (*(float(*)())l->func)(l->args[0], l->args[1],
  91.        l->args[2], l->args[3],
  92.        l->args[4], l->args[5],
  93.        l->args[6], l->args[7]);
  94.   } else
  95.   if (l->rtype == __AVdouble) {
  96.     *(double*)l->raddr = (*(double(*)())l->func)(l->args[0], l->args[1],
  97.  l->args[2], l->args[3],
  98.  l->args[4], l->args[5],
  99.  l->args[6], l->args[7]);
  100.   } else {
  101.     i = (*l->func)(l->args[0], l->args[1], l->args[2], l->args[3],
  102.    l->args[4], l->args[5], l->args[6], l->args[7]);
  103.     /* save return value */
  104.     if (l->rtype == __AVvoid) {
  105.     } else
  106.     if (l->rtype == __AVword) {
  107.       RETURN(__avword, i);
  108.     } else
  109.     if (l->rtype == __AVchar) {
  110.       RETURN(char, i);
  111.     } else
  112.     if (l->rtype == __AVschar) {
  113.       RETURN(signed char, i);
  114.     } else
  115.     if (l->rtype == __AVuchar) {
  116.       RETURN(unsigned char, i);
  117.     } else
  118.     if (l->rtype == __AVshort) {
  119.       RETURN(short, i);
  120.     } else
  121.     if (l->rtype == __AVushort) {
  122.       RETURN(unsigned short, i);
  123.     } else
  124.     if (l->rtype == __AVint) {
  125.       RETURN(int, i);
  126.     } else
  127.     if (l->rtype == __AVuint) {
  128.       RETURN(unsigned int, i);
  129.     } else
  130.     if (l->rtype == __AVlong || l->rtype == __AVlonglong) {
  131.       RETURN(long, i);
  132.     } else
  133.     if (l->rtype == __AVulong || l->rtype == __AVulonglong) {
  134.       RETURN(unsigned long, i);
  135.     } else
  136.   /* see above
  137.     if (l->rtype == __AVfloat) {
  138.     } else
  139.     if (l->rtype == __AVdouble) {
  140.     } else
  141.   */
  142.     if (l->rtype == __AVvoidp) {
  143.       RETURN(void*, i);
  144.     } else
  145.     if (l->rtype == __AVstruct) {
  146.       if (l->flags & __AV_PCC_STRUCT_RETURN) {
  147.         /* pcc struct return convention: need a  *(TYPE*)l->raddr = *(TYPE*)i;  */
  148.         if (l->rsize == sizeof(char)) {
  149.           RETURN(char, *(char*)i);
  150.         } else
  151.         if (l->rsize == sizeof(short)) {
  152.           RETURN(short, *(short*)i);
  153.         } else
  154.         if (l->rsize == sizeof(int)) {
  155.           RETURN(int, *(int*)i);
  156.         } else
  157.         if (l->rsize == sizeof(long)) {
  158.           RETURN(long, *(long*)i);
  159.         } else {
  160.           int n = (l->rsize + sizeof(__avword)-1)/sizeof(__avword);
  161.           while (--n >= 0)
  162.             ((__avword*)l->raddr)[n] = ((__avword*)i)[n];
  163.         }
  164.       } else {
  165.         /* normal struct return convention */
  166.         if (l->flags & __AV_REGISTER_STRUCT_RETURN) {
  167.           /* Return structs of size <= 32 in registers. */
  168.           if (l->rsize > 0 && l->rsize <= 32) {
  169.             if (l->rsize >= 1)
  170.               ((unsigned char *)l->raddr)[0] = (unsigned char)(i);
  171.             if (l->rsize >= 2)
  172.               ((unsigned char *)l->raddr)[1] = (unsigned char)(i>>8);
  173.             if (l->rsize >= 3)
  174.               ((unsigned char *)l->raddr)[2] = (unsigned char)(i>>16);
  175.             if (l->rsize >= 4)
  176.               ((unsigned char *)l->raddr)[3] = (unsigned char)(i>>24);
  177.             if (l->rsize >= 5)
  178.               ((unsigned char *)l->raddr)[4] = (unsigned char)(i>>32);
  179.             if (l->rsize >= 6)
  180.               ((unsigned char *)l->raddr)[5] = (unsigned char)(i>>40);
  181.             if (l->rsize >= 7)
  182.               ((unsigned char *)l->raddr)[6] = (unsigned char)(i>>48);
  183.             if (l->rsize >= 8)
  184.               ((unsigned char *)l->raddr)[7] = (unsigned char)(i>>56);
  185.             if (l->rsize >= 9) {
  186.               ((unsigned char *)l->raddr)[8] = (unsigned char)(iret2);
  187.               if (l->rsize >= 10)
  188.                 ((unsigned char *)l->raddr)[9] = (unsigned char)(iret2>>8);
  189.               if (l->rsize >= 11)
  190.                 ((unsigned char *)l->raddr)[10] = (unsigned char)(iret2>>16);
  191.               if (l->rsize >= 12)
  192.                 ((unsigned char *)l->raddr)[11] = (unsigned char)(iret2>>24);
  193.               if (l->rsize >= 13)
  194.                 ((unsigned char *)l->raddr)[12] = (unsigned char)(iret2>>32);
  195.               if (l->rsize >= 14)
  196.                 ((unsigned char *)l->raddr)[13] = (unsigned char)(iret2>>40);
  197.               if (l->rsize >= 15)
  198.                 ((unsigned char *)l->raddr)[14] = (unsigned char)(iret2>>48);
  199.               if (l->rsize >= 16)
  200.                 ((unsigned char *)l->raddr)[15] = (unsigned char)(iret2>>56);
  201.               if (l->rsize >= 17) {
  202.                 ((unsigned char *)l->raddr)[16] = (unsigned char)(iret3);
  203.                 if (l->rsize >= 18)
  204.                   ((unsigned char *)l->raddr)[17] = (unsigned char)(iret3>>8);
  205.                 if (l->rsize >= 19)
  206.                   ((unsigned char *)l->raddr)[18] = (unsigned char)(iret3>>16);
  207.                 if (l->rsize >= 20)
  208.                   ((unsigned char *)l->raddr)[19] = (unsigned char)(iret3>>24);
  209.                 if (l->rsize >= 21)
  210.                   ((unsigned char *)l->raddr)[20] = (unsigned char)(iret3>>32);
  211.                 if (l->rsize >= 22)
  212.                   ((unsigned char *)l->raddr)[21] = (unsigned char)(iret3>>40);
  213.                 if (l->rsize >= 23)
  214.                   ((unsigned char *)l->raddr)[22] = (unsigned char)(iret3>>48);
  215.                 if (l->rsize >= 24)
  216.                   ((unsigned char *)l->raddr)[23] = (unsigned char)(iret3>>56);
  217.                 if (l->rsize >= 25) {
  218.                   ((unsigned char *)l->raddr)[24] = (unsigned char)(iret4);
  219.                   if (l->rsize >= 26)
  220.                     ((unsigned char *)l->raddr)[25] = (unsigned char)(iret4>>8);
  221.                   if (l->rsize >= 27)
  222.                     ((unsigned char *)l->raddr)[26] = (unsigned char)(iret4>>16);
  223.                   if (l->rsize >= 28)
  224.                     ((unsigned char *)l->raddr)[27] = (unsigned char)(iret4>>24);
  225.                   if (l->rsize >= 29)
  226.                     ((unsigned char *)l->raddr)[28] = (unsigned char)(iret4>>32);
  227.                   if (l->rsize >= 30)
  228.                     ((unsigned char *)l->raddr)[29] = (unsigned char)(iret4>>40);
  229.                   if (l->rsize >= 31)
  230.                     ((unsigned char *)l->raddr)[30] = (unsigned char)(iret4>>48);
  231.                   if (l->rsize >= 32)
  232.                     ((unsigned char *)l->raddr)[31] = (unsigned char)(iret4>>56);
  233.                 }
  234.               }
  235.             }
  236.           }
  237.         }
  238.       }
  239.     }
  240.   }
  241.   return 0;
  242. }
  243. #endif /*_avcall_ia64_c */