]> git.saurik.com Git - apple/libc.git/blame - stdio/FreeBSD/vfwprintf.c.patch
Libc-320.tar.gz
[apple/libc.git] / stdio / FreeBSD / vfwprintf.c.patch
CommitLineData
9385eb3d
A
1--- vfwprintf.c.orig Thu Jul 24 12:42:14 2003
2+++ vfwprintf.c Sun Aug 24 16:22:23 2003
3@@ -70,9 +70,20 @@
4 #include "local.h"
5 #include "fvwrite.h"
6
7+#ifdef ALTIVEC
8+#include <machine/cpu_capabilities.h>
9+
10+#define VECTORTYPE vector unsigned char
11+#endif /* ALTIVEC */
12+
13 /* Define FLOATING_POINT to get floating point. */
14 #define FLOATING_POINT
15
16+/* if no floating point, turn off HEXFLOAT as well */
17+#if defined(HEXFLOAT) && !defined(FLOATING_POINT)
18+#undef HEXFLOAT
19+#endif /* defined(HEXFLOAT) && !defined(FLOATING_POINT) */
20+
21 union arg {
22 int intarg;
23 u_int uintarg;
24@@ -92,7 +103,7 @@
25 long *plongarg;
26 long long *plonglongarg;
27 ptrdiff_t *pptrdiffarg;
28- size_t *psizearg;
29+ ssize_t *psizearg;
30 intmax_t *pintmaxarg;
31 #ifdef FLOATING_POINT
32 double doublearg;
33@@ -100,6 +111,16 @@
34 #endif
35 wint_t wintarg;
36 wchar_t *pwchararg;
37+#ifdef ALTIVEC
38+ VECTORTYPE vectorarg;
39+ unsigned char vuchararg[16];
40+ signed char vchararg[16];
41+ unsigned short vushortarg[8];
42+ signed short vshortarg[8];
43+ unsigned int vuintarg[4];
44+ signed int vintarg[4];
45+ float vfloatarg[4];
46+#endif /* ALTIVEC */
47 };
48
49 /*
50@@ -110,7 +131,11 @@
51 T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG,
52 T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET,
53 T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR,
54+#ifdef ALTIVEC
55+ T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR, T_VECTOR
56+#else /* ! ALTIVEC */
57 T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR
58+#endif /* ALTIVEC */
59 };
60
61 static int __sbprintf(FILE *, const wchar_t *, va_list);
62@@ -122,6 +147,37 @@
63 static void __find_arguments(const wchar_t *, va_list, union arg **);
64 static void __grow_type_table(int, enum typeid **, int *);
65
66+ /*
67+ * Get the argument indexed by nextarg. If the argument table is
68+ * built, use it to get the argument. If its not, get the next
69+ * argument (and arguments must be gotten sequentially).
70+ */
71+#define GETARG(type) \
72+ ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
73+ (nextarg++, va_arg(ap, type)))
74+
75+#ifdef ALTIVEC
76+#define hasAltivec (_cpu_capabilities & kHasAltivec)
77+/*-----------------------------------------------------------------------
78+ * getvec() must be a real subroutine. If it is a #define, then __vfprintf()
79+ * would have its calling sequence changed by Altivec so that a non-Altivec
80+ * processor would crash on illegal instruction. By isolating the calling
81+ * sequence in getvec(), __vprintf() is callable by a non-Altivec processor.
82+ *-----------------------------------------------------------------------*/
83+static va_list
84+getvec(union arg *dst, const union arg *argtable, int nextarg, va_list ap)
85+{
86+ dst->vectorarg = GETARG(VECTORTYPE);
87+ return ap;
88+}
89+
90+#define SETVEC(dst) \
91+{ \
92+ ap = getvec(&dst, argtable, nextarg, ap); \
93+ nextarg++; \
94+}
95+#endif /* ALTIVEC */
96+
97 /*
98 * Helper function for `fprintf to unbuffered unix file': creates a
99 * temporary buffer. We only work on write-only files; this avoids
100@@ -418,6 +474,15 @@
101
102 #endif /* FLOATING_POINT */
103
104+#ifdef HEXFLOAT
105+extern int __hdtoa(double d, const char *xdigs, int prec, char *cp,
106+ int *expt, int *signflag, char **dtoaend);
107+#if !__TYPE_LONGDOUBLE_IS_DOUBLE
108+extern int __hldtoa(long double d, const char *xdigs, int prec, char *cp,
109+ int *expt, int *signflag, char **dtoaend);
110+#endif /* !__TYPE_LONGDOUBLE_IS_DOUBLE */
111+#endif /* HEXFLOAT */
112+
113 /*
114 * The size of the buffer we use as scratch space for integer
115 * conversions, among other things. Technically, we would need the
116@@ -446,6 +511,9 @@
117 #define PTRDIFFT 0x800 /* ptrdiff_t */
118 #define INTMAXT 0x1000 /* intmax_t */
119 #define CHARINT 0x2000 /* print char using int format */
120+#ifdef ALTIVEC
121+#define VECTOR 0x4000 /* Altivec vector */
122+#endif /* ALTIVEC */
123
124 /*
125 * Non-MT-safe version
126@@ -496,6 +564,11 @@
127 int nseps; /* number of group separators with ' */
128 int nrepeats; /* number of repeats of the last group */
129 #endif
130+#ifdef ALTIVEC
131+ union arg vval; /* Vector argument. */
132+ wchar_t *pct; /* Pointer to '%' at beginning of specifier. */
133+ wchar_t vsep; /* Vector separator character. */
134+#endif
135 u_long ulval; /* integer arguments %[diouxX] */
136 uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */
137 int base; /* base for [diouxX] conversion */
138@@ -525,6 +598,15 @@
139
140 static const wchar_t xdigs_lower[16] = L"0123456789abcdef";
141 static const wchar_t xdigs_upper[16] = L"0123456789ABCDEF";
142+#ifdef HEXFLOAT
143+#define HEXFLOATDELTA 32
144+#define HEXFLOATSTART 32
145+ static char *hexfloat = NULL;
146+ static int hexfloatlen = 0;
147+ const char *xdigs0; /* digits for [aA] conversion */
148+ static const char xdigs_lower0[16] = "0123456789abcdef";
149+ static const char xdigs_upper0[16] = "0123456789ABCDEF";
150+#endif /* HEXFLOAT */
151
152 /*
153 * BEWARE, these `goto error' on error, PRINT uses `n2' and
154@@ -553,15 +635,6 @@
155 } while(0)
156
157 /*
158- * Get the argument indexed by nextarg. If the argument table is
159- * built, use it to get the argument. If its not, get the next
160- * argument (and arguments must be gotten sequentially).
161- */
162-#define GETARG(type) \
163- ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
164- (nextarg++, va_arg(ap, type)))
165-
166- /*
167 * To extend shorts properly, we need both signed and unsigned
168 * argument extraction methods.
169 */
170@@ -612,7 +685,6 @@
171 val = GETARG (int); \
172 }
173
174-
175 thousands_sep = '\0';
176 grouping = NULL;
177 #ifdef FLOATING_POINT
178@@ -650,6 +722,9 @@
179 }
180 if (ch == '\0')
181 goto done;
182+#ifdef ALTIVEC
183+ pct = fmt;
184+#endif /* ALTIVEC */
185 fmt++; /* skip over '%' */
186
187 flags = 0;
188@@ -658,6 +733,9 @@
189 prec = -1;
190 sign = '\0';
191 ox[1] = '\0';
192+#ifdef ALTIVEC
193+ vsep = 'X'; /* Illegal value, changed to defaults later. */
194+#endif /* ALTIVEC */
195
196 rflag: ch = *fmt++;
197 reswitch: switch (ch) {
198@@ -673,6 +751,11 @@
199 case '#':
200 flags |= ALT;
201 goto rflag;
202+#ifdef ALTIVEC
203+ case ',': case ';': case ':': case '_':
204+ vsep = ch;
205+ goto rflag;
206+#endif /* ALTIVEC */
207 case '*':
208 /*-
209 * ``A negative field width argument is taken as a
210@@ -770,8 +853,18 @@
211 case 'c':
212 if (flags & LONGINT)
213 *(cp = buf) = (wchar_t)GETARG(wint_t);
214+#ifdef ALTIVEC
215+ else {
216+ if (flags & VECTOR) {
217+ SETVEC(vval);
218+ break;
219+ }
220+ *(cp = buf) = (wchar_t)btowc(GETARG(int));
221+ }
222+#else /* ALTIVEC */
223 else
224 *(cp = buf) = (wchar_t)btowc(GETARG(int));
225+#endif /* ALTIVEC */
226 size = 1;
227 sign = '\0';
228 break;
229@@ -780,6 +873,12 @@
230 /*FALLTHROUGH*/
231 case 'd':
232 case 'i':
233+#ifdef ALTIVEC
234+ if (flags & VECTOR) {
235+ SETVEC(vval);
236+ break;
237+ } else
238+#endif /* ALTIVEC */
239 if (flags & INTMAX_SIZE) {
240 ujval = SJARG();
241 if ((intmax_t)ujval < 0) {
242@@ -799,38 +898,74 @@
243 #ifdef HEXFLOAT
244 case 'a':
245 case 'A':
246+#ifdef ALTIVEC
247+ if (flags & VECTOR) {
248+ flags |= FPT;
249+ SETVEC(vval);
250+ break;
251+ }
252+#endif /* ALTIVEC */
253 if (ch == 'a') {
254 ox[1] = 'x';
255- xdigs = xdigs_lower;
256+ xdigs0 = xdigs_lower0;
257 expchar = 'p';
258 } else {
259 ox[1] = 'X';
260- xdigs = xdigs_upper;
261+ xdigs0 = xdigs_upper0;
262 expchar = 'P';
263 }
264- /*
265- * XXX We don't actually have a conversion
266- * XXX routine for this yet.
267- */
268+ if (!hexfloat) {
269+ hexfloat = malloc(hexfloatlen = HEXFLOATSTART);
270+ if (!hexfloat)
271+ goto error;
272+ }
273+ /* one extra for integer part and another for null */
274+ if (prec > hexfloatlen - 2) {
275+ int hlen = prec + HEXFLOATDELTA;
276+ char *hf = realloc(hexfloat, hlen);
277+ if (hf == NULL)
278+ goto error;
279+ hexfloat = hf;
280+ hexfloatlen = hlen;
281+ }
282 if (flags & LONGDBL) {
283- fparg.ldbl = (double)GETARG(long double);
284- dtoaresult =
285- __hldtoa(fparg.ldbl, xdigs, prec,
286- &expt, &signflag, &dtoaend);
287+#if __TYPE_LONGDOUBLE_IS_DOUBLE
288+ fparg.dbl = (double)GETARG(long double);
289+ prec = __hdtoa(fparg.dbl, xdigs0, prec,
290+ hexfloat, &expt, &signflag, &dtoaend);
291+#else /* ! __TYPE_LONGDOUBLE_IS_DOUBLE */
292+ fparg.ldbl = GETARG(long double);
293+ prec = __hldtoa(fparg.ldbl, xdigs0, prec,
294+ hexfloat, &expt, &signflag, &dtoaend);
295+#endif /* __TYPE_LONGDOUBLE_IS_DOUBLE */
296 } else {
297 fparg.dbl = GETARG(double);
298- dtoaresult =
299- __hdtoa(fparg.dbl, xdigs, prec,
300- &expt, &signflag, &dtoaend);
301+ prec = __hdtoa(fparg.dbl, xdigs0, prec,
302+ hexfloat, &expt, &signflag, &dtoaend);
303+ }
304+ prec++;
305+ if (expt == INT_MAX) {
306+ ox[1] = 0;
307+ hexfloat[1] = 0;
308+ } else {
309+ expt++;
310+ *dtoaend = 0;
311+ ndig = dtoaend - hexfloat;
312 }
313 if (convbuf != NULL)
314 free(convbuf);
315- cp = convbuf = __mbsconv(dtoaresult, -1);
316- freedtoa(dtoaresult);
317- goto fp_begin;
318+ cp = convbuf = __mbsconv(hexfloat, -1);
319+ goto hex_begin;
320 #endif
321 case 'e':
322 case 'E':
323+#ifdef ALTIVEC
324+ if (flags & VECTOR) {
325+ flags |= FPT;
326+ SETVEC(vval);
327+ break;
328+ }
329+#endif /* ALTIVEC */
330 expchar = ch;
331 if (prec < 0) /* account for digit before decpt */
332 prec = DEFPREC + 1;
333@@ -839,10 +974,24 @@
334 goto fp_begin;
335 case 'f':
336 case 'F':
337+#ifdef ALTIVEC
338+ if (flags & VECTOR) {
339+ flags |= FPT;
340+ SETVEC(vval);
341+ break;
342+ }
343+#endif /* ALTIVEC */
344 expchar = '\0';
345 goto fp_begin;
346 case 'g':
347 case 'G':
348+#ifdef ALTIVEC
349+ if (flags & VECTOR) {
350+ flags |= FPT;
351+ SETVEC(vval);
352+ break;
353+ }
354+#endif /* ALTIVEC */
355 expchar = ch - ('g' - 'e');
356 if (prec == 0)
357 prec = 1;
358@@ -851,6 +1000,17 @@
359 prec = DEFPREC;
360 if (convbuf != NULL)
361 free(convbuf);
362+#if __TYPE_LONGDOUBLE_IS_DOUBLE
363+ if (flags & LONGDBL)
364+ fparg.ldbl = GETARG(long double);
365+ else
366+ fparg.dbl = GETARG(double);
367+ dtoaresult =
368+ dtoa(fparg.dbl, expchar ? 2 : 3, prec,
369+ &expt, &signflag, &dtoaend);
370+ if (expt == 9999)
371+ expt = INT_MAX;
372+#else /* ! __TYPE_LONGDOUBLE_IS_DOUBLE */
373 if (flags & LONGDBL) {
374 fparg.ldbl = GETARG(long double);
375 dtoaresult =
376@@ -864,9 +1024,13 @@
377 if (expt == 9999)
378 expt = INT_MAX;
379 }
380+#endif /* __TYPE_LONGDOUBLE_IS_DOUBLE */
381 ndig = dtoaend - dtoaresult;
382 cp = convbuf = __mbsconv(dtoaresult, -1);
383 freedtoa(dtoaresult);
384+#ifdef HEXFLOAT
385+hex_begin:
386+#endif /* HEXFLOAT */
387 if (signflag)
388 sign = '-';
389 if (expt == INT_MAX) { /* inf or nan */
390@@ -959,6 +1123,12 @@
391 flags |= LONGINT;
392 /*FALLTHROUGH*/
393 case 'o':
394+#ifdef ALTIVEC
395+ if (flags & VECTOR) {
396+ SETVEC(vval);
397+ break;
398+ } else
399+#endif /* ALTIVEC */
400 if (flags & INTMAX_SIZE)
401 ujval = UJARG();
402 else
403@@ -973,6 +1143,12 @@
404 * defined manner.''
405 * -- ANSI X3J11
406 */
407+#ifdef ALTIVEC
408+ if (flags & VECTOR) {
409+ SETVEC(vval);
410+ break;
411+ }
412+#endif /* ALTIVEC */
413 ujval = (uintmax_t)(uintptr_t)GETARG(void *);
414 base = 16;
415 xdigs = xdigs_lower;
416@@ -1025,6 +1201,12 @@
417 flags |= LONGINT;
418 /*FALLTHROUGH*/
419 case 'u':
420+#ifdef ALTIVEC
421+ if (flags & VECTOR) {
422+ SETVEC(vval);
423+ break;
424+ } else
425+#endif /* ALTIVEC */
426 if (flags & INTMAX_SIZE)
427 ujval = UJARG();
428 else
429@@ -1037,6 +1219,12 @@
430 case 'x':
431 xdigs = xdigs_lower;
432 hex:
433+#ifdef ALTIVEC
434+ if (flags & VECTOR) {
435+ SETVEC(vval);
436+ break;
437+ } else
438+#endif /* ALTIVEC */
439 if (flags & INTMAX_SIZE)
440 ujval = UJARG();
441 else
442@@ -1081,6 +1269,14 @@
443 if (size > BUF) /* should never happen */
444 abort();
445 break;
446+#ifdef ALTIVEC
447+ case 'v':
448+ if (hasAltivec) {
449+ flags |= VECTOR;
450+ goto rflag;
451+ }
452+ /* drop through */
453+#endif /* ALTIVEC */
454 default: /* "%?" prints ?, unless ? is NUL */
455 if (ch == '\0')
456 goto done;
457@@ -1092,6 +1288,185 @@
458 break;
459 }
460
461+#ifdef ALTIVEC
462+ if (flags & VECTOR) {
463+ /*
464+ * Do the minimum amount of work necessary to construct
465+ * a format specifier that can be used to recursively
466+ * call vfprintf() for each element in the vector.
467+ */
468+ int i, j; /* Counter. */
469+ int vcnt; /* Number of elements in vector. */
470+ char *vfmt; /* Pointer to format specifier. */
471+ char vfmt_buf[32]; /* Static buffer for format spec. */
472+ int vwidth = 0; /* Width specified via '*'. */
473+ int vprec = 0; /* Precision specified via '*'. */
474+ union { /* Element. */
475+ int i;
476+ float f;
477+ } velm;
478+ char *vstr; /* Used for asprintf(). */
479+ int vlen; /* Length returned by asprintf(). */
480+
481+ /*
482+ * Set vfmt. If vfmt_buf may not be big enough,
483+ * malloc() space, taking care to free it later.
484+ */
485+ if (&fmt[-1] - pct < sizeof(vfmt_buf))
486+ vfmt = vfmt_buf;
487+ else
488+ vfmt = (char *)malloc(&fmt[-1] - pct + 1);
489+
490+ /* Set the separator character, if not specified. */
491+ if (vsep == 'X') {
492+ if (ch == 'c')
493+ vsep = '\0';
494+ else
495+ vsep = ' ';
496+ }
497+
498+ /* Create the format specifier. */
499+ for (i = j = 0; i < &fmt[-1] - pct; i++) {
500+ switch (pct[i]) {
501+ case ',': case ';': case ':': case '_':
502+ case 'v': case 'h': case 'l':
503+ /* Ignore. */
504+ break;
505+ case '*':
506+ if (pct[i - 1] != '.')
507+ vwidth = 1;
508+ else
509+ vprec = 1;
510+ /* FALLTHROUGH */
511+ default:
512+ vfmt[j++] = pct[i];
513+ }
514+ }
515+
516+ /*
517+ * Determine the number of elements in the vector and
518+ * finish up the format specifier.
519+ */
520+ if (flags & SHORTINT) {
521+ vfmt[j++] = 'h';
522+ vcnt = 8;
523+ } else if (flags & LONGINT) {
524+ vfmt[j++] = 'l';
525+ vcnt = 4;
526+ } else {
527+ switch (ch) {
528+ case 'a':
529+ case 'A':
530+ case 'e':
531+ case 'E':
532+ case 'f':
533+ case 'g':
534+ case 'G':
535+ vcnt = 4;
536+ break;
537+ default:
538+ /*
539+ * The default case should never
540+ * happen.
541+ */
542+ case 'c':
543+ case 'd':
544+ case 'i':
545+ case 'u':
546+ case 'o':
547+ case 'p':
548+ case 'x':
549+ case 'X':
550+ vcnt = 16;
551+ }
552+ }
553+ vfmt[j++] = ch;
554+ vfmt[j++] = '\0';
555+
556+/* Get a vector element. */
557+#define VPRINT(cnt, ind, args...) do { \
558+ if (flags & FPT) { \
559+ velm.f = vval.vfloatarg[ind]; \
560+ vlen = asprintf(&vstr, vfmt , ## args, velm.f); \
561+ } else { \
562+ switch (cnt) { \
563+ default: \
564+ /* The default case should never happen. */ \
565+ case 4: \
566+ velm.i = (unsigned)vval.vintarg[ind]; \
567+ break; \
568+ case 8: \
569+ velm.i = (unsigned short)vval.vshortarg[ind]; \
570+ break; \
571+ case 16: \
572+ velm.i = (unsigned char)vval.vchararg[ind]; \
573+ break; \
574+ } \
575+ vlen = asprintf(&vstr, vfmt , ## args, velm.i); \
576+ } \
577+ ret += vlen; \
578+ PRINT(vstr, vlen); \
579+ free(vstr); \
580+} while (0)
581+
582+ /* Actually print. */
583+ if (vwidth == 0) {
584+ if (vprec == 0) {
585+ /* First element. */
586+ VPRINT(vcnt, 0);
587+ for (i = 1; i < vcnt; i++) {
588+ /* Separator. */
589+ if (vsep)
590+ PRINT(&vsep, 1);
591+
592+ /* Element. */
593+ VPRINT(vcnt, i);
594+ }
595+ } else {
596+ /* First element. */
597+ VPRINT(vcnt, 0, prec);
598+ for (i = 1; i < vcnt; i++) {
599+ /* Separator. */
600+ if (vsep)
601+ PRINT(&vsep, 1);
602+
603+ /* Element. */
604+ VPRINT(vcnt, i, prec);
605+ }
606+ }
607+ } else {
608+ if (vprec == 0) {
609+ /* First element. */
610+ VPRINT(vcnt, 0, width);
611+ for (i = 1; i < vcnt; i++) {
612+ /* Separator. */
613+ if (vsep)
614+ PRINT(&vsep, 1);
615+
616+ /* Element. */
617+ VPRINT(vcnt, i, width);
618+ }
619+ } else {
620+ /* First element. */
621+ VPRINT(vcnt, 0, width, prec);
622+ for (i = 1; i < vcnt; i++) {
623+ /* Separator. */
624+ if (vsep)
625+ PRINT(&vsep, 1);
626+
627+ /* Element. */
628+ VPRINT(vcnt, i, width, prec);
629+ }
630+ }
631+ }
632+#undef VPRINT
633+
634+ if (vfmt != vfmt_buf)
635+ free(vfmt);
636+
637+ continue;
638+ }
639+#endif /* ALTIVEC */
640 /*
641 * All reasonable formats wind up here. At this point, `cp'
642 * points to a string which (if not flags&LADJUST) should be
643@@ -1109,7 +1484,7 @@
644 realsz = dprec > size ? dprec : size;
645 if (sign)
646 realsz++;
647- else if (ox[1])
648+ if (ox[1])
649 realsz += 2;
650
651 prsize = width > realsz ? width : realsz;
652@@ -1123,9 +1498,9 @@
653 PAD(width - realsz, blanks);
654
655 /* prefix */
656- if (sign) {
657+ if (sign)
658 PRINT(&sign, 1);
659- } else if (ox[1]) { /* ox[1] is either x, X, or \0 */
660+ if (ox[1]) { /* ox[1] is either x, X, or \0 */
661 ox[0] = '0';
662 PRINT(ox, 2);
663 }
664@@ -1368,6 +1743,11 @@
665 if (flags & LONGINT)
666 ADDTYPE(T_WINT);
667 else
668+#ifdef ALTIVEC
669+ if (flags & VECTOR)
670+ ADDTYPE(T_VECTOR);
671+ else
672+#endif /* ALTIVEC */
673 ADDTYPE(T_INT);
674 break;
675 case 'D':
676@@ -1387,6 +1767,11 @@
677 case 'f':
678 case 'g':
679 case 'G':
680+#ifdef ALTIVEC
681+ if (flags & VECTOR)
682+ ADDTYPE(T_VECTOR);
683+ else
684+#endif /* ALTIVEC */
685 if (flags & LONGDBL)
686 ADDTYPE(T_LONG_DOUBLE);
687 else
688@@ -1415,9 +1800,19 @@
689 flags |= LONGINT;
690 /*FALLTHROUGH*/
691 case 'o':
692+#ifdef ALTIVEC
693+ if (flags & VECTOR)
694+ ADDTYPE(T_VECTOR);
695+ else
696+#endif /* ALTIVEC */
697 ADDUARG();
698 break;
699 case 'p':
700+#ifdef ALTIVEC
701+ if (flags & VECTOR)
702+ ADDTYPE(T_VECTOR);
703+ else
704+#endif /* ALTIVEC */
705 ADDTYPE(TP_VOID);
706 break;
707 case 'S':
708@@ -1435,6 +1830,11 @@
709 case 'u':
710 case 'X':
711 case 'x':
712+#ifdef ALTIVEC
713+ if (flags & VECTOR)
714+ ADDTYPE(T_VECTOR);
715+ else
716+#endif /* ALTIVEC */
717 ADDUARG();
718 break;
719 default: /* "%?" prints ?, unless ? is NUL */
720@@ -1520,6 +1920,12 @@
721 (*argtable) [n].longdoublearg = va_arg (ap, long double);
722 break;
723 #endif
724+#ifdef ALTIVEC
725+ case T_VECTOR:
726+ if (hasAltivec)
727+ ap = getvec( &((*argtable) [n]), NULL, 0, ap );
728+ break;
729+#endif /* ALTIVEC */
730 case TP_CHAR:
731 (*argtable) [n].pchararg = va_arg (ap, char *);
732 break;