home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / CLISP-2.LHA / CLISP960530-ki.lha / ffcall / avcall / avcall.h < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-04  |  31.3 KB  |  855 lines

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