Annotation of GNUtools/cc/va-pyr.h, revision 1.1

1.1     ! root        1: /**
        !             2:  *
        !             3:  *     Varargs for PYR/GNU CC
        !             4:  *
        !             5:  * WARNING -- WARNING -- DANGER
        !             6:  *
        !             7:  * The code in this file implements varargs for gcc on a pyr in
        !             8:  * a way that is compatible with code compiled by the Pyramid Technology
        !             9:  * C compiler.
        !            10:  * As such, it depends strongly on the Pyramid conventions for
        !            11:  * parameter passing.ct and independent implementation. 
        !            12:  * These (somewhat bizarre) parameter-passing conventions are described
        !            13:  * in the ``OSx Operating System Porting Guide''.
        !            14:  * 
        !            15:  * A quick summary is useful:
        !            16:  * 12 of the 48 register-windowed regs available for
        !            17:  * parameter passing.  Parameters of a function call that are eligible
        !            18:  * to be passed in registers are assigned registers from TR0/PR0 onwards;
        !            19:  * all other arguments are passed on the stack.
        !            20:  * Structure and union parameters are *never* passed in registers,
        !            21:  * even if they are small enough to fit.  They are always passed on
        !            22:  * the stack.
        !            23:  *
        !            24:  * Double-sized parameters cannot be passed in TR11, because
        !            25:  * TR12 is not used for passing parameters.  If, in the absence of this
        !            26:  * rule, a double-sized param would have been passed in TR11,
        !            27:  * that parameter is passed on the stack and no parameters are
        !            28:  * passed in TR11.
        !            29:  * 
        !            30:  * It is only known to work for passing 32-bit integer quantities
        !            31:  * (ie chars, shorts, ints/enums, longs), doubles, or pointers. 
        !            32:  * Passing structures on a Pyramid via varargs is a loser.
        !            33:  * Passing an object larger than 8 bytes on a pyramid via varargs may
        !            34:  * also be a loser.
        !            35:  * 
        !            36:  */
        !            37: 
        !            38: 
        !            39: /*
        !            40:  *  pointer to next stack parameter in __va_buf[0]
        !            41:  *  pointer to next parameter register in __va_buf[1]
        !            42:  *  Count of registers seen at __va_buf[2]
        !            43:  *  saved pr0..pr11 in __va_buf[3..14]
        !            44:  *  # of calls to va_arg (debugging) at __va_buf[15]
        !            45:  */
        !            46: 
        !            47: /* Define __gnuc_va_list.  */
        !            48: 
        !            49: #ifndef __GNUC_VA_LIST
        !            50: #define __GNUC_VA_LIST
        !            51: 
        !            52: typedef void *__voidptr;
        !            53: #if 1
        !            54: 
        !            55: typedef struct __va_regs {
        !            56:       __voidptr __stackp,__regp,__count;
        !            57:       __voidptr __pr0,__pr1,__pr2,__pr3,__pr4,__pr5,__pr6,__pr7,__pr8,__pr9,__pr10,__pr11;
        !            58:   } __va_regs;
        !            59: 
        !            60: typedef __va_regs __va_buf;
        !            61: #else
        !            62: 
        !            63: /* __va_buf[0] = address of next arg passed on the stack
        !            64:    __va_buf[1] = address of next arg passed in a register
        !            65:    __va_buf[2] = register-# of next arg passed in a register
        !            66:  */
        !            67: typedef __voidptr(*__va_buf);
        !            68: 
        !            69: #endif
        !            70: 
        !            71: typedef __va_buf __gnuc_va_list;
        !            72: 
        !            73: #endif /* not __GNUC_VA_LIST */
        !            74: 
        !            75: /* If this is for internal libc use, don't define anything but
        !            76:    __gnuc_va_list.  */
        !            77: #if defined (_STDARG_H) || defined (_VARARGS_H)
        !            78: 
        !            79: /* In GCC version 2, we want an ellipsis at the end of the declaration
        !            80:    of the argument list.  GCC version 1 can't parse it.  */
        !            81: 
        !            82: #if __GNUC__ > 1
        !            83: #define __va_ellipsis ...
        !            84: #else
        !            85: #define __va_ellipsis
        !            86: #endif
        !            87: 
        !            88: #define va_alist \
        !            89:   __va0,__va1,__va2,__va3,__va4,__va5,__va6,__va7,__va8,__va9,__va10,__va11, \
        !            90:  __builtin_va_alist
        !            91: 
        !            92: /* The ... causes current_function_varargs to be set in cc1.  */
        !            93: #define va_dcl __voidptr va_alist; __va_ellipsis
        !            94: 
        !            95: 
        !            96: /* __asm ("rcsp %0" : "=r" ( _AP [0]));*/
        !            97: 
        !            98: #define va_start(_AP)  \
        !            99:   _AP =  ((struct __va_regs) {                                         \
        !           100:    &(_AP.__pr0), (void*)&__builtin_va_alist, (void*)0,                 \
        !           101:         __va0,__va1,__va2,__va3,__va4,__va5,                           \
        !           102:        __va6,__va7,__va8,__va9,__va10,__va11})
        !           103: 
        !           104: 
        !           105: /* Avoid errors if compiling GCC v2 with GCC v1.  */
        !           106: #if __GNUC__ == 1
        !           107: #define __extension__
        !           108: #endif
        !           109: 
        !           110: /* We cast to void * and then to TYPE * because this avoids
        !           111:    a warning about increasing the alignment requirement.  */
        !           112: #define va_arg(_AP, _MODE)     \
        !           113: __extension__                                                          \
        !           114: ({__voidptr *__ap = (__voidptr*)&_AP;                                  \
        !           115:   register int __size = sizeof (_MODE);                                        \
        !           116:   register int __onstack =                                             \
        !           117:          (__size > 8 || ( (int)(__ap[2]) > 11) ||                      \
        !           118:            (__size==8 && (int)(__ap[2])==11));                         \
        !           119:   register int* __param_addr =  ((int*)((__ap) [__onstack]));          \
        !           120:                                                                        \
        !           121:   ((void *)__ap[__onstack])+=__size;                                   \
        !           122:     if (__onstack==0 || (int)(__ap[2])==11)                            \
        !           123:       __ap[2]+= (__size >> 2);                                         \
        !           124:   *(( _MODE *) (void *) __param_addr);                                 \
        !           125: })
        !           126: 
        !           127: void va_end (__gnuc_va_list);          /* Defined in libgcc.a */
        !           128: #define va_end(_X)
        !           129: 
        !           130: #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.