home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / gnu / gcc / bug / 2271 < prev    next >
Encoding:
Text File  |  1992-09-08  |  6.0 KB  |  214 lines

  1. Newsgroups: gnu.gcc.bug
  2. Path: sparky!uunet!cis.ohio-state.edu!late.e-technik.uni-erlangen.DE!anhaeupl
  3. From: anhaeupl@late.e-technik.uni-erlangen.DE (Bernd Anhaeupl)
  4. Subject: gcc 2.2.2 stdarg/varargs bug on hp9k7xx-hpux (with patch)
  5. Message-ID: <9209070919.AA21843@late.e-technik.uni-erlangen.de>
  6. Sender: gnulists@ai.mit.edu
  7. Organization: GNUs Not Usenet
  8. Distribution: gnu
  9. Date: Mon, 7 Sep 1992 13:19:46 GMT
  10. Approved: bug-gcc@prep.ai.mit.edu
  11. Lines: 201
  12.  
  13. hpux-Version:     8.07
  14. gcc-Version:      2.2.2
  15. config:           hp720-hpux
  16.               (with gas 1.36 from utah)
  17. Problem:     <stdarg.h> and <varargs.h> do not work
  18. Example:
  19. ------------------------------------ cut here ----------------------------------
  20. #ifdef STDARG
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <math.h>
  24. #include <assert.h>
  25. #include <stdarg.h>
  26.  
  27. void t1(int n,...)
  28. {
  29.     va_list args;
  30.  
  31.     double fa1,fa2,fa3;
  32.     int    a1,a2,a3;
  33.  
  34.     fa1=fa2=fa3=a1=a2=a3=0;
  35.     va_start(args,n);
  36.     fa1=va_arg(args,double);
  37.     a1 =va_arg(args,int);
  38.     fa2=va_arg(args,double);
  39.  
  40.     printf("varargs: (%d,%d,%d)[%g,%g,%g]\n",a1,a2,a3,fa1,fa2,fa3);
  41.     va_end(args);
  42. }
  43.  
  44. int main()
  45. {
  46.     t1(0,1.0,1,2.0);
  47.     printf("Hello, world!\ncos(0)=%f\n",cos(0));
  48.     return EXIT_SUCCESS;
  49. }
  50. #else
  51. #include <stdlib.h>
  52. #include <stdio.h>
  53. #include <math.h>
  54. #include <assert.h>
  55. #include <varargs.h>
  56.  
  57.  
  58. void t1(va_alist)
  59. va_dcl
  60. {
  61.     va_list args;
  62.  
  63.     double fa1,fa2,fa3;
  64.     int    a1,a2,a3;
  65.  
  66.     fa1=fa2=fa3=a1=a2=a3=0;
  67.     va_start(args);
  68.     a1 =va_arg(args,int);
  69.     fa1=va_arg(args,double);
  70.     fa2=va_arg(args,double);
  71.     a2 =va_arg(args,int);
  72.     fa3=va_arg(args,double);
  73.  
  74.     printf("varargs: (%d,%d,%d)[%g,%g,%g]\n",a1,a2,a3,fa1,fa2,fa3);
  75.  
  76.     va_end(args);
  77. }
  78.  
  79. int main()
  80. {
  81.     t1(1,1.0,2.0,2,3.0);
  82.     printf("Hello, world!\ncos(0)=%f\n",cos(0));
  83.     return EXIT_SUCCESS;
  84. }
  85. #endif
  86. -------------------------------- cut here -----------------------------
  87.  
  88. Program output after compilation with gcc -g -DSTDARG test.c -lM:
  89. without patch below (wrong)        with patch below (correct)
  90. -----------------------------------    -----------------------------------
  91. varargs: (1,0,0)[7.39631e+97,2,0]    varargs: (1,0,0)[1,2,0]
  92. Hello, world!                Hello, world!                
  93. cos(0)=1.000000                cos(0)=1.000000                
  94. -----------------------------------    -----------------------------------    
  95. program output after compilation with gcc -g test.c -lM:
  96. without patch below (wrong)        with patch below (correct)
  97. ------------------------------------    ------------------------------------    
  98. varargs: (1,2,0)[7.39631e+97,2,3]    [varargs: (1,2,0)[1,2,3]
  99. Hello, world!                Hello, world!                
  100. cos(0)=1.000000                cos(0)=1.000000                
  101. ------------------------------------    ------------------------------------    
  102.  
  103. You see that gnus vararg stuff does not find floating point arguments passed
  104. in registers.
  105.  
  106. Temporary Solution:    
  107. Replace va-hp800.h with
  108. -----------------------------cut here ----------------------------------
  109. /*  
  110.    Patch for GNUs varargs/stdarg implementation on HP-UX 8.07
  111.    Bernd Anhdupl, LATE, Uni Erlangen, Germany    08/06/92
  112.    (anhaeupl@late.e-technik.uni-erlangen.de)
  113.  
  114.    The following code seems to work. Note, that the HP-UX linker (ld)
  115.    can ensure (by generating extra code), that floating point arguments, 
  116.    which are passed through floating point registers are copied to the 
  117.    corresponding general registers. Therefore you must only generate the
  118.    proper code to store the general registers arg0...arg3 at the
  119.    corresponding stack positions.
  120. */
  121. #if __GNUC__ > 1
  122. typedef void* va_list;
  123. #  define __va_rounded_size(TYPE)  \
  124.     (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
  125. #  ifdef _STDARG_H
  126. typedef struct
  127. {
  128.   char *__va_stack_start;    /* Real start of stack args. */
  129.   char *__va_int;        /* Pointer to the general register */
  130.                 /* args and stack. */
  131.   char *__va_float;        /* Pointer to the fp register args.  */
  132.   char *__va_double;
  133. } __gnu_va_list;
  134. /*
  135.    __builtin_saveregs should be rewritten, since it is not necessary to
  136.    store the floating point registers, if the functions .EXTERN statemant
  137.    is correct. (You have to tell the linker that the function expects the
  138.    arguments in general registers.)
  139. */
  140. #define va_start(AP,LASTARG) ((AP) = ((__gnu_va_list *)__builtin_saveregs())->__va_int)
  141. #  else
  142. extern void * __va_save();
  143. /*
  144. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  145. !!! Implementation (must be moved to libgcc.a): !!!
  146. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  147. void *__va_save(int*arg0,int*arg1,int*arg2,int*arg3)
  148. {
  149.     return arg0+1;
  150. }
  151. */
  152. #define va_alist  __arg0,__arg1,__arg2,__arg3
  153. #define va_dcl
  154. /* since registers have no address, the following call ensures that 
  155.    (general) register arguments are stored on the stack */
  156. #define va_start(AP) ((AP) = __va_save(&__arg0,&__arg1,&__arg2,&__arg3))
  157. #  endif /* _STDARG_H */
  158.  
  159. #define va_arg(AP, TYPE)             \
  160.   ( ( (__va_rounded_size(TYPE) <= 8)        \
  161.      ? ( (AP)-= __va_rounded_size (TYPE),    \
  162.     (__alignof__ (TYPE) > 4         \
  163.      ? ((int)(AP) &= ~(0x7))        \
  164.      : 0))                    \
  165.      : (int)((AP) -= sizeof (TYPE *))),        \
  166.    ( (__va_rounded_size(TYPE) <= 8)         \
  167.     ? *(TYPE *)(AP)                \
  168.     : **(TYPE **)(AP)))
  169.  
  170. #define va_end(AP)
  171.  
  172. #else /* __GNUCC__ > 1 */
  173. #error wrong gcc version
  174. #endif /* __GNUCC__ > 1 */
  175. ------------------------------------ cut here ----------------------------------
  176. and add the necessary function __va_save(int&,int&,int&,int&) (see comment above)
  177. to libgcc.a
  178.  
  179. This patch also makes GNU's varargs/stdarg stuff compatible with HP's.
  180.  
  181. Bernd Anhdupl
  182. (anhaeupl@late.e-technik.uni-erlangen.de)
  183.  
  184.  
  185.  
  186. ps: Does anybody have a patch for the ARGW4 bug? 
  187.     Please respond via email!
  188.  
  189. (for example: the followin program
  190. ---------------------- cut here ------------------------
  191. #include <stdio.h>
  192. #include <stdlib.h>
  193.  
  194. void test(double x1,int x2, double x3)
  195. {
  196.     printf("%g,%d,%g",x1,x2,x3);
  197. }
  198.  
  199. int main(void)
  200. {
  201.     test(1,2,3);
  202.     return EXIT_SUCCESS;
  203. }
  204. --------------------- cut here ------------------------
  205. results in
  206. -------------------------------------------------------
  207. gcc -g test.c
  208. /usr/tmp/cca21836.s:55:Illegal argument description: 4
  209. -------------------------------------------------------
  210. ). Please respond via e-mail.
  211.  
  212.  
  213.  
  214.