home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / CLISP-2.LHA / CLISP960530-ki.lha / ffcall / avcall / avcall.h.in < prev    next >
Encoding:
Text File  |  1996-04-15  |  31.2 KB  |  854 lines

  1. #ifndef _avcall_h                /*-*- C -*-*/
  2. #define _avcall_h "$Id: avcall.h.in,v 1.1.1.1 1995/09/10 10:59:00 marcus Exp $"
  3. /**
  4.   Copyright 1993 Bill Triggs, <bill@robots.oxford.ac.uk>,
  5.   Oxford University Robotics Group, Oxford OX1 3PJ, U.K.
  6.  
  7.   Copyright 1995 Bruno Haible, <haible@ma2s2.mathematik.uni-karlsruhe.de>
  8.  
  9.   This is free software distributed under the GNU General Public
  10.   Licence described in the file COPYING. Contact the author if
  11.   you don't have this or can't live with it. There is ABSOLUTELY
  12.   NO WARRANTY, explicit or implied, on this software.
  13. **/
  14. /*----------------------------------------------------------------------
  15.   av_call() foreign function interface.
  16.  
  17.   Varargs-style macros to build a C argument list incrementally
  18.   and call a function on it.
  19.  ----------------------------------------------------------------------*/
  20.  
  21.  
  22. /* These definitions are adjusted by `configure' automatically. */
  23.  
  24. /* CPU */
  25. #ifndef __i386__
  26. #undef __i386__
  27. #endif
  28. #ifndef __m68k__
  29. #undef __m68k__
  30. #endif
  31. #ifndef __mips__
  32. #undef __mips__
  33. #endif
  34. #ifndef __sparc__
  35. #undef __sparc__
  36. #endif
  37. #ifndef __alpha__
  38. #undef __alpha__
  39. #endif
  40. #ifndef __hppa__
  41. #undef __hppa__
  42. #endif
  43. #ifndef __arm__
  44. #undef __arm__
  45. #endif
  46. #ifndef __rs6000__
  47. #undef __rs6000__
  48. #endif
  49. #ifndef __m88k__
  50. #undef __m88k__
  51. #endif
  52. #ifndef __convex__
  53. #undef __convex__
  54. #endif
  55.  
  56. /* Calling convention */
  57. /* Define if using pcc non-reentrant struct return convention */
  58. #undef __PCC_STRUCT_RETURN__
  59. /* Define if small structs are returned in registers */
  60. #undef __SMALL_STRUCT_RETURN__
  61.  
  62. /* End of definitions adjusted by `configure'. */
  63.  
  64.  
  65. /* Max # words in argument-list and temporary structure storage.
  66.  */
  67. #ifndef __AV_ALIST_WORDS
  68. #define __AV_ALIST_WORDS  256
  69. #endif
  70.  
  71. /* Determine the alignment of a type at compile time.
  72.  */
  73. #if defined(__GNUC__)
  74. #define __AV_alignof __alignof__
  75. #else
  76. #if defined(__mips__) /* SGI compiler */
  77. #define __AV_alignof __builtin_alignof
  78. #else
  79. #define __AV_offsetof(type,ident)  ((unsigned long)&(((type*)0)->ident))
  80. #define __AV_alignof(type)  __AV_offsetof(struct { char __slot1; type __slot2; }, __slot2)
  81. #endif
  82. #endif
  83.  
  84. /* C builtin types.
  85.  */
  86. typedef long __avword;
  87.  
  88. enum __AVtype
  89. {
  90.   __AVword,
  91.   __AVvoid,
  92.   __AVchar,
  93.   __AVschar,
  94.   __AVuchar,
  95.   __AVshort,
  96.   __AVushort,
  97.   __AVint,
  98.   __AVuint,
  99.   __AVlong,
  100.   __AVulong,
  101.   __AVfloat,
  102.   __AVdouble,
  103.   __AVvoidp,
  104.   __AVstruct
  105. };
  106.  
  107. enum __AV_alist_flags
  108. {
  109.  
  110.   /* how to return structs */
  111.   /* There are basically 3 ways to return structs:
  112.    * a. The called function returns a pointer to static data. Not reentrant.
  113.    * b. The caller passes the return structure address in a dedicated register
  114.    *    or as a first (or last), invisible argument. The called function stores
  115.    *    its result there.
  116.    * c. Like b, and the called function also returns the return structure
  117.    *    address in the return value register. (This is not very distinguishable
  118.    *    from b.)
  119.    * Independently of this,
  120.    * r. small structures (<= 4 or <= 8 bytes) may be returned in the return
  121.    *    value register(s), or
  122.    * m. even small structures are passed in memory.
  123.    */
  124.   /* gcc-2.6.3 employs the following strategy:
  125.    *   - If PCC_STATIC_STRUCT_RETURN is defined in the machine description
  126.    *     it uses method a, else method c.
  127.    *   - If flag_pcc_struct_return is set (either by -fpcc-struct-return or if
  128.    *     DEFAULT_PCC_STRUCT_RETURN is defined to 1 in the machine description)
  129.    *     it uses method m, else (either by -freg-struct-return or if
  130.    *     DEFAULT_PCC_STRUCT_RETURN is defined to 0 in the machine description)
  131.    *     method r.
  132.    */
  133.   __AV_PCC_STRUCT_RETURN    = 1<<0,    /* a: need to copy the struct */
  134.   __AV_SMALL_STRUCT_RETURN    = 1<<1,    /* r: special case for small structs */
  135.   __AV_GCC_STRUCT_RETURN    = 1<<2,    /* consider 8 byte structs as small */
  136. #if defined(__sparc__)
  137.   __AV_SUNCC_STRUCT_RETURN    = 1<<3,
  138. #endif
  139. #if defined(__i386__)
  140.   __AV_NEXTGCC_STRUCT_RETURN    = 1<<3,
  141. #endif
  142.   /* the default way to return structs */
  143.   /* This choice here is based on the assumption that the function you are
  144.    * going to call has been compiled with the same compiler you are using to
  145.    * include this file.
  146.    * If you want to call functions with another struct returning convention,
  147.    * just  #define __AV_STRUCT_RETURN ...
  148.    * before or after #including <avcall.h>.
  149.    */
  150. #ifndef __AV_STRUCT_RETURN
  151.   __AV_STRUCT_RETURN        =
  152. #if defined(__PCC_STRUCT_RETURN__) /* defined through configure, see above */
  153.                   __AV_PCC_STRUCT_RETURN |
  154. #if defined(__sparc__) && defined(sun) && !(defined(__STDC__) || defined(__GNUC__)) /* sun cc */
  155.                     __AV_SUNCC_STRUCT_RETURN,
  156. #else
  157.                     0,
  158. #endif
  159. #else
  160. #if defined(__SMALL_STRUCT_RETURN__) /* defined through configure, see above */
  161.                   __AV_SMALL_STRUCT_RETURN |
  162. #endif
  163. #if defined(__GNUC__)
  164.                   __AV_GCC_STRUCT_RETURN |
  165. #endif
  166. #if defined(__i386__) && defined(NeXT) && defined(__GNUC__) /* NeXT gcc-2.5.8 */
  167.                   __AV_NEXTGCC_STRUCT_RETURN |
  168. #endif
  169.                     0,
  170. #endif
  171. #endif
  172.  
  173.   /* how to return floats */
  174. #if defined(__m68k__) || defined(__sparc__)
  175.   __AV_SUNCC_FLOAT_RETURN    = 1<<4,
  176. #endif
  177.   /* the default way to return floats */
  178.   /* This choice here is based on the assumption that the function you are
  179.    * going to call has been compiled with the same compiler you are using to
  180.    * include this file.
  181.    * If you want to call functions with another float returning convention,
  182.    * just  #define __AV_FLOAT_RETURN ...
  183.    * before or after #including <avcall.h>.
  184.    */
  185. #ifndef __AV_FLOAT_RETURN
  186. #if (defined(__m68k__) || defined(__sparc__)) && !defined(__GNUC__) && defined(sun)  /* sun cc */
  187.   __AV_FLOAT_RETURN        = __AV_SUNCC_FLOAT_RETURN,
  188. #else
  189.   __AV_FLOAT_RETURN        = 0,
  190. #endif
  191. #endif
  192.  
  193.   /* how to pass structs */
  194. #if defined(__mips__)
  195.   __AV_SGICC_STRUCT_ARGS    = 1<<5,
  196. #endif
  197. #if defined(__rs6000__)
  198.   __AV_AIXCC_STRUCT_ARGS    = 1<<5,
  199. #endif
  200.   /* the default way to pass floats */
  201.   /* This choice here is based on the assumption that the function you are
  202.    * going to call has been compiled with the same compiler you are using to
  203.    * include this file.
  204.    * If you want to call functions with another float passing convention,
  205.    * just  #define __AV_STRUCT_ARGS ...
  206.    * before or after #including <avcall.h>.
  207.    */
  208. #ifndef __AV_STRUCT_ARGS
  209. #if defined(__mips__) && !defined(__GNUC__) /* SGI mips cc */
  210.   __AV_STRUCT_ARGS        = __AV_SGICC_STRUCT_ARGS,
  211. #else
  212. #if defined(__rs6000__) && !defined(__GNUC__) /* AIX cc, xlc */
  213.   __AV_STRUCT_ARGS        = __AV_AIXCC_STRUCT_ARGS,
  214. #else
  215.   __AV_STRUCT_ARGS        = 0,
  216. #endif
  217. #endif
  218. #endif
  219.  
  220.   /* how to pass floats */
  221.   /* ANSI C compilers and GNU gcc pass floats as floats.
  222.    * K&R C compilers pass floats as doubles.
  223.    * (Except some compilers like SGI MIPS "cc" and "cc -cckr" if a prototype is
  224.    * known for the called functions. But to compile a program with prototypes,
  225.    * "cc -ansi" is better anyway.
  226.    */
  227.   __AV_ANSI_FLOAT_ARGS        = 0,    /* pass floats as floats */
  228.   __AV_TRADITIONAL_FLOAT_ARGS    = 1<<6, /* pass floats as doubles */
  229.   /* the default way to pass floats */
  230.   /* This choice here is based on the assumption that the function you are
  231.    * going to call has been compiled with the same compiler you are using to
  232.    * include this file.
  233.    * If you want to call functions with another float passing convention,
  234.    * just  #define __AV_FLOAT_ARGS ...
  235.    * before or after #including <avcall.h>.
  236.    */
  237. #ifndef __AV_FLOAT_ARGS
  238. #if defined(__STDC__) || defined(__GNUC__) /* what about hppa "cc -Aa" ?? */
  239.   __AV_FLOAT_ARGS        = __AV_ANSI_FLOAT_ARGS,
  240. #else
  241.   __AV_FLOAT_ARGS        = __AV_TRADITIONAL_FLOAT_ARGS,
  242. #endif
  243. #endif
  244.  
  245.   /* how to pass and return small integer arguments */
  246.   __AV_ANSI_INTEGERS        = 0, /* no promotions */
  247.   __AV_TRADITIONAL_INTEGERS    = 0, /* promote [u]char, [u]short to [u]int */
  248.   /* Fortunately these two methods are compatible. Our macros work with both. */
  249.   /* the default way to pass and return small integer arguments */
  250.   /* This choice here is based on the assumption that the function you are
  251.    * going to call has been compiled with the same compiler you are using to
  252.    * include this file.
  253.    * If you want to call functions with another float passing convention,
  254.    * just  #define __AV_INTEGERS ...
  255.    * before or after #including <avcall.h>.
  256.    */
  257. #ifndef __AV_INTEGERS
  258. #if defined(__STDC__) || defined(__GNUC__)
  259.   __AV_INTEGERS            = __AV_ANSI_INTEGERS,
  260. #else
  261.   __AV_INTEGERS            = __AV_TRADITIONAL_INTEGERS,
  262. #endif
  263. #endif
  264.  
  265.   /* These are for internal use only */
  266. #if defined(__i386__) || defined(__m68k__) || defined(__alpha__) || defined(__arm__) || defined(__rs6000__) || defined(__convex__)
  267.   __AV_REGISTER_STRUCT_RETURN    = 1<<8,
  268. #endif
  269. #if defined(__mips__)
  270.   __AV_FLOAT_1            = 1<<9,
  271.   __AV_FLOAT_2            = 1<<10,
  272. #endif
  273.  
  274.   __AV_flag_for_broken_compilers_that_dont_like_trailing_commas
  275. };
  276.  
  277. typedef struct
  278. {
  279.   /* function to be called */
  280.   int            (*func)();
  281.   /* some av_... macros need these flags */
  282.   int            flags;
  283.   /* return type, address for the result */
  284.   void*            raddr;
  285.   enum __AVtype        rtype;
  286.   unsigned long        rsize;
  287.   /* current pointer into the args[] array */
  288.   __avword*        aptr;
  289. #if defined(__sparc__) || defined(__hppa__)
  290.   /* limit pointer into the args[] array */
  291.   __avword*        eptr;
  292. #endif
  293. #if defined(__i386__) || defined(__m68k__) || defined(__sparc__) || defined(__hppa__) || defined(__arm__) || defined(__rs6000__) || defined(__convex__)
  294.   /* temporary storage, used to split doubles into two words */
  295.   union {
  296.     double    _double;
  297.     __avword    words[2];
  298.   }            tmp;
  299. #endif
  300. #if defined(__mips__)
  301.   /* store the floating-point arguments in an extra array */
  302.   int            anum;
  303.   double        floatarg[2];
  304. #endif
  305.   __avword        args[__AV_ALIST_WORDS]; /* sizeof(double)-aligned */
  306. #if defined(__rs6000__)
  307.   /* store the floating-point arguments in an extra array */
  308.   double*        faptr;
  309.   double        fargs[13];
  310. #endif
  311. #if defined(AMIGA)
  312.   /* store the arguments passed in registers in an extra array */
  313.   __avword        regargs[8+7];
  314. #endif
  315. } av_alist;
  316.  
  317. /* The limit for the pointer into the args[] array. */
  318. #if defined(__sparc__) || defined(__hppa__)
  319. #define __av_eptr(LIST)    ((LIST).eptr)
  320. #else
  321. #define __av_eptr(LIST)    (&(LIST).args[__AV_ALIST_WORDS])
  322. #endif
  323.  
  324.  
  325. /*
  326.  *  av_start_<type> macros which specify the return type
  327.  */
  328.  
  329. #define __AV_START_FLAGS  \
  330.   __AV_STRUCT_RETURN | __AV_FLOAT_RETURN | __AV_STRUCT_ARGS | __AV_FLOAT_ARGS | __AV_INTEGERS
  331.  
  332. #define __av_start(LIST,FUNC,RADDR,RETTYPE)                \
  333.   ((LIST).func = (int(*)())(FUNC),                    \
  334.    (LIST).raddr = (void*)(RADDR),                    \
  335.    (LIST).rtype = (RETTYPE),                        \
  336.    __av_start1(LIST)                            \
  337.    (LIST).flags = __AV_START_FLAGS)
  338.  
  339. #if defined(__i386__) || defined(__m68k__) || defined(__alpha__) || defined(__arm__) || defined(__m88k__) || defined(__convex__)
  340. #define __av_start1(LIST)                        \
  341.    (LIST).aptr = &(LIST).args[0],
  342. #endif
  343. #if defined(__sparc__)
  344. #define __av_start1(LIST)                        \
  345.    (LIST).aptr = &(LIST).args[0],                    \
  346.    (LIST).eptr = &(LIST).args[__AV_ALIST_WORDS],
  347. #endif
  348. #if defined(__mips__)
  349. #define __av_start1(LIST)                        \
  350.    (LIST).anum = 0,                            \
  351.    (LIST).aptr = &(LIST).args[0],
  352. #endif
  353. #if defined(__hppa__)
  354. #define __av_start1(LIST)                        \
  355.    (LIST).aptr = &(LIST).args[__AV_ALIST_WORDS],            \
  356.    (LIST).eptr = &(LIST).args[0],
  357. #endif
  358. #if defined(__rs6000__)
  359. #define __av_start1(LIST)                        \
  360.    (LIST).aptr = &(LIST).args[0],                    \
  361.    (LIST).faptr = &(LIST).fargs[0],
  362. #endif
  363.  
  364. #define av_start_void(LIST,FUNC)        __av_start(LIST,FUNC,0,    __AVvoid)
  365. #define av_start_char(LIST,FUNC,RADDR)        __av_start(LIST,FUNC,RADDR,__AVchar)
  366. #define av_start_schar(LIST,FUNC,RADDR)        __av_start(LIST,FUNC,RADDR,__AVschar)
  367. #define av_start_uchar(LIST,FUNC,RADDR)        __av_start(LIST,FUNC,RADDR,__AVuchar)
  368. #define av_start_short(LIST,FUNC,RADDR)        __av_start(LIST,FUNC,RADDR,__AVshort)
  369. #define av_start_ushort(LIST,FUNC,RADDR)    __av_start(LIST,FUNC,RADDR,__AVushort)
  370. #define av_start_int(LIST,FUNC,RADDR)        __av_start(LIST,FUNC,RADDR,__AVint)
  371. #define av_start_uint(LIST,FUNC,RADDR)        __av_start(LIST,FUNC,RADDR,__AVuint)
  372. #define av_start_long(LIST,FUNC,RADDR)        __av_start(LIST,FUNC,RADDR,__AVlong)
  373. #define av_start_ulong(LIST,FUNC,RADDR)        __av_start(LIST,FUNC,RADDR,__AVulong)
  374. #define av_start_float(LIST,FUNC,RADDR)        __av_start(LIST,FUNC,RADDR,__AVfloat)
  375. #define av_start_double(LIST,FUNC,RADDR)    __av_start(LIST,FUNC,RADDR,__AVdouble)
  376. #define av_start_ptr(LIST,FUNC,TYPE,RADDR)    __av_start(LIST,FUNC,RADDR,__AVvoidp)
  377.  
  378. #define av_start_struct(LIST,FUNC,TYPE,TYPE_SPLITTABLE,RADDR)        \
  379.   _av_start_struct(LIST,FUNC,sizeof(TYPE),TYPE_SPLITTABLE,RADDR)
  380. #define _av_start_struct(LIST,FUNC,TYPE_SIZE,TYPE_SPLITTABLE,RADDR)    \
  381.   (__av_start(LIST,FUNC,RADDR,__AVstruct),                \
  382.    (LIST).rsize = TYPE_SIZE,                        \
  383.    __av_start_struct1(LIST,TYPE_SIZE,TYPE_SPLITTABLE),            \
  384.    0)
  385.  
  386. #define __av_start_struct1(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
  387.   ((LIST).flags & __AV_PCC_STRUCT_RETURN                \
  388.    ? /* pcc struct return convention:                    \
  389.       * called function returns pointer to value, we'll copy its contents afterwards. \
  390.       */                                \
  391.      0                                    \
  392.    : __av_start_struct2(LIST,TYPE_SIZE,TYPE_SPLITTABLE)            \
  393.   )
  394. #if defined(__sparc__) || defined(__m88k__)
  395. /* Return structure pointer is passed in a special register.
  396.  */
  397. #define __av_start_struct2(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  0
  398. #else
  399. #define __av_start_struct2(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
  400.   (((LIST).flags & __AV_SMALL_STRUCT_RETURN)                \
  401.    && __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)        \
  402.    ? /* <= Word-sized structures are returned in a register. */        \
  403.      __av_start_struct3(LIST)                        \
  404.    : __av_start_struct4(LIST,TYPE_SIZE)                    \
  405.   )
  406. /* Determines whether a structure is returned in registers,
  407.  * depending on its size and its word-splittable flag.
  408.  */
  409. #if defined(__i386__) || defined(__m68k__) || defined(__arm__) || defined(__rs6000__) || defined(__convex__)
  410. #define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
  411.   ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4        \
  412.    || ((TYPE_SIZE) == 8 && (TYPE_SPLITTABLE)                \
  413.        && ((LIST).flags & __AV_GCC_STRUCT_RETURN)            \
  414.   )   )
  415. /* Turn on __AV_REGISTER_STRUCT_RETURN if __AV_SMALL_STRUCT_RETURN was set
  416.  * and the struct will actually be returned in registers.
  417.  */
  418. #define __av_start_struct3(LIST)  \
  419.   ((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0)
  420. #endif
  421. #if defined(__alpha__)
  422. #define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
  423.   ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 || (TYPE_SIZE) == 8    \
  424.    || ((TYPE_SIZE) == 16 && (TYPE_SPLITTABLE)                \
  425.        && ((LIST).flags & __AV_GCC_STRUCT_RETURN)            \
  426.   )   )
  427. /* Turn on __AV_REGISTER_STRUCT_RETURN if __AV_SMALL_STRUCT_RETURN was set
  428.  * and the struct will actually be returned in registers.
  429.  */
  430. #define __av_start_struct3(LIST)  \
  431.   ((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0)
  432. #endif
  433. #if defined(__hppa__)
  434. #define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
  435.   ((LIST).flags & __AV_GCC_STRUCT_RETURN                \
  436.    ? ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4)        \
  437.    : ((TYPE_SIZE) <= 8)                            \
  438.   )
  439. /* Test both __AV_GCC_STRUCT_RETURN and __AV_SMALL_STRUCT_RETURN at run time. */
  440. #define __av_start_struct3(LIST)  \
  441.   0
  442. #endif
  443. #if defined(__mips__)
  444. #define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
  445.   ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4)
  446. /* Test __AV_SMALL_STRUCT_RETURN instead of __AV_REGISTER_STRUCT_RETURN. */
  447. #define __av_start_struct3(LIST)  \
  448.   0
  449. #endif
  450. #if defined(__i386__)
  451. /* Return structure pointer is passed in a special register or as first arg. */
  452. #define __av_start_struct4(LIST,TYPE_SIZE)                \
  453.   ((LIST).flags & __AV_NEXTGCC_STRUCT_RETURN                \
  454.    ? 0                         /* special register */    \
  455.    : (*(LIST).aptr++ = (__avword)((LIST).raddr), 0)    /* first arg */    \
  456.   )
  457. #endif
  458. #if defined(__m68k__) || defined(__hppa__)
  459. /* Return structure pointer is passed in a special register.
  460.  */
  461. #define __av_start_struct4(LIST,TYPE_SIZE)  0
  462. #endif
  463. /* Return structure pointer is passed as first arg.
  464.  */
  465. #if defined(__alpha__) || defined(__arm__) || defined(__rs6000__) || defined(__convex__)
  466. #define __av_start_struct4(LIST,TYPE_SIZE)                \
  467.    (*(LIST).aptr++ = (__avword)((LIST).raddr), 0)
  468. #endif
  469. #if defined(__mips__)
  470. #define __av_start_struct4(LIST,TYPE_SIZE)                \
  471.    (*(LIST).aptr++ = (__avword)((LIST).raddr),                \
  472.     (LIST).anum++,                            \
  473.     0                                    \
  474.    )
  475. #endif
  476. #endif
  477.  
  478.  
  479. /*
  480.  * av_<type> macros which specify the argument and its type
  481.  */
  482.  
  483. /*
  484.  * scalar argument types
  485.  */
  486.  
  487. #if defined(__i386__) || defined(__m68k__) || defined(__sparc__) || defined(__alpha__) || defined(__arm__) || defined(__rs6000__) || defined(__m88k__) || defined(__convex__)
  488. /* Floats and all integer types are passed as words,
  489.  * doubles as two words.
  490.  */
  491. #define __av_word(LIST,VAL)                        \
  492.   (++(LIST).aptr > __av_eptr(LIST)                    \
  493.    ? -1 : ((LIST).aptr[-1] = (__avword)(VAL), 0))
  494. #endif
  495. #if defined(__mips__)
  496. /* Most things are passed as integers:
  497.  */
  498. #define __av_word(LIST,VAL)                        \
  499.   (++(LIST).aptr > __av_eptr(LIST)                    \
  500.    ? -1 : ((LIST).anum++, (LIST).aptr[-1] = (__avword)(VAL), 0))
  501. #endif
  502. #if defined(__hppa__)
  503. /* Floats and all integer types are passed as words,
  504.  * doubles as two words.
  505.  */
  506. #define __av_word(LIST,VAL)                        \
  507.   (--(LIST).aptr < __av_eptr(LIST)                    \
  508.    ? -1 : (*(LIST).aptr = (__avword)(VAL), 0))
  509. #endif
  510. #if defined(AMIGA)
  511. /* Some arguments are passed in registers. Query the macro AV_ARG_REGNUM.
  512.  * This should really be an argument to __av_word.
  513.  */
  514. #undef __av_word
  515. #define __av_word(LIST,VAL)                        \
  516.   ((AV_ARG_REGNUM) >= 0                            \
  517.    ? ((AV_ARG_REGNUM) < 8+7                        \
  518.       ? -1 : ((LIST).regargs[(AV_ARG_REGNUM)] = (__avword)(VAL), 0))    \
  519.    : (++(LIST).aptr > __av_eptr(LIST)                    \
  520.       ? -1 : ((LIST).aptr[-1] = (__avword)(VAL), 0)))
  521. #endif
  522.  
  523. /* integer argument types */
  524.  
  525. #define av_long            __av_word
  526. #define av_ulong(LIST,VAL)    __av_word(LIST,(unsigned long)(VAL))
  527. #define av_ptr(LIST,TYPE,VAL)    __av_word(LIST,(TYPE)(VAL))
  528. #define av_char            av_long
  529. #define av_schar        av_long
  530. #define av_short        av_long
  531. #define av_int            av_long
  532. #define av_uchar        av_ulong
  533. #define av_ushort        av_ulong
  534. #define av_uint            av_ulong
  535.  
  536. /* floating-point argument types */
  537.  
  538. #define av_float(LIST,VAL)                        \
  539.   ((LIST).flags & __AV_TRADITIONAL_FLOAT_ARGS                \
  540.    ? av_double(LIST,(float)(VAL))                    \
  541.    : __av_float(LIST,VAL))
  542.  
  543. #if defined(__i386__) || defined(__m68k__) || defined(__sparc__) || defined(__arm__) || defined(__convex__)
  544.  
  545. #define __av_float(LIST,VAL)                        \
  546.   (++(LIST).aptr > __av_eptr(LIST)                    \
  547.    ? -1 : (((float*)(LIST).aptr)[-1] = (float)(VAL), 0))
  548.  
  549. /* This assumes sizeof(double) == 2*sizeof(__avword). */
  550. #define av_double(LIST,VAL)                        \
  551.    (((LIST).aptr += 2) > __av_eptr(LIST)                \
  552.     ? -1 :                                \
  553.     ((LIST).tmp._double = (double)(VAL),                \
  554.      (LIST).aptr[-2] = (LIST).tmp.words[0],                \
  555.      (LIST).aptr[-1] = (LIST).tmp.words[1],                \
  556.      0))
  557.  
  558. #endif
  559.  
  560. #if defined(__mips__)
  561.  
  562. /* Up to 2 leading float or double non-varargs args can be passed in
  563.  * float registers, but we also push them into the corresponding int
  564.  * registers in case of varargs. For doubles we need to align the aptr
  565.  * to an even boundary.
  566.  */
  567. #define __av_float(LIST,VAL)                        \
  568.   (++(LIST).aptr > __av_eptr(LIST)                    \
  569.    ? -1 : ((++(LIST).anum == 1                        \
  570.         ? ((LIST).flags |= __AV_FLOAT_1,                \
  571.            ((float*)(LIST).floatarg)[1] = ((float*)(LIST).aptr)[-1] = (float)(VAL))\
  572.         : (LIST).anum == 2 && ((LIST).flags & __AV_FLOAT_1)        \
  573.         ? ((LIST).flags |= __AV_FLOAT_2,                \
  574.            ((float*)(LIST).floatarg)[3] = ((float*)(LIST).aptr)[-1] = (float)(VAL))\
  575.         : (*(float*)&(LIST).aptr[-1] = (float)(VAL))),        \
  576.        0))
  577.  
  578. #define av_double(LIST,VAL)                        \
  579.   (((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+15)&-8))        \
  580.    > __av_eptr(LIST)                            \
  581.    ? -1 : ((++(LIST).anum == 1                        \
  582.         ? ((LIST).flags |= __AV_FLOAT_1,                \
  583.            (LIST).floatarg[0] = ((double*)(LIST).aptr)[-1] = (double)(VAL))\
  584.         : (LIST).anum == 2 && ((LIST).flags & __AV_FLOAT_1)        \
  585.         ? ((LIST).flags |= __AV_FLOAT_2,                \
  586.            (LIST).floatarg[1] = ((double*)(LIST).aptr)[-1] = (double)(VAL))\
  587.         : (((double*)(LIST).aptr)[-1] = (double)(VAL))),        \
  588.        0))
  589.  
  590. #endif
  591.  
  592. #if defined(__alpha__)
  593.  
  594. #define av_double(LIST,VAL)                        \
  595.   (++(LIST).aptr > __av_eptr(LIST)                    \
  596.    ? -1 : (((double*)(LIST).aptr)[-1] = (double)(VAL), 0))
  597.  
  598. #define __av_float(LIST,VAL)                        \
  599.   (++(LIST).aptr > __av_eptr(LIST)                    \
  600.    ? -1                                    \
  601.    : (((LIST).aptr > &(LIST).args[6]                    \
  602.        ? /* These args will be fetched from memory using "lds" instructions */ \
  603.      /* therefore store them as floats */                \
  604.      (*(float*)((LIST).aptr-1) = (float)(VAL))            \
  605.        : /* The first 6 args will be put into registers by "ldt" instructions */ \
  606.      /* (see avcall-alpha.c!). Therefore store them as doubles. */    \
  607.      /* When viewed as floats, the value will be the correct one. */\
  608.      (*(double*)((LIST).aptr-1) = (double)(float)(VAL))        \
  609.      ), 0))
  610.  
  611. #endif
  612.  
  613. #if defined(__hppa__)
  614.  
  615. #define __av_float(LIST,VAL)                        \
  616.   (--(LIST).aptr < __av_eptr(LIST)                    \
  617.    ? -1 : (*(float*)(LIST).aptr = (float)(VAL), 0))
  618.  
  619. #define av_double(LIST,VAL)                        \
  620.   (((LIST).aptr = (__avword*)(((long)(LIST).aptr-sizeof(double)) & -(long)sizeof(double))) \
  621.     < __av_eptr(LIST)                            \
  622.     ? -1 : (*(double*)(LIST).aptr = (double)(VAL), 0))
  623.  
  624. #endif
  625.  
  626. #if defined(__rs6000__)
  627.  
  628. /* Up to 13 float or double non-varargs args can be passed in
  629.  * float registers, but we also push them into the corresponding int
  630.  * registers in case of varargs.
  631.  */
  632.  
  633. #define __av_float(LIST,VAL)                        \
  634.   (++(LIST).aptr > __av_eptr(LIST)                    \
  635.    ? -1 : (((float*)(LIST).aptr)[-1] = (float)(VAL),            \
  636.        (LIST).faptr < &(LIST).fargs[13] &&                \
  637.         (*(LIST).faptr++ = (double)(float)(VAL)),        \
  638.        0))
  639.  
  640. #define av_double(LIST,VAL)                        \
  641.    (((LIST).aptr += 2) > __av_eptr(LIST)                \
  642.     ? -1 :                                \
  643.     ((LIST).tmp._double = (double)(VAL),                \
  644.      (LIST).aptr[-2] = (LIST).tmp.words[0],                \
  645.      (LIST).aptr[-1] = (LIST).tmp.words[1],                \
  646.      (LIST).faptr < &(LIST).fargs[13] &&                \
  647.     (*(LIST).faptr++ = (LIST).tmp._double),                \
  648.      0))
  649.  
  650. #endif
  651.  
  652. #if defined(__m88k__)
  653.  
  654. #define __av_float(LIST,VAL)                        \
  655.   (++(LIST).aptr > __av_eptr(LIST)                    \
  656.    ? -1 : (((float*)(LIST).aptr)[-1] = (float)(VAL), 0))
  657.  
  658. #define av_double(LIST,VAL)                        \
  659.    (((LIST).aptr = (__avword*)(((long)(LIST).aptr+sizeof(double)+sizeof(double)-1) & -(long)sizeof(double))) \
  660.     > __av_eptr(LIST)                            \
  661.     ? -1 : (((double*)(LIST).aptr)[-1] = (double)(VAL), 0))
  662.  
  663. #endif
  664.  
  665. /*
  666.  * structure argument types
  667.  */
  668.  
  669. #define av_struct(LIST,TYPE,VAL)                    \
  670.   __av_struct(LIST,TYPE,sizeof(TYPE),__AV_alignof(TYPE),__av_struct_assign,VAL)
  671. #define __av_struct_assign(TYPE,TYPE_SIZE,TYPE_ALIGN,PLACE,VAL)        \
  672.   *(TYPE*)(PLACE) = (VAL)
  673. /* _av_struct() is like av_struct(), except that you pass the type's size and alignment
  674.  * and the value's address instead of the type and the value themselves.
  675.  */
  676. #define _av_struct(LIST,TYPE_SIZE,TYPE_ALIGN,VAL_ADDR)            \
  677.   __av_struct(LIST,unknown,TYPE_SIZE,TYPE_ALIGN,__av_struct_copy,VAL_ADDR)
  678. #define __av_struct_copy(TYPE,TYPE_SIZE,TYPE_ALIGN,PLACE,VAL_ADDR)    \
  679.   __structcpy(PLACE,VAL_ADDR,TYPE_SIZE,TYPE_ALIGN)
  680. #if defined(__i386__) || defined(__mips__) || defined(__alpha__) || defined(__rs6000__) || defined(__m88k__)
  681. /* Structures are passed as fully aligned structures on the arg stack.
  682.  * We align the aptr, store the structure, then fill to word alignment.
  683.  * Single-small-integer structures are NOT promoted to integers and have
  684.  * different alignment.
  685.  */
  686. /* little endian -> small structures < 1 word are adjusted to the left */
  687. #if defined(__i386__) || defined(__alpha__)
  688. #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)        \
  689.   (((LIST).aptr =                            \
  690.     (__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN)))\
  691.    > __av_eptr(LIST)                            \
  692.    ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
  693.        (LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(__avword)-1) & -(long)sizeof(__avword)),\
  694.        0))
  695. #endif
  696. /* small structures < 1 word are adjusted depending on compiler */
  697. #if defined(__mips__)
  698. #define __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
  699.   (((LIST).aptr =                            \
  700.     (__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN)))\
  701.    > __av_eptr(LIST)                            \
  702.    ? -1 : (++(LIST).anum,                        \
  703.        ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
  704.        (LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(__avword)-1) & -(long)sizeof(__avword)),\
  705.        0))
  706. #define __av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
  707.   (((LIST).aptr =                            \
  708.     (__avword*)(((((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN))\
  709.          +sizeof(__avword)-1) & -(long)sizeof(__avword)))    \
  710.    > __av_eptr(LIST)                            \
  711.    ? -1 : (++(LIST).anum,                        \
  712.        ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
  713.        0))
  714. #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)        \
  715.   ((LIST).flags & __AV_SGICC_STRUCT_ARGS                \
  716.    ? /* SGI MIPS cc passes small structures left-adjusted, although big-endian! */\
  717.      __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
  718.    : /* SGI MIPS gcc passes small structures within the first four words left-      \
  719.       * adjusted, for compatibility with cc. But structures in memory are passed  \
  720.       * right-adjusted!! See gcc-2.6.3/config/mips/mips.c:function_arg().      \
  721.       */                                      \
  722.      ((LIST).aptr < &(LIST).args[4]                        \
  723.       ? __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)    \
  724.       : __av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)))
  725. #endif
  726. #if defined(__rs6000__)
  727. #define __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)\
  728.   (((LIST).aptr =                            \
  729.     (__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN)))\
  730.    > __av_eptr(LIST)                            \
  731.    ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
  732.        (LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(__avword)-1) & -(long)sizeof(__avword)),\
  733.        0))
  734. #define __av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)\
  735.   (((LIST).aptr =                            \
  736.     (__avword*)(((((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN))\
  737.          +sizeof(__avword)-1) & -(long)sizeof(__avword)))    \
  738.    > __av_eptr(LIST)                            \
  739.    ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
  740.        0))
  741. #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)        \
  742.   ((LIST).flags & __AV_AIXCC_STRUCT_ARGS                \
  743.    ? /* AIX cc and xlc pass small structures left-adjusted, although big-endian! */\
  744.      __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
  745.    : /* gcc passes small structures right-adjusted. */            \
  746.      __av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL))
  747. #endif
  748. /* big endian -> small structures < 1 word are adjusted to the right */
  749. #if defined(__m88k__)
  750. #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)        \
  751.   (((LIST).aptr =                            \
  752.     (__avword*)(((((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN))\
  753.          +sizeof(__avword)-1) & -(long)sizeof(__avword)))    \
  754.    > __av_eptr(LIST)                            \
  755.    ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
  756.        0))
  757. #endif
  758. #endif
  759. #if defined(__m68k__) || defined(__arm__) || defined(__convex__)
  760. /* Structures are passed as embedded copies on the arg stack.
  761.  */
  762. #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)        \
  763.   (((LIST).aptr = (__avword*)(((long)(LIST).aptr+(TYPE_SIZE)+sizeof(__avword)-1) & -(long)sizeof(__avword))) \
  764.     > __av_eptr(LIST)                            \
  765.     ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
  766.         0))
  767. #endif
  768. #if defined(__sparc__)
  769. /* Structures are passed as pointers to caller-made local copies. We
  770.  * grab space for the copies from the end of the argument list space
  771.  * and always use maximal (double) alignment.
  772.  */
  773. #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)        \
  774.    (++(LIST).aptr                            \
  775.     > ((LIST).eptr = (__avword*)((long)(LIST).eptr - (((TYPE_SIZE)+7)&-8)))\
  776.     ? -1 :                                \
  777.     (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)(LIST).eptr,VAL),        \
  778.      (LIST).aptr[-1] = (__avword)(LIST).eptr,                \
  779.      0))
  780. #endif
  781. #if defined(__hppa__)
  782. /* Structures <= 8 bytes are passed as embedded copies on the arg stack.
  783.  * Big structures are passed as pointers to caller-made local copies.
  784.  */
  785. #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)            \
  786.   ((TYPE_SIZE) > 8                                \
  787.    ? (--(LIST).aptr                                \
  788.       < ((LIST).eptr = (__avword*)((long)(LIST).eptr + (((TYPE_SIZE) + 7) & -8))) \
  789.       ? -1                                    \
  790.       : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((long)(LIST).eptr - (((TYPE_SIZE) + 7) & -8)), VAL), \
  791.      *(LIST).aptr = (__avword)((long)(LIST).eptr - (((TYPE_SIZE) + 7) & -8)), \
  792.      0))                                    \
  793.    : ((TYPE_SIZE) > 4                                \
  794.       ? (((LIST).aptr = (__avword*)((((long)(LIST).aptr & -8) - (long)(TYPE_SIZE)) & -8)) \
  795.       < &(LIST).args[0]                            \
  796.       ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)(LIST).aptr,VAL), 0))    \
  797.       : /* FIXME: gcc-2.6.3 passes structures <= 4 bytes in memory left-adjusted! ?? */\
  798.         (((LIST).aptr = (__avword*)(((long)(LIST).aptr & -4) - (long)(TYPE_SIZE))) \
  799.       < &(LIST).args[0]                            \
  800.       ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)(LIST).aptr,VAL),    \
  801.           (LIST).aptr = (__avword*)((long)(LIST).aptr & -4),        \
  802.           0))))
  803. #endif
  804.  
  805. /*
  806.  * calling the function
  807.  */
  808.  
  809. #define av_call(LIST) __builtin_avcall(&(LIST))
  810.  
  811. /* Determine whether a struct type is word-splittable, i.e. whether each of
  812.  * its components fit into a register.
  813.  * The entire computation is done at compile time.
  814.  */
  815. #define av_word_splittable_1(slot1)  \
  816.   (__av_offset1(slot1)/sizeof(__avword) == (__av_offset1(slot1)+sizeof(slot1)-1)/sizeof(__avword))
  817. #define av_word_splittable_2(slot1,slot2)  \
  818.   ((__av_offset1(slot1)/sizeof(__avword) == (__av_offset1(slot1)+sizeof(slot1)-1)/sizeof(__avword)) \
  819.    && (__av_offset2(slot1,slot2)/sizeof(__avword) == (__av_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__avword)) \
  820.   )
  821. #define av_word_splittable_3(slot1,slot2,slot3)  \
  822.   ((__av_offset1(slot1)/sizeof(__avword) == (__av_offset1(slot1)+sizeof(slot1)-1)/sizeof(__avword)) \
  823.    && (__av_offset2(slot1,slot2)/sizeof(__avword) == (__av_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__avword)) \
  824.    && (__av_offset3(slot1,slot2,slot3)/sizeof(__avword) == (__av_offset3(slot1,slot2,slot3)+sizeof(slot3)-1)/sizeof(__avword)) \
  825.   )
  826. #define av_word_splittable_4(slot1,slot2,slot3,slot4)  \
  827.   ((__av_offset1(slot1)/sizeof(__avword) == (__av_offset1(slot1)+sizeof(slot1)-1)/sizeof(__avword)) \
  828.    && (__av_offset2(slot1,slot2)/sizeof(__avword) == (__av_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__avword)) \
  829.    && (__av_offset3(slot1,slot2,slot3)/sizeof(__avword) == (__av_offset3(slot1,slot2,slot3)+sizeof(slot3)-1)/sizeof(__avword)) \
  830.    && (__av_offset4(slot1,slot2,slot3,slot4)/sizeof(__avword) == (__av_offset4(slot1,slot2,slot3,slot4)+sizeof(slot4)-1)/sizeof(__avword)) \
  831.   )
  832. #define __av_offset1(slot1)  \
  833.   0
  834. #define __av_offset2(slot1,slot2)  \
  835.   ((__av_offset1(slot1)+sizeof(slot1)+__AV_alignof(slot2)-1) & -(long)__AV_alignof(slot2))
  836. #define __av_offset3(slot1,slot2,slot3)  \
  837.   ((__av_offset2(slot1,slot2)+sizeof(slot2)+__AV_alignof(slot3)-1) & -(long)__AV_alignof(slot3))
  838. #define __av_offset4(slot1,slot2,slot3,slot4)  \
  839.   ((__av_offset3(slot1,slot2,slot3)+sizeof(slot3)+__AV_alignof(slot4)-1) & -(long)__AV_alignof(slot4))
  840.  
  841. /*
  842.  * Miscellaneous declarations.
  843.  */
  844.  
  845. #if defined(__STDC__) || defined(__GNUC__)
  846. extern int __builtin_avcall (av_alist* l);
  847. extern void __structcpy (void* dest, void* src, unsigned long size, unsigned long alignment);
  848. #else
  849. extern int __builtin_avcall ();
  850. extern void __structcpy ();
  851. #endif
  852.  
  853. #endif /*_avcall_h */
  854.