home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / gnu / gcc / help / 2018 < prev    next >
Encoding:
Text File  |  1992-08-31  |  7.7 KB  |  163 lines

  1. Newsgroups: gnu.gcc.help
  2. Path: sparky!uunet!stanford.edu!ames!haven.umd.edu!darwin.sura.net!wupost!gumby!destroyer!ncar!csn!news.den.mmc.com!traffic!kevin
  3. From: kevin@traffic.den.mmc.com (Kevin Rodgers)
  4. Subject: Re: gcc-2.2.2: varargs problem?
  5. Message-ID: <1992Aug31.160101.15510@den.mmc.com>
  6. Sender: news@den.mmc.com (News)
  7. Nntp-Posting-Host: traffic.den.mmc.com
  8. Organization: Martin Marietta Western Internal Systems, Technical Operations
  9. References: <1992Aug28.215327.2534@unixg.ubc.ca>
  10. Date: Mon, 31 Aug 1992 16:01:01 GMT
  11. Lines: 150
  12.  
  13. In article <1992Aug28.215327.2534@unixg.ubc.ca> lindholm@ucs.ubc.ca (George Lindholm) writes:
  14. >How do I prototype and define a procedure that takes a variable number of
  15. >arguments?
  16.  
  17. Here's the beginning of the relevant Info node:
  18.  
  19. |File: gcc.info,  Node: Varargs,  Next: Trampolines,  Prev: Stack and Calling,  Up: Target Macros
  20. |
  21. |Implementing the Varargs Macros
  22. |===============================
  23. |
  24. |   GNU CC comes with an implementation of `varargs.h' and `stdarg.h'
  25. |that work without change on machines that pass arguments on the stack. 
  26. |Other machines require their own implementations of varargs, and the
  27. |two machine independent header files must have conditionals to include
  28. |it.
  29. |
  30. |   ANSI `stdarg.h' differs from traditional `varargs.h' mainly in the
  31. |calling convention for `va_start'.  The traditional implementation
  32. |takes just one argument, which is the variable in which to store the
  33. |argument pointer.  The ANSI implementation of `va_start' takes an
  34. |additional second argument.  The user is supposed to write the last
  35. |named argument of the function here.
  36. |
  37. |   However, `va_start' should not use this argument.  The way to find
  38. |the end of the named arguments is with the built-in functions described
  39. |below.
  40.  
  41. What is the justification for these last two sentences?  Gcc 2.2.2 seems
  42. to compile vanilla ANSI stdarg code (under SunOS 4.1.1) just fine.
  43.  
  44. And FYI, here's the rest of that Info node:
  45.  
  46. |`__builtin_saveregs ()'
  47. |     Use this built-in function to save the argument registers in
  48. |     memory so that the varargs mechanism can access them.  Both ANSI
  49. |     and traditional versions of `va_start' must use
  50. |     `__builtin_saveregs', unless you use `SETUP_INCOMING_VARARGS' (see
  51. |     below) instead.
  52. |
  53. |     On some machines, `__builtin_saveregs' is open-coded under the
  54. |     control of the macro `EXPAND_BUILTIN_SAVEREGS'.  On other machines,
  55. |     it calls a routine written in assembler language, found in
  56. |     `libgcc2.c'.
  57. |
  58. |     Regardless of what code is generated for the call to
  59. |     `__builtin_saveregs', it appears at the beginning of the function,
  60. |     not where the call to `__builtin_saveregs' is written.  This is
  61. |     because the registers must be saved before the function starts to
  62. |     use them for its own purposes.
  63. |
  64. |`__builtin_args_info (CATEGORY)'
  65. |     Use this built-in function to find the first anonymous arguments in
  66. |     registers.
  67. |
  68. |     In general, a machine may have several categories of registers
  69. |     used for arguments, each for a particular category of data types. 
  70. |     (For example, on some machines, floating-point registers are used
  71. |     for floating-point arguments while other arguments are passed in
  72. |     the general registers.) To make non-varargs functions use the
  73. |     proper calling convention, you have defined the `CUMULATIVE_ARGS'
  74. |     data type to record how many registers in each category have been
  75. |     used so far
  76. |
  77. |     `__builtin_args_info' accesses the same data structure of type
  78. |     `CUMULATIVE_ARGS' after the ordinary argument layout is finished
  79. |     with it, with CATEGORY specifying which word to access.  Thus, the
  80. |     value indicates the first unused register in a given category.
  81. |
  82. |     Normally, you would use `__builtin_args_info' in the implementation
  83. |     of `va_start', accessing each category just once and storing the
  84. |     value in the `va_list' object.  This is because `va_list' will
  85. |     have to update the values, and there is no way to alter the values
  86. |     accessed by `__builtin_args_info'.
  87. |
  88. |`__builtin_next_arg ()'
  89. |     This is the equivalent of `__builtin_args_info', for stack
  90. |     arguments.  It returns the address of the first anonymous stack
  91. |     argument, as type `void *'. If `ARGS_GROW_DOWNWARD', it returns
  92. |     the address of the location above the first anonymous stack
  93. |     argument. Use it in `va_start' to initialize the pointer for
  94. |     fetching arguments from the stack.
  95. |
  96. |`__builtin_classify_type (OBJECT)'
  97. |     Since each machine has its own conventions for which data types are
  98. |     passed in which kind of register, your implementation of `va_arg'
  99. |     has to embody these conventions.  The easiest way to categorize the
  100. |     specified data type is to use `__builtin_classify_type' together
  101. |     with `sizeof' and `__alignof__'.
  102. |
  103. |     `__builtin_classify_type' ignores the value of OBJECT, considering
  104. |     only its data type.  It returns an integer describing what kind of
  105. |     type that is--integer, floating, pointer, structure, and so on.
  106. |
  107. |     The file `typeclass.h' defines an enumeration that you can use to
  108. |     interpret the values of `__builtin_classify_type'.
  109. |
  110. |   These machine description macros help implement varargs:
  111. |
  112. |`EXPAND_BUILTIN_SAVEREGS (ARGS)'
  113. |     If defined, is a C expression that produces the machine-specific
  114. |     code for a call to `__builtin_saveregs'.  This code will be moved
  115. |     to the very beginning of the function, before any parameter access
  116. |     are made. The return value of this function should be an RTX that
  117. |     contains the value to use as the return of `__builtin_saveregs'.
  118. |
  119. |     The argument ARGS is a `tree_list' containing the arguments that
  120. |     were passed to `__builtin_saveregs'.
  121. |
  122. |     If this macro is not defined, the compiler will output an ordinary
  123. |     call to the library function `__builtin_saveregs'.
  124. |
  125. |`SETUP_INCOMING_VARARGS (ARGS_SO_FAR, MODE, TYPE, PRETEND_ARGS_SIZE, SECOND_TIME)'
  126. |     This macro offers an alternative to using `__builtin_saveregs' and
  127. |     defining the macro `EXPAND_BUILTIN_SAVEREGS'.  Use it to store the
  128. |     anonymous register arguments into the stack so that all the
  129. |     arguments appear to have been passed consecutively on the stack. 
  130. |     Once this is done, you can use the standard implementation of
  131. |     varargs that works for machines that pass all their arguments on
  132. |     the stack.
  133. |
  134. |     The argument ARGS_SO_FAR is the `CUMULATIVE_ARGS' data structure,
  135. |     containing the values that obtain after processing of the named
  136. |     arguments.  The arguments MODE and TYPE describe the last named
  137. |     argument--its machine mode and its data type as a tree node.
  138. |
  139. |     The macro implementation should do two things: first, push onto the
  140. |     stack all the argument registers *not* used for the named
  141. |     arguments, and second, store the size of the data thus pushed into
  142. |     the `int'-valued variable whose name is supplied as the argument
  143. |     PRETEND_ARGS_SIZE.  The value that you store here will serve as
  144. |     additional offset for setting up the stack frame.
  145. |
  146. |     Because you must generate code to push the anonymous arguments at
  147. |     compile time without knowing their data types,
  148. |     `SETUP_INCOMING_VARARGS' is only useful on machines that have just
  149. |     a single category of argument register and use it uniformly for
  150. |     all data types.
  151. |
  152. |     If the argument SECOND_TIME is nonzero, it means that the
  153. |     arguments of the function are being analyzed for the second time. 
  154. |     This happens for an inline function, which is not actually
  155. |     compiled until the end of the source file.  The macro
  156. |     `SETUP_INCOMING_VARARGS' should not generate any instructions in
  157. |     this case.
  158. -- 
  159. Kevin Rodgers                kevin@traffic.den.mmc.com
  160. Martin Marietta MS A16401        (303) 790-3971
  161. 116 Inverness Dr. East
  162. Englewood CO 80112 USA            GO BUFFS!
  163.