Add v9 support.
authorDoug Evans <dje@gnu.org>
Wed, 15 Jun 1994 07:43:31 +0000 (07:43 +0000)
committerDoug Evans <dje@gnu.org>
Wed, 15 Jun 1994 07:43:31 +0000 (07:43 +0000)
From-SVN: r7483

gcc/ginclude/va-sparc.h

index ba79c58..d75e1e8 100644 (file)
@@ -6,6 +6,17 @@
 #ifndef __GNUC_VA_LIST
 #define __GNUC_VA_LIST
 
+#ifdef __sparc_v9__
+typedef long long __va_greg;
+typedef double __va_freg;
+typedef struct {
+  __va_greg * __va_next_o;             /* next available %o* register */
+  __va_greg * __va_next_o_limit;       /* past last available %o* register */
+  __va_freg * __va_next_fp;            /* next available %f* register */
+  __va_freg * __va_next_fp_limit;      /* last available %f* register */
+  __va_greg * __va_next_stack;         /* next extended word on stack */
+} __gnuc_va_list;
+#else
 #ifndef __svr4__
 /* This has to be a char * to be compatible with Sun.
    i.e., we have to pass a `va_list' to vsprintf.  */
@@ -15,6 +26,7 @@ typedef char * __gnuc_va_list;
    i.e., we have to pass a `va_list' to vsprintf.  */
 typedef void * __gnuc_va_list;
 #endif
+#endif /* not __sparc_v9__ */
 #endif /* not __GNUC_VA_LIST */
 
 /* If this is for internal libc use, don't define anything but
@@ -23,6 +35,19 @@ typedef void * __gnuc_va_list;
 
 #ifdef _STDARG_H
 
+#ifdef __sparc_v9__
+#define va_start(AP, LASTARG) \
+__extension__ \
+  ({ \
+     AP.__va_next_o = (__va_greg *) __builtin_saveregs (); \
+     AP.__va_next_o_limit = (AP.__va_next_o + \
+                            (__builtin_args_info (0) < 6 ? 6 - __builtin_args_info (0) : 0)); \
+     AP.__va_next_fp = (__va_freg *) AP.__va_next_o_limit; \
+     AP.__va_next_fp_limit = (AP.__va_next_fp + \
+                             (__builtin_args_info (1) < 16 ? (16 - __builtin_args_info (1) + 1) / 2 : 0)); \
+     AP.__va_next_stack = (__va_greg *) __builtin_next_arg(); \
+  })
+#else
 /* Call __builtin_next_arg even though we aren't using its value, so that
    we can verify that LASTARG is correct.  */
 #ifdef __GCC_NEW_VARARGS__
@@ -32,29 +57,67 @@ typedef void * __gnuc_va_list;
 #define va_start(AP, LASTARG)                                  \
   (__builtin_saveregs (), AP = ((char *) __builtin_next_arg (LASTARG)))
 #endif
+#endif /* not __sparc_v9__ */
 
 #else
 
 #define va_alist  __builtin_va_alist
 #define va_dcl    int __builtin_va_alist;...
 
+#ifdef __sparc_v9__
+#define va_start(AP) \
+__extension__ \
+  ({ \
+     AP.__va_next_o = (__va_greg *) __builtin_saveregs (); \
+     AP.__va_next_o_limit = (AP.__va_next_o + \
+                            (__builtin_args_info (0) < 6 ? 6 - __builtin_args_info (0) : 0)); \
+     AP.__va_next_fp = (__va_freg *) AP.__va_next_o_limit; \
+     AP.__va_next_fp_limit = (AP.__va_next_fp + \
+                             (__builtin_args_info (1) < 16 ? (16 - __builtin_args_info (1) + 1) / 2 : 0)); \
+     AP.__va_next_stack = (__va_greg *) __builtin_next_arg(); \
+  })
+#else
 #ifdef __GCC_NEW_VARARGS__
 #define va_start(AP)           ((AP) = (char *) __builtin_saveregs ())
 #else
 #define va_start(AP)                                           \
  (__builtin_saveregs (), (AP) = ((char *) &__builtin_va_alist))
 #endif
+#endif /* not __sparc_v9__ */
 
 #endif
 
 #ifndef va_end
 void va_end (__gnuc_va_list);          /* Defined in libgcc.a */
+
+/* Values returned by __builtin_classify_type.  */
+
+enum __va_type_classes {
+  __no_type_class = -1,
+  __void_type_class,
+  __integer_type_class,
+  __char_type_class,
+  __enumeral_type_class,
+  __boolean_type_class,
+  __pointer_type_class,
+  __reference_type_class,
+  __offset_type_class,
+  __real_type_class,
+  __complex_type_class,
+  __function_type_class,
+  __method_type_class,
+  __record_type_class,
+  __union_type_class,
+  __array_type_class,
+  __string_type_class,
+  __set_type_class,
+  __file_type_class,
+  __lang_type_class
+};
+
 #endif
 #define va_end(pvar)
 
-#define __va_rounded_size(TYPE)  \
-  (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
-
 /* Avoid errors if compiling GCC v2 with GCC v1.  */
 #if __GNUC__ == 1
 #define __extension__
@@ -64,6 +127,56 @@ void va_end (__gnuc_va_list);               /* Defined in libgcc.a */
    passed by invisible reference.  ??? RECORD_TYPE args passed
    in the stack are made to be word-aligned; for an aggregate that is
    not word-aligned, we advance the pointer to the first non-reg slot.  */
+
+#ifdef __sparc_v9__
+
+#define va_arg(pvar,TYPE)                                      \
+__extension__                                                  \
+({int __type = __builtin_classify_type (* (TYPE *) 0);         \
+  void * __result;                                             \
+  if (__type == __real_type_class)             /* float? */    \
+    {                                                          \
+      __va_freg *__r;                                          \
+      /* see PASS_IN_REG_P in sparc.h */                       \
+      if (pvar.__va_next_fp < pvar.__va_next_fp_limit          \
+         && ((__r = (__va_freg *) (((__va_greg) pvar.__va_next_fp + sizeof (TYPE) - 1) & ~(__va_greg) (sizeof (TYPE) - 1))) \
+             < pvar.__va_next_fp_limit))                       \
+       {                                                       \
+         pvar.__va_next_fp = __r + sizeof (TYPE) / 8;          \
+       }                                                       \
+      else                                                     \
+       {                                                       \
+         __r = (__va_freg *) pvar.__va_next_stack;             \
+         pvar.__va_next_stack += sizeof (TYPE) / 8;            \
+       }                                                       \
+      __result = __r;                                          \
+    }                                                          \
+  else if (__type < __record_type_class)       /* integer? */  \
+    {                                                          \
+      __va_greg *__r;                                          \
+      if (pvar.__va_next_o < pvar.__va_next_o_limit)           \
+       __r = pvar.__va_next_o++;                               \
+      else                                                     \
+       __r = pvar.__va_next_stack++;                           \
+      /* adjust for 4 byte ints */                             \
+      __result = (char *) __r + 8 - sizeof (TYPE);             \
+    }                                                          \
+  else /* aggregate object */                                  \
+    {                                                          \
+      void **__r;                                              \
+      if (pvar.__va_next_o < pvar.__va_next_o_limit)           \
+       __r = (void **) pvar.__va_next_o++;                     \
+      else                                                     \
+       __r = (void **) pvar.__va_next_stack++;                 \
+      __result = *__r;                                         \
+    }                                                          \
+  *(TYPE *) __result;})
+
+#else /* not __sparc_v9__ */
+
+#define __va_rounded_size(TYPE)  \
+  (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
+
 /* We don't declare the union member `d' to have type TYPE
    because that would lose in C++ if TYPE has a constructor.  */
 /* We cast to void * and then to TYPE * because this avoids
@@ -72,7 +185,7 @@ void va_end (__gnuc_va_list);                /* Defined in libgcc.a */
 #define va_arg(pvar,TYPE)                                      \
 __extension__                                                  \
 ({ TYPE __va_temp;                                             \
-   ((__builtin_classify_type (__va_temp) >= 12)                        \
+   ((__builtin_classify_type (__va_temp) >= __record_type_class) \
     ? ((pvar) = (char *)(pvar) + __va_rounded_size (TYPE *),   \
        **(TYPE **) (void *) ((char *)(pvar) - __va_rounded_size (TYPE *))) \
     : __va_rounded_size (TYPE) == 8                            \
@@ -83,6 +196,6 @@ __extension__                                                        \
         *(TYPE *) (void *) __u.__d; })                         \
     : ((pvar) = (char *)(pvar) + __va_rounded_size (TYPE),     \
        *((TYPE *) (void *) ((char *)(pvar) - __va_rounded_size (TYPE)))));})
+#endif /* not __sparc_v9__ */
 
 #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
-