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

信息检索与抽取

开发平台:

Unix_Linux

  1. #ifndef _avcall_h /*-*- C -*-*/
  2. #define _avcall_h
  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.   av_call() foreign function interface.
  13.   Varargs-style macros to build a C argument list incrementally
  14.   and call a function on it.
  15.  ----------------------------------------------------------------------*/
  16. /* These definitions are adjusted by `configure' automatically. */
  17. /* CPU */
  18. #ifndef __i386__
  19. #define __i386__ 1
  20. #endif
  21. #ifndef __m68k__
  22. #undef __m68k__
  23. #endif
  24. #ifndef __mips__
  25. #undef __mips__
  26. #endif
  27. #ifndef __mipsn32__
  28. #undef __mipsn32__
  29. #endif
  30. #ifndef __mips64__
  31. #undef __mips64__
  32. #endif
  33. #ifndef __sparc__
  34. #undef __sparc__
  35. #endif
  36. #ifndef __sparc64__
  37. #undef __sparc64__
  38. #endif
  39. #ifndef __alpha__
  40. #undef __alpha__
  41. #endif
  42. #ifndef __hppa__
  43. #undef __hppa__
  44. #endif
  45. #ifndef __arm__
  46. #undef __arm__
  47. #endif
  48. #ifndef __rs6000__
  49. #undef __rs6000__
  50. #endif
  51. #ifndef __m88k__
  52. #undef __m88k__
  53. #endif
  54. #ifndef __convex__
  55. #undef __convex__
  56. #endif
  57. #ifndef __ia64__
  58. #undef __ia64__
  59. #endif
  60. /* Darwin uses same ABI as AIX */
  61. #ifdef __APPLE__
  62. #define _AIX
  63. #endif
  64. /* Calling convention */
  65. /* Define if using pcc non-reentrant struct return convention */
  66. #undef __PCC_STRUCT_RETURN__
  67. /* Define if small structs are returned in registers */
  68. #define __SMALL_STRUCT_RETURN__ 1
  69. /* Define if floating-point results are returned in the integer registers */
  70. #undef __IREG_FLOAT_RETURN__
  71. /* CL_LONGLONG */
  72. /* Define if your compiler supports the `long long' type. */
  73. #undef HAVE_LONGLONG
  74. /* End of definitions adjusted by `configure'. */
  75. /* Max # words in argument-list and temporary structure storage.
  76.  */
  77. #ifndef __AV_ALIST_WORDS
  78. #define __AV_ALIST_WORDS  256
  79. #endif
  80. /* Determine the alignment of a type at compile time.
  81.  */
  82. #if defined(__GNUC__)
  83. #define __AV_alignof __alignof__
  84. #else
  85. #if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) /* SGI compiler */
  86. #define __AV_alignof __builtin_alignof
  87. #else
  88. #define __AV_offsetof(type,ident)  ((unsigned long)&(((type*)0)->ident))
  89. #define __AV_alignof(type)  __AV_offsetof(struct { char __slot1; type __slot2; }, __slot2)
  90. #endif
  91. #endif
  92. /* C builtin types.
  93.  */
  94. #if defined(__mipsn32__)
  95. typedef long long __avword;
  96. #else
  97. typedef long __avword;
  98. #endif
  99. enum __AVtype
  100. {
  101.   __AVword,
  102.   __AVvoid,
  103.   __AVchar,
  104.   __AVschar,
  105.   __AVuchar,
  106.   __AVshort,
  107.   __AVushort,
  108.   __AVint,
  109.   __AVuint,
  110.   __AVlong,
  111.   __AVulong,
  112.   __AVlonglong,
  113.   __AVulonglong,
  114.   __AVfloat,
  115.   __AVdouble,
  116.   __AVvoidp,
  117.   __AVstruct
  118. };
  119. enum __AV_alist_flags
  120. {
  121.   /* how to return structs */
  122.   /* There are basically 3 ways to return structs:
  123.    * a. The called function returns a pointer to static data. Not reentrant.
  124.    * b. The caller passes the return structure address in a dedicated register
  125.    *    or as a first (or last), invisible argument. The called function stores
  126.    *    its result there.
  127.    * c. Like b, and the called function also returns the return structure
  128.    *    address in the return value register. (This is not very distinguishable
  129.    *    from b.)
  130.    * Independently of this,
  131.    * r. small structures (<= 4 or <= 8 bytes) may be returned in the return
  132.    *    value register(s), or
  133.    * m. even small structures are passed in memory.
  134.    */
  135.   /* gcc-2.6.3 employs the following strategy:
  136.    *   - If PCC_STATIC_STRUCT_RETURN is defined in the machine description
  137.    *     it uses method a, else method c.
  138.    *   - If flag_pcc_struct_return is set (either by -fpcc-struct-return or if
  139.    *     DEFAULT_PCC_STRUCT_RETURN is defined to 1 in the machine description)
  140.    *     it uses method m, else (either by -freg-struct-return or if
  141.    *     DEFAULT_PCC_STRUCT_RETURN is defined to 0 in the machine description)
  142.    *     method r.
  143.    */
  144.   __AV_PCC_STRUCT_RETURN = 1<<0, /* a: need to copy the struct */
  145.   __AV_SMALL_STRUCT_RETURN = 1<<1, /* r: special case for small structs */
  146.   __AV_GCC_STRUCT_RETURN = 1<<2, /* consider 8 byte structs as small */
  147. #if defined(__sparc__) && !defined(__sparc64__)
  148.   __AV_SUNCC_STRUCT_RETURN = 1<<3,
  149.   __AV_SUNPROCC_STRUCT_RETURN = 1<<4,
  150. #endif
  151. #if defined(__i386__)
  152.   __AV_NEXTGCC_STRUCT_RETURN = 1<<3,
  153.   __AV_MSVC_STRUCT_RETURN = 1<<4,
  154. #endif
  155. #if defined(__hppa__)
  156.   __AV_OLDGCC_STRUCT_RETURN = 1<<3,
  157. #endif
  158.   /* the default way to return structs */
  159.   /* This choice here is based on the assumption that the function you are
  160.    * going to call has been compiled with the same compiler you are using to
  161.    * include this file.
  162.    * If you want to call functions with another struct returning convention,
  163.    * just  #define __AV_STRUCT_RETURN ...
  164.    * before or after #including <avcall.h>.
  165.    */
  166. #ifndef __AV_STRUCT_RETURN
  167.   __AV_STRUCT_RETURN =
  168. #if defined(__sparc__) && !defined(__sparc64__) && defined(sun) && defined(__SUNPRO_C) /* SUNWspro cc */
  169.   __AV_SUNPROCC_STRUCT_RETURN,
  170. #else
  171. #if defined(__PCC_STRUCT_RETURN__) /* defined through configure, see above */
  172.   __AV_PCC_STRUCT_RETURN |
  173. #if defined(__sparc__) && !defined(__sparc64__) && defined(sun) && !(defined(__STDC__) || defined(__GNUC__)) /* sun cc */
  174.      __AV_SUNCC_STRUCT_RETURN,
  175. #else
  176.      0,
  177. #endif
  178. #else
  179. #if defined(__SMALL_STRUCT_RETURN__) || defined(__mipsn32__) || defined(__mips64__) /* defined through configure, see above */
  180.   __AV_SMALL_STRUCT_RETURN |
  181. #endif
  182. #if defined(__GNUC__)
  183.   __AV_GCC_STRUCT_RETURN |
  184. #endif
  185. #if defined(__i386__) && defined(NeXT) && defined(__GNUC__) /* NeXT gcc-2.5.8 */
  186.   __AV_NEXTGCC_STRUCT_RETURN |
  187. #endif
  188. #if defined(__i386__) && defined(_MSC_VER) /* MSVC 4.0 */
  189.   __AV_MSVC_STRUCT_RETURN |
  190. #endif
  191. #if defined(__hppa__) && defined(__GNUC__) && (__GNUC_MINOR__ < 7)
  192.   __AV_OLDGCC_STRUCT_RETURN |
  193. #endif
  194.      0,
  195. #endif
  196. #endif
  197. #endif
  198.   /* how to return floats */
  199. #if defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__))
  200.   __AV_SUNCC_FLOAT_RETURN = 1<<5,
  201. #endif
  202. #if defined(__m68k__)
  203.   __AV_FREG_FLOAT_RETURN = 1<<6,
  204. #endif
  205.   /* the default way to return floats */
  206.   /* This choice here is based on the assumption that the function you are
  207.    * going to call has been compiled with the same compiler you are using to
  208.    * include this file.
  209.    * If you want to call functions with another float returning convention,
  210.    * just  #define __AV_FLOAT_RETURN ...
  211.    * before or after #including <avcall.h>.
  212.    */
  213. #ifndef __AV_FLOAT_RETURN
  214. #if (defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__))) && !defined(__GNUC__) && defined(sun) && !defined(__SUNPRO_C)  /* sun cc */
  215.   __AV_FLOAT_RETURN = __AV_SUNCC_FLOAT_RETURN,
  216. #elif (defined(__m68k__) && !defined(__IREG_FLOAT_RETURN__))
  217.   __AV_FLOAT_RETURN = __AV_FREG_FLOAT_RETURN,
  218. #else
  219.   __AV_FLOAT_RETURN = 0,
  220. #endif
  221. #endif
  222.   /* how to pass structs */
  223. #if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__)
  224.   __AV_SGICC_STRUCT_ARGS = 1<<7,
  225. #endif
  226. #if defined(__rs6000__)
  227.   __AV_AIXCC_STRUCT_ARGS = 1<<7,
  228. #endif
  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_STRUCT_ARGS ...
  235.    * before or after #including <avcall.h>.
  236.    */
  237. #ifndef __AV_STRUCT_ARGS
  238. #if (defined(__mips__) || defined(__mipsn32__) || defined(__mips64__)) && !defined(__GNUC__) /* SGI mips cc */
  239.   __AV_STRUCT_ARGS = __AV_SGICC_STRUCT_ARGS,
  240. #else
  241. #if defined(__rs6000__) && defined(_AIX) && !defined(__GNUC__) /* AIX cc, xlc */
  242.   __AV_STRUCT_ARGS = __AV_AIXCC_STRUCT_ARGS,
  243. #else
  244.   __AV_STRUCT_ARGS = 0,
  245. #endif
  246. #endif
  247. #endif
  248.   /* how to pass floats */
  249.   /* ANSI C compilers and GNU gcc pass floats as floats.
  250.    * K&R C compilers pass floats as doubles.
  251.    * (Except some compilers like SGI MIPS "cc" and "cc -cckr" if a prototype is
  252.    * known for the called functions. But to compile a program with prototypes,
  253.    * "cc -ansi" is better anyway.
  254.    */
  255.   __AV_ANSI_FLOAT_ARGS = 0,    /* pass floats as floats */
  256.   __AV_TRADITIONAL_FLOAT_ARGS = 1<<8, /* pass floats as doubles */
  257.   /* the default way to pass floats */
  258.   /* This choice here is based on the assumption that the function you are
  259.    * going to call has been compiled with the same compiler you are using to
  260.    * include this file.
  261.    * If you want to call functions with another float passing convention,
  262.    * just  #define __AV_FLOAT_ARGS ...
  263.    * before or after #including <avcall.h>.
  264.    */
  265. #ifndef __AV_FLOAT_ARGS
  266. #if defined(__STDC__) || defined(__GNUC__) /* what about hppa "cc -Aa" ?? */
  267.   __AV_FLOAT_ARGS = __AV_ANSI_FLOAT_ARGS,
  268. #else
  269.   __AV_FLOAT_ARGS = __AV_TRADITIONAL_FLOAT_ARGS,
  270. #endif
  271. #endif
  272.   /* how to pass and return small integer arguments */
  273.   __AV_ANSI_INTEGERS = 0, /* no promotions */
  274.   __AV_TRADITIONAL_INTEGERS = 0, /* promote [u]char, [u]short to [u]int */
  275.   /* Fortunately these two methods are compatible. Our macros work with both. */
  276.   /* the default way to pass and return small integer arguments */
  277.   /* This choice here is based on the assumption that the function you are
  278.    * going to call has been compiled with the same compiler you are using to
  279.    * include this file.
  280.    * If you want to call functions with another float passing convention,
  281.    * just  #define __AV_INTEGERS ...
  282.    * before or after #including <avcall.h>.
  283.    */
  284. #ifndef __AV_INTEGERS
  285. #if defined(__STDC__) || defined(__GNUC__)
  286.   __AV_INTEGERS = __AV_ANSI_INTEGERS,
  287. #else
  288.   __AV_INTEGERS = __AV_TRADITIONAL_INTEGERS,
  289. #endif
  290. #endif
  291.   /* stack cleanup policy */
  292.   __AV_CDECL_CLEANUP = 0, /* caller pops args after return */
  293.   __AV_STDCALL_CLEANUP = 0, /* callee pops args before return */
  294.      /* currently only supported on __i386__ */
  295. #ifndef __AV_CLEANUP
  296.   __AV_CLEANUP = __AV_CDECL_CLEANUP,
  297. #endif
  298.   /* These are for internal use only */
  299. #if defined(__i386__) || defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc64__) || defined(__alpha__) || defined(__arm__) || defined(__rs6000__) || defined(__convex__) || defined(__ia64__)
  300.   __AV_REGISTER_STRUCT_RETURN = 1<<9,
  301. #endif
  302. #if defined(__mips__) && !defined(__mipsn32__)
  303.   __AV_FLOAT_1 = 1<<10,
  304.   __AV_FLOAT_2 = 1<<11,
  305. #endif
  306.   __AV_flag_for_broken_compilers_that_dont_like_trailing_commas
  307. };
  308. typedef struct
  309. {
  310.   /* function to be called */
  311.   __avword (*func)();
  312.   /* some av_... macros need these flags */
  313.   int flags;
  314.   /* return type, address for the result */
  315.   void* raddr;
  316.   enum __AVtype rtype;
  317.   unsigned long rsize;
  318.   /* current pointer into the args[] array */
  319.   __avword* aptr;
  320. #if defined(__sparc__) || defined(__sparc64__) || defined(__hppa__) || (defined(__rs6000__) && !defined(_AIX))
  321.   /* limit pointer into the args[] array */
  322.   __avword* eptr;
  323. #endif
  324. #if defined(__i386__) && 0
  325.   /* Filler word, needed if the numbers of words up to now in this structure */
  326.   /* is odd (because on MSVC, alignof(double) = 8, normally = 4).            */
  327.   __avword filler1;
  328. #endif
  329. #if defined(__i386__) || defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__arm__) || defined(__rs6000__) || defined(__convex__)
  330.   /* temporary storage, used to split doubles into two words */
  331.   union {
  332.     double _double;
  333. #if defined(__sparc__) && !defined(__sparc64__) && defined(HAVE_LONGLONG)
  334.     long long _longlong;
  335. #endif
  336.     __avword words[2];
  337.   } tmp;
  338. #endif
  339. #if defined(__mips__) && !defined(__mipsn32__)
  340.   /* store the floating-point arguments in an extra array */
  341.   int anum;
  342.   double floatarg[2];
  343. #endif
  344. #if defined(__mipsn32__) || defined(__mips64__)
  345.   /* store the floating-point arguments in an extra array */
  346.   int anum; /* redundant: (LIST).aptr = &(LIST).args[(LIST).anum] */
  347.   unsigned int farg_mask; /* bitmask of those entries in farg[] which have a value */
  348.   unsigned int darg_mask; /* bitmask of those entries in args[] which have a double value */
  349.   float farg[8];
  350. #endif
  351. #if defined(__sparc64__)
  352.   /* store the floating-point arguments in an extra array */
  353.   int anum; /* redundant: (LIST).aptr = &(LIST).args[(LIST).anum] */
  354.   unsigned int farg_mask; /* bitmask of those entries in farg[] which have a value */
  355.   unsigned int darg_mask; /* bitmask of those entries in args[] which have a double value */
  356. #endif
  357. #if defined(__ia64__)
  358.   /* store the floating-point arguments in an extra array */
  359.   double* faptr;
  360.   double fargs[8];
  361. #endif
  362.   __avword args[__AV_ALIST_WORDS]; /* sizeof(double)-aligned */
  363. #if defined(__rs6000__)
  364.   /* store the floating-point arguments in an extra array */
  365.   double* faptr;
  366.   double fargs[13];
  367. #endif
  368. #if defined(AMIGA)
  369.   /* store the arguments passed in registers in an extra array */
  370.   __avword regargs[8+7];
  371. #endif
  372. } av_alist;
  373. /* The limit for the pointer into the args[] array. */
  374. #if defined(__sparc__) || defined(__sparc64__) || defined(__hppa__) || (defined(__rs6000__) && !defined(_AIX))
  375. #define __av_eptr(LIST) ((LIST).eptr)
  376. #else
  377. #define __av_eptr(LIST) (&(LIST).args[__AV_ALIST_WORDS])
  378. #endif
  379. /*
  380.  *  av_start_<type> macros which specify the return type
  381.  */
  382. #define __AV_START_FLAGS  
  383.   __AV_STRUCT_RETURN | __AV_FLOAT_RETURN | __AV_STRUCT_ARGS | __AV_FLOAT_ARGS | __AV_INTEGERS | __AV_CLEANUP
  384. #define __av_start(LIST,FUNC,RADDR,RETTYPE)
  385.   ((LIST).func = (__avword(*)())(FUNC),
  386.    (LIST).raddr = (void*)(RADDR),
  387.    (LIST).rtype = (RETTYPE),
  388.    __av_start1(LIST)
  389.    (LIST).flags = __AV_START_FLAGS)
  390. #if defined(__i386__) || defined(__m68k__) || defined(__alpha__) || defined(__arm__) || defined(__m88k__) || defined(__convex__)
  391. #define __av_start1(LIST)
  392.    (LIST).aptr = &(LIST).args[0],
  393. #endif
  394. #if defined(__mips__) && !defined(__mipsn32__)
  395. #define __av_start1(LIST)
  396.    (LIST).anum = 0,
  397.    (LIST).aptr = &(LIST).args[0],
  398. #endif
  399. #if defined(__mipsn32__) || defined(__mips64__)
  400. #define __av_start1(LIST)
  401.    (LIST).anum = 0,
  402.    (LIST).farg_mask = 0,
  403.    (LIST).darg_mask = 0,
  404.    (LIST).aptr = &(LIST).args[0],
  405. #endif
  406. #if defined(__sparc__) && !defined(__sparc64__)
  407. #define __av_start1(LIST)
  408.    (LIST).aptr = &(LIST).args[0],
  409.    (LIST).eptr = &(LIST).args[__AV_ALIST_WORDS],
  410. #endif
  411. #if defined(__sparc64__)
  412. #define __av_start1(LIST)
  413.    (LIST).anum = 0,
  414.    (LIST).farg_mask = 0,
  415.    (LIST).darg_mask = 0,
  416.    (LIST).aptr = &(LIST).args[0],
  417.    (LIST).eptr = &(LIST).args[__AV_ALIST_WORDS],
  418. #endif
  419. #if defined(__hppa__)
  420. #define __av_start1(LIST)
  421.    (LIST).aptr = &(LIST).args[__AV_ALIST_WORDS],
  422.    (LIST).eptr = &(LIST).args[0],
  423. #endif
  424. #if defined(__rs6000__)
  425. #if defined(_AIX)
  426. #define __av_start1(LIST)
  427.    (LIST).aptr = &(LIST).args[0],
  428.    (LIST).faptr = &(LIST).fargs[0],
  429. #else
  430. #define __av_start1(LIST)
  431.    (LIST).aptr = &(LIST).args[0],
  432.    (LIST).faptr = &(LIST).fargs[0],                                     
  433.    (LIST).eptr = &(LIST).args[__AV_ALIST_WORDS],
  434. #endif
  435. #endif
  436. #if defined(__ia64__)
  437. #define __av_start1(LIST)
  438.    (LIST).aptr = &(LIST).args[0],
  439.    (LIST).faptr = &(LIST).fargs[0],
  440. #endif
  441. #define av_start_void(LIST,FUNC) __av_start(LIST,FUNC,0,    __AVvoid)
  442. #define av_start_char(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVchar)
  443. #define av_start_schar(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVschar)
  444. #define av_start_uchar(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVuchar)
  445. #define av_start_short(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVshort)
  446. #define av_start_ushort(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVushort)
  447. #define av_start_int(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVint)
  448. #define av_start_uint(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVuint)
  449. #define av_start_long(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVlong)
  450. #define av_start_ulong(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVulong)
  451. #define av_start_longlong(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVlonglong)
  452. #define av_start_ulonglong(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVulonglong)
  453. #define av_start_float(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVfloat)
  454. #define av_start_double(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVdouble)
  455. #define av_start_ptr(LIST,FUNC,TYPE,RADDR) __av_start(LIST,FUNC,RADDR,__AVvoidp)
  456. #define av_start_struct(LIST,FUNC,TYPE,TYPE_SPLITTABLE,RADDR)
  457.   _av_start_struct(LIST,FUNC,sizeof(TYPE),TYPE_SPLITTABLE,RADDR)
  458. #define _av_start_struct(LIST,FUNC,TYPE_SIZE,TYPE_SPLITTABLE,RADDR)
  459.   (__av_start(LIST,FUNC,RADDR,__AVstruct),
  460.    (LIST).rsize = TYPE_SIZE,
  461.    __av_start_struct1(LIST,TYPE_SIZE,TYPE_SPLITTABLE),
  462.    0)
  463. #define __av_start_struct1(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  
  464.   ((LIST).flags & __AV_PCC_STRUCT_RETURN
  465.    ? /* pcc struct return convention:
  466.       * called function returns pointer to value, we'll copy its contents afterwards. 
  467.       */
  468.      0
  469.    : __av_start_struct2(LIST,TYPE_SIZE,TYPE_SPLITTABLE)
  470.   )
  471. #if (defined(__sparc__) && !defined(__sparc64__)) || defined(__m88k__)
  472. /* Return structure pointer is passed in a special register.
  473.  */
  474. #define __av_start_struct2(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  0
  475. #else
  476. #define __av_start_struct2(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  
  477.   (((LIST).flags & __AV_SMALL_STRUCT_RETURN)
  478.    && __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)
  479.    ? /* <= Word-sized structures are returned in a register. */
  480.      __av_start_struct3(LIST)
  481.    : __av_start_struct4(LIST,TYPE_SIZE)
  482.   )
  483. /* Determines whether a structure is returned in registers,
  484.  * depending on its size and its word-splittable flag.
  485.  */
  486. #if (defined(__i386__) && defined(_WIN32))
  487. #define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  
  488.   ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4
  489.    || ((TYPE_SIZE) == 8
  490.        && (((LIST).flags & __AV_MSVC_STRUCT_RETURN)
  491.            || ((TYPE_SPLITTABLE)
  492.                && ((LIST).flags & __AV_GCC_STRUCT_RETURN)
  493.   )   )   )   )
  494. /* Turn on __AV_REGISTER_STRUCT_RETURN if __AV_SMALL_STRUCT_RETURN was set
  495.  * and the struct will actually be returned in registers.
  496.  */
  497. #define __av_start_struct3(LIST)  
  498.   ((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0)
  499. #endif
  500. #if (defined(__i386__) && !defined(_WIN32)) || defined(__m68k__) || defined(__arm__) || defined(__rs6000__) || defined(__convex__)
  501. #define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  
  502.   ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4
  503.    || ((TYPE_SIZE) == 8 && (TYPE_SPLITTABLE)
  504.        && ((LIST).flags & __AV_GCC_STRUCT_RETURN)
  505.   )   )
  506. /* Turn on __AV_REGISTER_STRUCT_RETURN if __AV_SMALL_STRUCT_RETURN was set
  507.  * and the struct will actually be returned in registers.
  508.  */
  509. #define __av_start_struct3(LIST)  
  510.   ((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0)
  511. #endif
  512. #if defined(__alpha__)
  513. #define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  
  514.   ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 || (TYPE_SIZE) == 8
  515.    || ((TYPE_SIZE) == 16 && (TYPE_SPLITTABLE)
  516.        && ((LIST).flags & __AV_GCC_STRUCT_RETURN)
  517.   )   )
  518. /* Turn on __AV_REGISTER_STRUCT_RETURN if __AV_SMALL_STRUCT_RETURN was set
  519.  * and the struct will actually be returned in registers.
  520.  */
  521. #define __av_start_struct3(LIST)  
  522.   ((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0)
  523. #endif
  524. #if defined(__hppa__)
  525. #define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  
  526.   ((LIST).flags & __AV_OLDGCC_STRUCT_RETURN
  527.    ? ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4)
  528.    : ((TYPE_SIZE) <= 8)
  529.   )
  530. /* Test both __AV_OLDGCC_STRUCT_RETURN and __AV_SMALL_STRUCT_RETURN at run time. */
  531. #define __av_start_struct3(LIST)  
  532.   0
  533. #endif
  534. #if defined(__mips__) && !defined(__mipsn32__)
  535. #define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  
  536.   ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4)
  537. /* Test __AV_SMALL_STRUCT_RETURN instead of __AV_REGISTER_STRUCT_RETURN. */
  538. #define __av_start_struct3(LIST)  
  539.   0
  540. #endif
  541. #if defined(__mipsn32__) || defined(__mips64__)
  542. #define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  
  543.   ((LIST).flags & __AV_GCC_STRUCT_RETURN
  544.    ? ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 || (TYPE_SIZE) == 8) 
  545.    : ((TYPE_SIZE) <= 16)
  546.   )
  547. /* Turn on __AV_REGISTER_STRUCT_RETURN if __AV_SMALL_STRUCT_RETURN was set
  548.  * and the struct will actually be returned in registers.
  549.  */
  550. #define __av_start_struct3(LIST)  
  551.   ((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0)
  552. #endif
  553. #if defined(__sparc64__) || defined(__ia64__)
  554. #define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  
  555.   ((TYPE_SIZE) <= 32)
  556. /* Turn on __AV_REGISTER_STRUCT_RETURN if __AV_SMALL_STRUCT_RETURN was set
  557.  * and the struct will actually be returned in registers.
  558.  */
  559. #define __av_start_struct3(LIST)  
  560.   ((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0)
  561. #endif
  562. #if defined(__i386__)
  563. /* Return structure pointer is passed in a special register or as first arg. */
  564. #define __av_start_struct4(LIST,TYPE_SIZE)
  565.   ((LIST).flags & __AV_NEXTGCC_STRUCT_RETURN
  566.    ? 0  /* special register */
  567.    : (*(LIST).aptr++ = (__avword)((LIST).raddr), 0) /* first arg */
  568.   )
  569. #endif
  570. #if defined(__m68k__) || defined(__hppa__) || defined(__ia64__)
  571. /* Return structure pointer is passed in a special register.
  572.  */
  573. #define __av_start_struct4(LIST,TYPE_SIZE)  0
  574. #endif
  575. /* Return structure pointer is passed as first arg.
  576.  */
  577. #if defined(__alpha__) || defined(__arm__) || defined(__rs6000__) || defined(__convex__)
  578. #define __av_start_struct4(LIST,TYPE_SIZE)
  579.    (*(LIST).aptr++ = (__avword)((LIST).raddr), 0)
  580. #endif
  581. #if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc64__)
  582. #define __av_start_struct4(LIST,TYPE_SIZE)
  583.    (*(LIST).aptr++ = (__avword)((LIST).raddr),
  584.     (LIST).anum++,
  585.     0
  586.    )
  587. #endif
  588. #endif
  589. /*
  590.  * av_<type> macros which specify the argument and its type
  591.  */
  592. /*
  593.  * scalar argument types
  594.  */
  595. #if defined(__i386__) || defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__alpha__) || defined(__arm__) || defined(__rs6000__) || defined(__m88k__) || defined(__convex__) || defined(__ia64__)
  596. /* Floats and all integer types are passed as words,
  597.  * doubles as two words.
  598.  */
  599. #define __av_word(LIST,VAL)
  600.   (++(LIST).aptr > __av_eptr(LIST)
  601.    ? -1 : ((LIST).aptr[-1] = (__avword)(VAL), 0))
  602. #endif
  603. #if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc64__)
  604. /* Most things are passed as integers:
  605.  */
  606. #define __av_word(LIST,VAL)
  607.   (++(LIST).aptr > __av_eptr(LIST)
  608.    ? -1 : ((LIST).anum++, (LIST).aptr[-1] = (__avword)(VAL), 0))
  609. #endif
  610. #if defined(__hppa__)
  611. /* Floats and all integer types are passed as words,
  612.  * doubles as two words.
  613.  */
  614. #define __av_word(LIST,VAL)
  615.   (--(LIST).aptr < __av_eptr(LIST)
  616.    ? -1 : (*(LIST).aptr = (__avword)(VAL), 0))
  617. #endif
  618. #if defined(AMIGA)
  619. /* Some arguments are passed in registers. Query the macro AV_ARG_REGNUM.
  620.  * This should really be an argument to __av_word.
  621.  */
  622. #undef __av_word
  623. #define __av_word(LIST,VAL)
  624.   ((AV_ARG_REGNUM) >= 0
  625.    ? ((AV_ARG_REGNUM) < 8+7
  626.       ? -1 : ((LIST).regargs[(AV_ARG_REGNUM)] = (__avword)(VAL), 0))
  627.    : (++(LIST).aptr > __av_eptr(LIST)
  628.       ? -1 : ((LIST).aptr[-1] = (__avword)(VAL), 0)))
  629. #endif
  630. /* integer argument types */
  631. #define av_long __av_word
  632. #define av_ulong(LIST,VAL) __av_word(LIST,(unsigned long)(VAL))
  633. #define av_ptr(LIST,TYPE,VAL) __av_word(LIST,(TYPE)(VAL))
  634. #define av_char av_long
  635. #define av_schar av_long
  636. #define av_short av_long
  637. #define av_int av_long
  638. #define av_uchar av_ulong
  639. #define av_ushort av_ulong
  640. #define av_uint av_ulong
  641. #if defined(__mips64__) || defined(__sparc64__) || defined(__alpha__) || defined(__ia64__)
  642. /* `long long' and `long' are identical. */
  643. #define av_longlong av_long
  644. #define av_ulonglong av_ulong
  645. #elif defined(__mipsn32__)
  646. /* `long long' fits in __avword. */
  647. #define av_longlong __av_word
  648. #define av_ulonglong(LIST,VAL) __av_word(LIST,(unsigned long long)(VAL))
  649. #elif defined(__i386__) || defined(__m68k__) || defined(__mips__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__arm__) || defined(__rs6000__) || defined(__m88k__) || defined(__convex__)
  650. /* `long long's are passed embedded on the arg stack. */
  651. #define av_longlong(LIST,VAL) __av_longlong(LIST,long long,VAL)
  652. #define av_ulonglong(LIST,VAL) __av_longlong(LIST,unsigned long long,VAL)
  653. #if defined(__i386__) || defined(__m68k__) || defined(__arm__) || (defined(__rs6000__) && defined(_AIX)) || defined(__convex__)
  654. /* `long long's are (at most) word-aligned. */
  655. #define __av_longlong(LIST,TYPE,VAL)
  656.   (((LIST).aptr += sizeof(TYPE)/sizeof(__avword)) > __av_eptr(LIST)
  657.    ? -1 : (((TYPE*)(LIST).aptr)[-1] = (TYPE)(VAL), 0))
  658. #endif
  659. #if defined(__mips__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || (defined(__rs6000__) && !defined(_AIX)) || defined(__m88k__)
  660. /* `long long's have alignment 8. */
  661. #if defined(__mips__)
  662. #define __av_longlong(LIST,TYPE,VAL)
  663.   (((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(TYPE)+__AV_alignof(TYPE)-1) & -(long)__AV_alignof(TYPE))) > __av_eptr(LIST) 
  664.    ? -1 : ((LIST).anum++, ((TYPE*)(LIST).aptr)[-1] = (TYPE)(VAL), 0))
  665. #endif
  666. #if defined(__sparc__) && !defined(__sparc64__)
  667. /* Within the arg stack, the alignment is only 4, not 8. */
  668. /* This assumes sizeof(long long) == 2*sizeof(__avword). */
  669. #define __av_longlong(LIST,TYPE,VAL)
  670.   (((LIST).aptr += sizeof(TYPE)/sizeof(__avword)) > __av_eptr(LIST)
  671.    ? -1 :
  672.    ((LIST).tmp._longlong = (TYPE)(VAL),
  673.     (LIST).aptr[-2] = (LIST).tmp.words[0],
  674.     (LIST).aptr[-1] = (LIST).tmp.words[1],
  675.     0))
  676. #endif
  677. #if defined(__hppa__)
  678. #define __av_longlong(LIST,TYPE,VAL)
  679.   (((LIST).aptr = (__avword*)(((__avword)(LIST).aptr & -(long)__AV_alignof(TYPE)) - sizeof(TYPE))) < __av_eptr(LIST) 
  680.    ? -1 : (*(TYPE*)(LIST).aptr = (TYPE)(VAL), 0))
  681. #endif
  682. #if (defined(__rs6000__) && !defined(_AIX)) || defined(__m88k__)
  683. #define __av_longlong(LIST,TYPE,VAL)
  684.   (((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(TYPE)+__AV_alignof(TYPE)-1) & -(long)__AV_alignof(TYPE))) > __av_eptr(LIST) 
  685.    ? -1 : (((TYPE*)(LIST).aptr)[-1] = (TYPE)(VAL), 0))
  686. #endif
  687. #endif
  688. #endif
  689. /* floating-point argument types */
  690. #define av_float(LIST,VAL)
  691.   ((LIST).flags & __AV_TRADITIONAL_FLOAT_ARGS
  692.    ? av_double(LIST,(float)(VAL))
  693.    : __av_float(LIST,VAL))
  694. #if defined(__i386__) || defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__arm__) || defined(__convex__)
  695. #define __av_float(LIST,VAL)
  696.   (++(LIST).aptr > __av_eptr(LIST)
  697.    ? -1 : (((float*)(LIST).aptr)[-1] = (float)(VAL), 0))
  698. /* This assumes sizeof(double) == 2*sizeof(__avword). */
  699. #define av_double(LIST,VAL)
  700.    (((LIST).aptr += 2) > __av_eptr(LIST)
  701.     ? -1 :
  702.     ((LIST).tmp._double = (double)(VAL),
  703.      (LIST).aptr[-2] = (LIST).tmp.words[0],
  704.      (LIST).aptr[-1] = (LIST).tmp.words[1],
  705.      0))
  706. #endif
  707. #if defined(__mips__) && !defined(__mipsn32__)
  708. /* Up to 2 leading float or double non-varargs args can be passed in
  709.  * float registers, but we also push them into the corresponding int
  710.  * registers in case of varargs. For doubles we need to align the aptr
  711.  * to an even boundary.
  712.  */
  713. #define __av_float(LIST,VAL)
  714.   (++(LIST).aptr > __av_eptr(LIST)
  715.    ? -1 : ((++(LIST).anum == 1
  716.     ? ((LIST).flags |= __AV_FLOAT_1,
  717.        ((float*)(LIST).floatarg)[1] = ((float*)(LIST).aptr)[-1] = (float)(VAL))
  718.     : (LIST).anum == 2 && ((LIST).flags & __AV_FLOAT_1)
  719.     ? ((LIST).flags |= __AV_FLOAT_2,
  720.        ((float*)(LIST).floatarg)[3] = ((float*)(LIST).aptr)[-1] = (float)(VAL))
  721.     : (*(float*)&(LIST).aptr[-1] = (float)(VAL))),
  722.    0))
  723. #define av_double(LIST,VAL)
  724.   (((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+15)&-8))
  725.    > __av_eptr(LIST)
  726.    ? -1 : ((++(LIST).anum == 1
  727.     ? ((LIST).flags |= __AV_FLOAT_1,
  728.        (LIST).floatarg[0] = ((double*)(LIST).aptr)[-1] = (double)(VAL))
  729.     : (LIST).anum == 2 && ((LIST).flags & __AV_FLOAT_1)
  730.     ? ((LIST).flags |= __AV_FLOAT_2,
  731.        (LIST).floatarg[1] = ((double*)(LIST).aptr)[-1] = (double)(VAL))
  732.     : (((double*)(LIST).aptr)[-1] = (double)(VAL))),
  733.    0))
  734. #endif
  735. #if defined(__mipsn32__) || defined(__mips64__)
  736. /* Up to 8 leading float or double non-varargs args can be passed in
  737.  * float registers, but we also push them into the corresponding int
  738.  * registers in case of varargs.
  739.  */
  740. #define __av_float(LIST,VAL)
  741.   ((LIST).aptr >= __av_eptr(LIST)
  742.    ? -1 : (((LIST).anum < 8
  743.     ? ((LIST).farg_mask |= (1 << (LIST).anum),
  744.        (LIST).farg[(LIST).anum] = *(float*)(LIST).aptr = (float)(VAL)) 
  745.     : (*(float*)(LIST).aptr = (float)(VAL))),
  746.    (LIST).anum++,
  747.    (LIST).aptr++,
  748.    0))
  749. #define av_double(LIST,VAL)
  750.   ((LIST).aptr >= __av_eptr(LIST)
  751.    ? -1 : (((LIST).anum < 8 && ((LIST).darg_mask |= (1 << (LIST).anum))), 
  752.    *(double*)(LIST).aptr = (double)(VAL),
  753.    (LIST).anum++,
  754.    (LIST).aptr++,
  755.    0))
  756. #endif
  757. #if defined(__sparc64__)
  758. /* Up to 16 leading float or double non-varargs args can be passed in
  759.  * float registers, but we also push them into the corresponding int
  760.  * registers in case of varargs.
  761.  */
  762. #define __av_float(LIST,VAL)
  763.   ((LIST).aptr >= __av_eptr(LIST)
  764.    ? -1 : (((LIST).anum < 16 && ((LIST).farg_mask |= (1 << (LIST).anum))), 
  765.    (*(float*)(LIST).aptr = (float)(VAL)),
  766.    (LIST).anum++,
  767.    (LIST).aptr++,
  768.    0))
  769. #define av_double(LIST,VAL)
  770.   ((LIST).aptr >= __av_eptr(LIST)
  771.    ? -1 : (((LIST).anum < 16 && ((LIST).darg_mask |= (1 << (LIST).anum))), 
  772.    *(double*)(LIST).aptr = (double)(VAL),
  773.    (LIST).anum++,
  774.    (LIST).aptr++,
  775.    0))
  776. #endif
  777. #if defined(__alpha__)
  778. #define av_double(LIST,VAL)
  779.   (++(LIST).aptr > __av_eptr(LIST)
  780.    ? -1 : (((double*)(LIST).aptr)[-1] = (double)(VAL), 0))
  781. #define __av_float(LIST,VAL)
  782.   (++(LIST).aptr > __av_eptr(LIST)
  783.    ? -1
  784.    : (((LIST).aptr > &(LIST).args[6]
  785.        ? /* These args will be fetched from memory using "lds" instructions */ 
  786.  /* therefore store them as floats */
  787.  (*(float*)((LIST).aptr-1) = (float)(VAL))
  788.        : /* The first 6 args will be put into registers by "ldt" instructions */ 
  789.  /* (see avcall-alpha.c!). Therefore store them as doubles. */
  790.  /* When viewed as floats, the value will be the correct one. */
  791.  (*(double*)((LIST).aptr-1) = (double)(float)(VAL))
  792.      ), 0))
  793. #endif
  794. #if defined(__hppa__)
  795. #define __av_float(LIST,VAL)
  796.   (--(LIST).aptr < __av_eptr(LIST)
  797.    ? -1 : (*(float*)(LIST).aptr = (float)(VAL), 0))
  798. #define av_double(LIST,VAL)
  799.   (((LIST).aptr = (__avword*)(((long)(LIST).aptr-sizeof(double)) & -(long)sizeof(double))) 
  800.     < __av_eptr(LIST)
  801.     ? -1 : (*(double*)(LIST).aptr = (double)(VAL), 0))
  802. #endif
  803. #if defined(__rs6000__) && defined(_AIX)
  804. /* Up to 13 float or double non-varargs args can be passed in
  805.  * float registers, but we also push them into the corresponding int
  806.  * registers in case of varargs.
  807.  */
  808. #define __av_float(LIST,VAL)
  809.   (++(LIST).aptr > __av_eptr(LIST)
  810.    ? -1 : (((float*)(LIST).aptr)[-1] = (float)(VAL),
  811.    (LIST).faptr < &(LIST).fargs[13] &&
  812. (*(LIST).faptr++ = (double)(float)(VAL)),
  813.    0))
  814. #define av_double(LIST,VAL)
  815.    (((LIST).aptr += 2) > __av_eptr(LIST)
  816.     ? -1 :
  817.     ((LIST).tmp._double = (double)(VAL),
  818.      (LIST).aptr[-2] = (LIST).tmp.words[0],
  819.      (LIST).aptr[-1] = (LIST).tmp.words[1],
  820.      (LIST).faptr < &(LIST).fargs[13] &&
  821. (*(LIST).faptr++ = (LIST).tmp._double),
  822.      0))
  823. #endif
  824. #if defined(__rs6000__) && !defined(_AIX)
  825. /* Up to 8 float or double non-varargs args can be passed in
  826.  * float registers, without occupying space in the general registers.
  827.  */
  828. #define __av_float(LIST,VAL)
  829.   ((LIST).faptr < &(LIST).fargs[8]
  830.    ? ((*(LIST).faptr++ = (double)(float)(VAL)), 0)
  831.    : (++(LIST).aptr > __av_eptr(LIST)
  832.       ? -1 : (((float*)(LIST).aptr)[-1] = (float)(VAL), 0)))
  833. #define av_double(LIST,VAL)
  834.   ((LIST).faptr < &(LIST).fargs[8]
  835.    ? ((*(LIST).faptr++ = (double)(VAL)), 0)
  836.    : (((LIST).aptr += 2) > __av_eptr(LIST)
  837.       ? -1 :
  838.       ((LIST).tmp._double = (double)(VAL),
  839.        (LIST).aptr[-2] = (LIST).tmp.words[0],
  840.        (LIST).aptr[-1] = (LIST).tmp.words[1],
  841.        0)))
  842. #endif
  843. #if defined(__m88k__)
  844. #define __av_float(LIST,VAL)
  845.   (++(LIST).aptr > __av_eptr(LIST)
  846.    ? -1 : (((float*)(LIST).aptr)[-1] = (float)(VAL), 0))
  847. #define av_double(LIST,VAL)
  848.    (((LIST).aptr = (__avword*)(((long)(LIST).aptr+sizeof(double)+sizeof(double)-1) & -(long)sizeof(double))) 
  849.     > __av_eptr(LIST)
  850.     ? -1 : (((double*)(LIST).aptr)[-1] = (double)(VAL), 0))
  851. #endif
  852. #if defined(__ia64__)
  853. /* Up to 8 leading float or double non-varargs args can be passed in
  854.  * float registers, but we also push them into the corresponding int
  855.  * registers in case of varargs.
  856.  */
  857. #define __av_float(LIST,VAL)
  858.   ((LIST).aptr >= __av_eptr(LIST)
  859.    ? -1 : ((*(float*)(LIST).aptr = (float)(VAL)),
  860.    ((LIST).faptr < &(LIST).fargs[8] && (*(LIST).faptr = *(float*)(LIST).aptr, (LIST).faptr++)), 
  861.    (LIST).aptr++,
  862.    0))
  863. #define av_double(LIST,VAL)
  864.   ((LIST).aptr >= __av_eptr(LIST)
  865.    ? -1 : (*(double*)(LIST).aptr = (double)(VAL),
  866.    ((LIST).faptr < &(LIST).fargs[8] && (*(LIST).faptr = *(double*)(LIST).aptr, (LIST).faptr++)), 
  867.    (LIST).aptr++,
  868.    0))
  869. #endif
  870. /*
  871.  * structure argument types
  872.  */
  873. #define av_struct(LIST,TYPE,VAL)
  874.   __av_struct(LIST,TYPE,sizeof(TYPE),__AV_alignof(TYPE),__av_struct_assign,VAL)
  875. #define __av_struct_assign(TYPE,TYPE_SIZE,TYPE_ALIGN,PLACE,VAL)
  876.   *(TYPE*)(PLACE) = (VAL)
  877. /* _av_struct() is like av_struct(), except that you pass the type's size and alignment
  878.  * and the value's address instead of the type and the value themselves.
  879.  */
  880. #define _av_struct(LIST,TYPE_SIZE,TYPE_ALIGN,VAL_ADDR)
  881.   __av_struct(LIST,unknown,TYPE_SIZE,TYPE_ALIGN,__av_struct_copy,VAL_ADDR)
  882. #define __av_struct_copy(TYPE,TYPE_SIZE,TYPE_ALIGN,PLACE,VAL_ADDR)
  883.   __structcpy(PLACE,VAL_ADDR,TYPE_SIZE,TYPE_ALIGN)
  884. /* Structure argument alignment. */
  885. #if defined(__i386__) && defined(_MSC_VER)
  886. /* In MSVC, doubles inside structures have alignment 8, i.e.
  887.  * __AV_alignof(double) = 8, but doubles (and also structures containing
  888.  * doubles) are passed on the stack with alignment 4. Looks really weird.
  889.  */
  890. #define __av_struct_alignment(TYPE_ALIGN)  
  891.   ((TYPE_ALIGN) <= 4 ? (TYPE_ALIGN) : 4)
  892. #else
  893. #define __av_struct_alignment(TYPE_ALIGN)  
  894.   (TYPE_ALIGN)
  895. #endif
  896. #if defined(__i386__) || defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) || defined(__alpha__) || (defined(__rs6000__) && defined(_AIX)) || defined(__m88k__) || defined(__ia64__)
  897. /* Structures are passed as fully aligned structures on the arg stack.
  898.  * We align the aptr, store the structure, then fill to word alignment.
  899.  * Single-small-integer structures are NOT promoted to integers and have
  900.  * different alignment.
  901.  */
  902. /* little endian -> small structures < 1 word are adjusted to the left */
  903. #if defined(__i386__) || defined(__alpha__)
  904. #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)
  905.   (((LIST).aptr =
  906.     (__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+__av_struct_alignment(TYPE_ALIGN)-1) & -(long)__av_struct_alignment(TYPE_ALIGN)))
  907.    > __av_eptr(LIST)
  908.    ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),
  909.    (LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(__avword)-1) & -(long)sizeof(__avword)),
  910.    0))
  911. #endif
  912. #if defined(__ia64__)
  913. /* Types larger than a word have 2-word alignment. */
  914. #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)
  915.   ((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+__av_struct_alignment(TYPE_ALIGN)-1) & -(long)__av_struct_alignment(TYPE_ALIGN)), 
  916.    ((TYPE_SIZE) > sizeof(__avword) && (((LIST).aptr - &(LIST).args[0]) & 1) ? ++(LIST).aptr : 0), 
  917.    ((LIST).aptr > __av_eptr(LIST)
  918.     ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),
  919.     (LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(__avword)-1) & -(long)sizeof(__avword)),
  920.     0)))
  921. #endif
  922. /* small structures < 1 word are adjusted depending on compiler */
  923. #if defined(__mips__) && !defined(__mipsn32__)
  924. #define __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) 
  925.   (((LIST).aptr =
  926.     (__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN)))
  927.    > __av_eptr(LIST)
  928.    ? -1 : (++(LIST).anum,
  929.    ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),
  930.    (LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(__avword)-1) & -(long)sizeof(__avword)),
  931.    0))
  932. #define __av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) 
  933.   (((LIST).aptr =
  934.     (__avword*)(((((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN))
  935.  +sizeof(__avword)-1) & -(long)sizeof(__avword)))
  936.    > __av_eptr(LIST)
  937.    ? -1 : (++(LIST).anum,
  938.    ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),
  939.    0))
  940. #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)
  941.   ((LIST).flags & __AV_SGICC_STRUCT_ARGS
  942.    ? /* SGI MIPS cc passes small structures left-adjusted, although big-endian! */
  943.      __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) 
  944.    : /* SGI MIPS gcc passes small structures within the first four words left-   
  945.       * adjusted, for compatibility with cc. But structures in memory are passed  
  946.       * right-adjusted!! See gcc-2.6.3/config/mips/mips.c:function_arg().   
  947.       */   
  948.      ((LIST).aptr < &(LIST).args[4]
  949.       ? __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)
  950.       : __av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)))
  951. #endif
  952. #if defined(__mipsn32__) || defined(__mips64__)
  953. /* When a structure is passed (partially) in registers, it is passed in the
  954.  * integer registers, except that doubles within the structure are passed in
  955.  * the floating point registers. Instead of distinguishing these cases, we
  956.  * always pass the structure in both the integer and the floating point
  957.  * registers.
  958.  */
  959. #define __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) 
  960.   (((LIST).aptr =
  961.     (__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN)))
  962.    > __av_eptr(LIST)
  963.    ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),
  964.    (LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(__avword)-1) & -(long)sizeof(__avword)),
  965.    ((LIST).anum < 8 && ((LIST).darg_mask |= (-1 << (LIST).anum))), 
  966.    (LIST).anum += (((((TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN)) + sizeof(__avword)-1) & -(long)sizeof(__avword))/sizeof(__avword),
  967.    (LIST).darg_mask &= (1 << ((LIST).anum < 8 ? (LIST).anum : 8)) - 1, 
  968.    0))
  969. #define __av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) 
  970.   (((LIST).aptr =
  971.     (__avword*)(((((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN))
  972.  +sizeof(__avword)-1) & -(long)sizeof(__avword)))
  973.    > __av_eptr(LIST)
  974.    ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),
  975.    ((LIST).anum < 8 && ((LIST).darg_mask |= (-1 << (LIST).anum))), 
  976.    (LIST).anum += (((((TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN)) + sizeof(__avword)-1) & -(long)sizeof(__avword))/sizeof(__avword),
  977.    (LIST).darg_mask &= (1 << ((LIST).anum < 8 ? (LIST).anum : 8)) - 1, 
  978.    0))
  979. #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)
  980.   ((LIST).flags & __AV_SGICC_STRUCT_ARGS
  981.    ? /* SGI MIPS cc passes small structures left-adjusted, although big-endian! */
  982.      __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) 
  983.    : /* SGI MIPS gcc passes small structures right-adjusted. */
  984.      __av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL))
  985. #endif
  986. #if defined(__rs6000__)
  987. #define __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)
  988.   (((LIST).aptr =
  989.     (__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN)))
  990.    > __av_eptr(LIST)
  991.    ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),
  992.    (LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(__avword)-1) & -(long)sizeof(__avword)),
  993.    0))
  994. #define __av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)
  995.   (((LIST).aptr =
  996.     (__avword*)(((((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN))
  997.  +sizeof(__avword)-1) & -(long)sizeof(__avword)))
  998.    > __av_eptr(LIST)
  999.    ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),
  1000.    0))
  1001. #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)
  1002.   ((LIST).flags & __AV_AIXCC_STRUCT_ARGS
  1003.    ? /* AIX cc and xlc pass small structures left-adjusted, although big-endian! */
  1004.      __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) 
  1005.    : /* gcc passes small structures right-adjusted. */
  1006.      __av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL))
  1007. #endif
  1008. /* big endian -> small structures < 1 word are adjusted to the right */
  1009. #if defined(__m88k__)
  1010. #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)
  1011.   (((LIST).aptr =
  1012.     (__avword*)(((((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN))
  1013.  +sizeof(__avword)-1) & -(long)sizeof(__avword)))
  1014.    > __av_eptr(LIST)
  1015.    ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),
  1016.    0))
  1017. #endif
  1018. #endif
  1019. #if defined(__m68k__) || defined(__arm__) || defined(__convex__)
  1020. /* Structures are passed as embedded copies on the arg stack.
  1021.  */
  1022. #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)
  1023.   (((LIST).aptr = (__avword*)(((long)(LIST).aptr+(TYPE_SIZE)+sizeof(__avword)-1) & -(long)sizeof(__avword))) 
  1024.     > __av_eptr(LIST)
  1025.     ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),
  1026.     0))
  1027. #endif
  1028. #if (defined(__sparc__) && !defined(__sparc64__)) || (defined(__rs6000__) && !defined(_AIX))
  1029. /* Structures are passed as pointers to caller-made local copies. We
  1030.  * grab space for the copies from the end of the argument list space
  1031.  * and always use maximal (double) alignment.
  1032.  */
  1033. #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)
  1034.    (++(LIST).aptr
  1035.     > ((LIST).eptr = (__avword*)((long)(LIST).eptr - (((TYPE_SIZE)+7)&-8)))
  1036.     ? -1 :
  1037.     (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)(LIST).eptr,VAL),
  1038.      (LIST).aptr[-1] = (__avword)(LIST).eptr,
  1039.      0))
  1040. #endif
  1041. #if defined(__sparc64__)
  1042. /* Structures <= 16 bytes are passed as embedded copies on the arg stack,
  1043.  * left-adjusted (although big-endian!).
  1044.  * When a structure is passed (partially) in registers, it is passed in the
  1045.  * integer registers, except that floats and doubles within the structure
  1046.  * are passed in the floating point registers. Instead of distinguishing
  1047.  * these cases, we always pass the structure in both the integer and the
  1048.  * floating point registers.
  1049.  * Big structures are passed as pointers to caller-made local copies.
  1050.  * FIXME: Shouldn't (LIST).anum be incremented in sync with (LIST).aptr ?
  1051.  */
  1052. #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)
  1053.   ((TYPE_SIZE) > 16
  1054.    ? (++(LIST).aptr
  1055.       > ((LIST).eptr = (__avword*)((long)(LIST).eptr - (((TYPE_SIZE)+7)&-8)))
  1056.       ? -1 :
  1057.       (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)(LIST).eptr,VAL),
  1058.        (LIST).aptr[-1] = (__avword)(LIST).eptr,
  1059.        0))
  1060.    : (((LIST).aptr =
  1061.        (__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN)))
  1062.       > __av_eptr(LIST)
  1063.       ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),
  1064.       (LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(__avword)-1) & -(long)sizeof(__avword)),
  1065.       ((LIST).anum < 16
  1066. && ((LIST).farg_mask |= (-1 << (LIST).anum),
  1067.     (LIST).darg_mask |= (-1 << (LIST).anum))),
  1068.       (LIST).anum += (((((TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN)) + sizeof(__avword)-1) & -(long)sizeof(__avword))/sizeof(__avword),
  1069.       (LIST).farg_mask &= (1 << ((LIST).anum < 16 ? (LIST).anum : 16)) - 1, 
  1070.       (LIST).darg_mask &= (1 << ((LIST).anum < 16 ? (LIST).anum : 16)) - 1, 
  1071.       0)))
  1072. #endif
  1073. #if defined(__hppa__)
  1074. /* Structures <= 8 bytes are passed as embedded copies on the arg stack.
  1075.  * Big structures are passed as pointers to caller-made local copies.
  1076.  */
  1077. #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)
  1078.   ((TYPE_SIZE) > 8
  1079.    ? (--(LIST).aptr
  1080.       < ((LIST).eptr = (__avword*)((long)(LIST).eptr + (((TYPE_SIZE) + 7) & -8))) 
  1081.       ? -1
  1082.       : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((long)(LIST).eptr - (((TYPE_SIZE) + 7) & -8)), VAL), 
  1083.  *(LIST).aptr = (__avword)((long)(LIST).eptr - (((TYPE_SIZE) + 7) & -8)), 
  1084.  0))
  1085.    : ((TYPE_SIZE) > 4
  1086.       ? (((LIST).aptr = (__avword*)((((long)(LIST).aptr & -8) - (long)(TYPE_SIZE)) & -8)) 
  1087.   < &(LIST).args[0]
  1088.   ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)(LIST).aptr,VAL), 0))
  1089.       : /* FIXME: gcc-2.6.3 passes structures <= 4 bytes in memory left-adjusted! ?? */
  1090.         (((LIST).aptr = (__avword*)(((long)(LIST).aptr & -4) - (long)(TYPE_SIZE))) 
  1091.   < &(LIST).args[0]
  1092.   ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)(LIST).aptr,VAL),
  1093.   (LIST).aptr = (__avword*)((long)(LIST).aptr & -4),
  1094.   0))))
  1095. #endif
  1096. /*
  1097.  * calling the function
  1098.  */
  1099. #define av_call(LIST) __builtin_avcall(&(LIST))
  1100. /* Determine whether a struct type is word-splittable, i.e. whether each of
  1101.  * its components fit into a register.
  1102.  * The entire computation is done at compile time.
  1103.  */
  1104. #define av_word_splittable_1(slot1)  
  1105.   (__av_offset1(slot1)/sizeof(__avword) == (__av_offset1(slot1)+sizeof(slot1)-1)/sizeof(__avword))
  1106. #define av_word_splittable_2(slot1,slot2)  
  1107.   ((__av_offset1(slot1)/sizeof(__avword) == (__av_offset1(slot1)+sizeof(slot1)-1)/sizeof(__avword)) 
  1108.    && (__av_offset2(slot1,slot2)/sizeof(__avword) == (__av_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__avword)) 
  1109.   )
  1110. #define av_word_splittable_3(slot1,slot2,slot3)  
  1111.   ((__av_offset1(slot1)/sizeof(__avword) == (__av_offset1(slot1)+sizeof(slot1)-1)/sizeof(__avword)) 
  1112.    && (__av_offset2(slot1,slot2)/sizeof(__avword) == (__av_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__avword)) 
  1113.    && (__av_offset3(slot1,slot2,slot3)/sizeof(__avword) == (__av_offset3(slot1,slot2,slot3)+sizeof(slot3)-1)/sizeof(__avword)) 
  1114.   )
  1115. #define av_word_splittable_4(slot1,slot2,slot3,slot4)  
  1116.   ((__av_offset1(slot1)/sizeof(__avword) == (__av_offset1(slot1)+sizeof(slot1)-1)/sizeof(__avword)) 
  1117.    && (__av_offset2(slot1,slot2)/sizeof(__avword) == (__av_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__avword)) 
  1118.    && (__av_offset3(slot1,slot2,slot3)/sizeof(__avword) == (__av_offset3(slot1,slot2,slot3)+sizeof(slot3)-1)/sizeof(__avword)) 
  1119.    && (__av_offset4(slot1,slot2,slot3,slot4)/sizeof(__avword) == (__av_offset4(slot1,slot2,slot3,slot4)+sizeof(slot4)-1)/sizeof(__avword)) 
  1120.   )
  1121. #define __av_offset1(slot1)  
  1122.   0
  1123. #define __av_offset2(slot1,slot2)  
  1124.   ((__av_offset1(slot1)+sizeof(slot1)+__AV_alignof(slot2)-1) & -(long)__AV_alignof(slot2))
  1125. #define __av_offset3(slot1,slot2,slot3)  
  1126.   ((__av_offset2(slot1,slot2)+sizeof(slot2)+__AV_alignof(slot3)-1) & -(long)__AV_alignof(slot3))
  1127. #define __av_offset4(slot1,slot2,slot3,slot4)  
  1128.   ((__av_offset3(slot1,slot2,slot3)+sizeof(slot3)+__AV_alignof(slot4)-1) & -(long)__AV_alignof(slot4))
  1129. /*
  1130.  * Miscellaneous declarations.
  1131.  */
  1132. #if defined(__STDC__) || defined(__GNUC__) || defined(__cplusplus)
  1133. extern int __builtin_avcall (av_alist* l);
  1134. extern void __structcpy (void* dest, void* src, unsigned long size, unsigned long alignment);
  1135. #else
  1136. extern int __builtin_avcall ();
  1137. extern void __structcpy ();
  1138. #endif
  1139. #endif /*_avcall_h */