]> git.saurik.com Git - apple/libc.git/blob - stdio/FreeBSD/vfprintf.c.patch
Libc-320.tar.gz
[apple/libc.git] / stdio / FreeBSD / vfprintf.c.patch
1 --- vfprintf.c.orig Thu Jul 24 12:42:14 2003
2 +++ vfprintf.c Sun Aug 24 16:21:44 2003
3 @@ -66,9 +66,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 @@ -88,7 +99,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 @@ -96,6 +107,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 @@ -106,7 +127,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 __sprint(FILE *, struct __suio *);
62 @@ -119,6 +144,37 @@
63 static void __find_arguments(const char *, 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 * Flush out all the vectors defined by the given uio,
99 * then reset it so that it can be reused.
100 @@ -424,6 +480,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 @@ -452,6 +517,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 @@ -503,6 +571,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 + char *pct; /* Pointer to '%' at beginning of specifier. */
133 + char 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 @@ -535,6 +608,12 @@
139
140 static const char xdigs_lower[16] = "0123456789abcdef";
141 static const char xdigs_upper[16] = "0123456789ABCDEF";
142 +#ifdef HEXFLOAT
143 +#define HEXFLOATDELTA 32
144 +#define HEXFLOATSTART 32
145 + static char *hexfloat = NULL;
146 + static int hexfloatlen = 0;
147 +#endif /* HEXFLOAT */
148
149 /*
150 * BEWARE, these `goto error' on error, and PAD uses `n'.
151 @@ -575,15 +654,6 @@
152 }
153
154 /*
155 - * Get the argument indexed by nextarg. If the argument table is
156 - * built, use it to get the argument. If its not, get the next
157 - * argument (and arguments must be gotten sequentially).
158 - */
159 -#define GETARG(type) \
160 - ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
161 - (nextarg++, va_arg(ap, type)))
162 -
163 - /*
164 * To extend shorts properly, we need both signed and unsigned
165 * argument extraction methods.
166 */
167 @@ -634,7 +704,6 @@
168 val = GETARG (int); \
169 }
170
171 -
172 thousands_sep = '\0';
173 grouping = NULL;
174 convbuf = NULL;
175 @@ -676,6 +745,9 @@
176 }
177 if (ch == '\0')
178 goto done;
179 +#ifdef ALTIVEC
180 + pct = fmt;
181 +#endif /* ALTIVEC */
182 fmt++; /* skip over '%' */
183
184 flags = 0;
185 @@ -684,6 +756,9 @@
186 prec = -1;
187 sign = '\0';
188 ox[1] = '\0';
189 +#ifdef ALTIVEC
190 + vsep = 'X'; /* Illegal value, changed to defaults later. */
191 +#endif /* ALTIVEC */
192
193 rflag: ch = *fmt++;
194 reswitch: switch (ch) {
195 @@ -699,6 +774,11 @@
196 case '#':
197 flags |= ALT;
198 goto rflag;
199 +#ifdef ALTIVEC
200 + case ',': case ';': case ':': case '_':
201 + vsep = ch;
202 + goto rflag;
203 +#endif /* ALTIVEC */
204 case '*':
205 /*-
206 * ``A negative field width argument is taken as a
207 @@ -807,6 +887,12 @@
208 }
209 size = (int)mbseqlen;
210 } else {
211 +#ifdef ALTIVEC
212 + if (flags & VECTOR) {
213 + SETVEC(vval);
214 + break;
215 + }
216 +#endif /* ALTIVEC */
217 *(cp = buf) = GETARG(int);
218 size = 1;
219 }
220 @@ -817,6 +903,12 @@
221 /*FALLTHROUGH*/
222 case 'd':
223 case 'i':
224 +#ifdef ALTIVEC
225 + if (flags & VECTOR) {
226 + SETVEC(vval);
227 + break;
228 + } else
229 +#endif /* ALTIVEC */
230 if (flags & INTMAX_SIZE) {
231 ujval = SJARG();
232 if ((intmax_t)ujval < 0) {
233 @@ -836,6 +928,13 @@
234 #ifdef HEXFLOAT
235 case 'a':
236 case 'A':
237 +#ifdef ALTIVEC
238 + if (flags & VECTOR) {
239 + flags |= FPT;
240 + SETVEC(vval);
241 + break;
242 + }
243 +#endif /* ALTIVEC */
244 if (ch == 'a') {
245 ox[1] = 'x';
246 xdigs = xdigs_lower;
247 @@ -845,25 +944,51 @@
248 xdigs = xdigs_upper;
249 expchar = 'P';
250 }
251 - /*
252 - * XXX We don't actually have a conversion
253 - * XXX routine for this yet.
254 - */
255 + if (!hexfloat) {
256 + hexfloat = malloc(hexfloatlen = HEXFLOATSTART);
257 + if (!hexfloat)
258 + goto error;
259 + }
260 + if (prec > hexfloatlen - 1) {
261 + int hlen = prec + HEXFLOATDELTA;
262 + char *hf = realloc(hexfloat, hlen);
263 + if (hf == NULL)
264 + goto error;
265 + hexfloat = hf;
266 + hexfloatlen = hlen;
267 + }
268 + cp = hexfloat;
269 if (flags & LONGDBL) {
270 - fparg.ldbl = (double)GETARG(long double);
271 - dtoaresult = cp =
272 - __hldtoa(fparg.ldbl, xdigs, prec,
273 +#if __TYPE_LONGDOUBLE_IS_DOUBLE
274 + fparg.dbl = (double)GETARG(long double);
275 + prec = __hdtoa(fparg.dbl, xdigs, prec, cp,
276 &expt, &signflag, &dtoaend);
277 +#else /* ! __TYPE_LONGDOUBLE_IS_DOUBLE */
278 + fparg.ldbl = GETARG(long double);
279 + prec = __hldtoa(fparg.ldbl, xdigs, prec, cp,
280 + &expt, &signflag, &dtoaend);
281 +#endif /* __TYPE_LONGDOUBLE_IS_DOUBLE */
282 } else {
283 fparg.dbl = GETARG(double);
284 - dtoaresult = cp =
285 - __hdtoa(fparg.dbl, xdigs, prec,
286 + prec = __hdtoa(fparg.dbl, xdigs, prec, cp,
287 &expt, &signflag, &dtoaend);
288 }
289 - goto fp_begin;
290 + prec++;
291 + if (expt == INT_MAX)
292 + ox[1] = 0;
293 + else
294 + expt++;
295 + goto hex_begin;
296 #endif
297 case 'e':
298 case 'E':
299 +#ifdef ALTIVEC
300 + if (flags & VECTOR) {
301 + flags |= FPT;
302 + SETVEC(vval);
303 + break;
304 + }
305 +#endif /* ALTIVEC */
306 expchar = ch;
307 if (prec < 0) /* account for digit before decpt */
308 prec = DEFPREC + 1;
309 @@ -872,10 +997,24 @@
310 goto fp_begin;
311 case 'f':
312 case 'F':
313 +#ifdef ALTIVEC
314 + if (flags & VECTOR) {
315 + flags |= FPT;
316 + SETVEC(vval);
317 + break;
318 + }
319 +#endif /* ALTIVEC */
320 expchar = '\0';
321 goto fp_begin;
322 case 'g':
323 case 'G':
324 +#ifdef ALTIVEC
325 + if (flags & VECTOR) {
326 + flags |= FPT;
327 + SETVEC(vval);
328 + break;
329 + }
330 +#endif /* ALTIVEC */
331 expchar = ch - ('g' - 'e');
332 if (prec == 0)
333 prec = 1;
334 @@ -884,6 +1023,17 @@
335 prec = DEFPREC;
336 if (dtoaresult != NULL)
337 freedtoa(dtoaresult);
338 +#if __TYPE_LONGDOUBLE_IS_DOUBLE
339 + if (flags & LONGDBL)
340 + fparg.dbl = (double)GETARG(long double);
341 + else
342 + fparg.dbl = GETARG(double);
343 + dtoaresult = cp =
344 + dtoa(fparg.dbl, expchar ? 2 : 3, prec,
345 + &expt, &signflag, &dtoaend);
346 + if (expt == 9999)
347 + expt = INT_MAX;
348 +#else /* ! __TYPE_LONGDOUBLE_IS_DOUBLE */
349 if (flags & LONGDBL) {
350 fparg.ldbl = GETARG(long double);
351 dtoaresult = cp =
352 @@ -897,6 +1047,10 @@
353 if (expt == 9999)
354 expt = INT_MAX;
355 }
356 +#endif /* __TYPE_LONGDOUBLE_IS_DOUBLE */
357 +#ifdef HEXFLOAT
358 +hex_begin:
359 +#endif /* HEXFLOAT */
360 if (signflag)
361 sign = '-';
362 if (expt == INT_MAX) { /* inf or nan */
363 @@ -990,6 +1144,12 @@
364 flags |= LONGINT;
365 /*FALLTHROUGH*/
366 case 'o':
367 +#ifdef ALTIVEC
368 + if (flags & VECTOR) {
369 + SETVEC(vval);
370 + break;
371 + } else
372 +#endif /* ALTIVEC */
373 if (flags & INTMAX_SIZE)
374 ujval = UJARG();
375 else
376 @@ -1004,6 +1164,12 @@
377 * defined manner.''
378 * -- ANSI X3J11
379 */
380 +#ifdef ALTIVEC
381 + if (flags & VECTOR) {
382 + SETVEC(vval);
383 + break;
384 + }
385 +#endif /* ALTIVEC */
386 ujval = (uintmax_t)(uintptr_t)GETARG(void *);
387 base = 16;
388 xdigs = xdigs_lower;
389 @@ -1053,6 +1219,12 @@
390 flags |= LONGINT;
391 /*FALLTHROUGH*/
392 case 'u':
393 +#ifdef ALTIVEC
394 + if (flags & VECTOR) {
395 + SETVEC(vval);
396 + break;
397 + } else
398 +#endif /* ALTIVEC */
399 if (flags & INTMAX_SIZE)
400 ujval = UJARG();
401 else
402 @@ -1065,6 +1237,12 @@
403 case 'x':
404 xdigs = xdigs_lower;
405 hex:
406 +#ifdef ALTIVEC
407 + if (flags & VECTOR) {
408 + SETVEC(vval);
409 + break;
410 + } else
411 +#endif /* ALTIVEC */
412 if (flags & INTMAX_SIZE)
413 ujval = UJARG();
414 else
415 @@ -1109,6 +1287,14 @@
416 if (size > BUF) /* should never happen */
417 abort();
418 break;
419 +#ifdef ALTIVEC
420 + case 'v':
421 + if (hasAltivec) {
422 + flags |= VECTOR;
423 + goto rflag;
424 + }
425 + /* drap through */
426 +#endif /* ALTIVEC */
427 default: /* "%?" prints ?, unless ? is NUL */
428 if (ch == '\0')
429 goto done;
430 @@ -1120,6 +1306,186 @@
431 break;
432 }
433
434 +#ifdef ALTIVEC
435 + if (flags & VECTOR) {
436 + /*
437 + * Do the minimum amount of work necessary to construct
438 + * a format specifier that can be used to recursively
439 + * call vfprintf() for each element in the vector.
440 + */
441 + int i, j; /* Counter. */
442 + int vcnt; /* Number of elements in vector. */
443 + char *vfmt; /* Pointer to format specifier. */
444 + char vfmt_buf[32]; /* Static buffer for format spec. */
445 + int vwidth = 0; /* Width specified via '*'. */
446 + int vprec = 0; /* Precision specified via '*'. */
447 + union { /* Element. */
448 + int i;
449 + float f;
450 + } velm;
451 + char *vstr; /* Used for asprintf(). */
452 + int vlen; /* Length returned by asprintf(). */
453 +
454 + /*
455 + * Set vfmt. If vfmt_buf may not be big enough,
456 + * malloc() space, taking care to free it later.
457 + */
458 + if (&fmt[-1] - pct < sizeof(vfmt_buf))
459 + vfmt = vfmt_buf;
460 + else
461 + vfmt = (char *)malloc(&fmt[-1] - pct + 1);
462 +
463 + /* Set the separator character, if not specified. */
464 + if (vsep == 'X') {
465 + if (ch == 'c')
466 + vsep = '\0';
467 + else
468 + vsep = ' ';
469 + }
470 +
471 + /* Create the format specifier. */
472 + for (i = j = 0; i < &fmt[-1] - pct; i++) {
473 + switch (pct[i]) {
474 + case ',': case ';': case ':': case '_':
475 + case 'v': case 'h': case 'l':
476 + /* Ignore. */
477 + break;
478 + case '*':
479 + if (pct[i - 1] != '.')
480 + vwidth = 1;
481 + else
482 + vprec = 1;
483 + /* FALLTHROUGH */
484 + default:
485 + vfmt[j++] = pct[i];
486 + }
487 + }
488 +
489 + /*
490 + * Determine the number of elements in the vector and
491 + * finish up the format specifier.
492 + */
493 + if (flags & SHORTINT) {
494 + vfmt[j++] = 'h';
495 + vcnt = 8;
496 + } else if (flags & LONGINT) {
497 + vfmt[j++] = 'l';
498 + vcnt = 4;
499 + } else {
500 + switch (ch) {
501 + case 'a':
502 + case 'A':
503 + case 'e':
504 + case 'E':
505 + case 'f':
506 + case 'g':
507 + case 'G':
508 + vcnt = 4;
509 + break;
510 + default:
511 + /*
512 + * The default case should never
513 + * happen.
514 + */
515 + case 'c':
516 + case 'd':
517 + case 'i':
518 + case 'u':
519 + case 'o':
520 + case 'p':
521 + case 'x':
522 + case 'X':
523 + vcnt = 16;
524 + }
525 + }
526 + vfmt[j++] = ch;
527 + vfmt[j++] = '\0';
528 +
529 +/* Get a vector element. */
530 +#define VPRINT(cnt, ind, args...) do { \
531 + if (flags & FPT) { \
532 + velm.f = vval.vfloatarg[ind]; \
533 + vlen = asprintf(&vstr, vfmt , ## args, velm.f); \
534 + } else { \
535 + switch (cnt) { \
536 + default: \
537 + /* The default case should never happen. */ \
538 + case 4: \
539 + velm.i = (unsigned)vval.vintarg[ind]; \
540 + break; \
541 + case 8: \
542 + velm.i = (unsigned short)vval.vshortarg[ind]; \
543 + break; \
544 + case 16: \
545 + velm.i = (unsigned char)vval.vchararg[ind]; \
546 + break; \
547 + } \
548 + vlen = asprintf(&vstr, vfmt , ## args, velm.i); \
549 + } \
550 + ret += vlen; \
551 + PRINT(vstr, vlen); \
552 + FLUSH(); \
553 + free(vstr); \
554 +} while (0)
555 +
556 + /* Actually print. */
557 + if (vwidth == 0) {
558 + if (vprec == 0) {
559 + /* First element. */
560 + VPRINT(vcnt, 0);
561 + for (i = 1; i < vcnt; i++) {
562 + /* Separator. */
563 + if (vsep)
564 + PRINT(&vsep, 1);
565 +
566 + /* Element. */
567 + VPRINT(vcnt, i);
568 + }
569 + } else {
570 + /* First element. */
571 + VPRINT(vcnt, 0, prec);
572 + for (i = 1; i < vcnt; i++) {
573 + /* Separator. */
574 + if (vsep)
575 + PRINT(&vsep, 1);
576 +
577 + /* Element. */
578 + VPRINT(vcnt, i, prec);
579 + }
580 + }
581 + } else {
582 + if (vprec == 0) {
583 + /* First element. */
584 + VPRINT(vcnt, 0, width);
585 + for (i = 1; i < vcnt; i++) {
586 + /* Separator. */
587 + if (vsep)
588 + PRINT(&vsep, 1);
589 +
590 + /* Element. */
591 + VPRINT(vcnt, i, width);
592 + }
593 + } else {
594 + /* First element. */
595 + VPRINT(vcnt, 0, width, prec);
596 + for (i = 1; i < vcnt; i++) {
597 + /* Separator. */
598 + if (vsep)
599 + PRINT(&vsep, 1);
600 +
601 + /* Element. */
602 + VPRINT(vcnt, i, width, prec);
603 + }
604 + }
605 + }
606 +#undef VPRINT
607 +
608 + if (vfmt != vfmt_buf)
609 + free(vfmt);
610 +
611 + continue;
612 + }
613 +#endif /* ALTIVEC */
614 /*
615 * All reasonable formats wind up here. At this point, `cp'
616 * points to a string which (if not flags&LADJUST) should be
617 @@ -1137,7 +1503,7 @@
618 realsz = dprec > size ? dprec : size;
619 if (sign)
620 realsz++;
621 - else if (ox[1])
622 + if (ox[1])
623 realsz += 2;
624
625 prsize = width > realsz ? width : realsz;
626 @@ -1151,9 +1517,9 @@
627 PAD(width - realsz, blanks);
628
629 /* prefix */
630 - if (sign) {
631 + if (sign)
632 PRINT(&sign, 1);
633 - } else if (ox[1]) { /* ox[1] is either x, X, or \0 */
634 + if (ox[1]) { /* ox[1] is either x, X, or \0 */
635 ox[0] = '0';
636 PRINT(ox, 2);
637 }
638 @@ -1400,6 +1766,11 @@
639 if (flags & LONGINT)
640 ADDTYPE(T_WINT);
641 else
642 +#ifdef ALTIVEC
643 + if (flags & VECTOR)
644 + ADDTYPE(T_VECTOR);
645 + else
646 +#endif /* ALTIVEC */
647 ADDTYPE(T_INT);
648 break;
649 case 'D':
650 @@ -1407,6 +1778,11 @@
651 /*FALLTHROUGH*/
652 case 'd':
653 case 'i':
654 +#ifdef ALTIVEC
655 + if (flags & VECTOR)
656 + ADDTYPE(T_VECTOR);
657 + else
658 +#endif
659 ADDSARG();
660 break;
661 #ifdef FLOATING_POINT
662 @@ -1419,6 +1795,11 @@
663 case 'f':
664 case 'g':
665 case 'G':
666 +#ifdef ALTIVEC
667 + if (flags & VECTOR)
668 + ADDTYPE(T_VECTOR);
669 + else
670 +#endif /* ALTIVEC */
671 if (flags & LONGDBL)
672 ADDTYPE(T_LONG_DOUBLE);
673 else
674 @@ -1447,9 +1828,19 @@
675 flags |= LONGINT;
676 /*FALLTHROUGH*/
677 case 'o':
678 +#ifdef ALTIVEC
679 + if (flags & VECTOR)
680 + ADDTYPE(T_VECTOR);
681 + else
682 +#endif /* ALTIVEC */
683 ADDUARG();
684 break;
685 case 'p':
686 +#ifdef ALTIVEC
687 + if (flags & VECTOR)
688 + ADDTYPE(T_VECTOR);
689 + else
690 +#endif /* ALTIVEC */
691 ADDTYPE(TP_VOID);
692 break;
693 case 'S':
694 @@ -1467,6 +1858,11 @@
695 case 'u':
696 case 'X':
697 case 'x':
698 +#ifdef ALTIVEC
699 + if (flags & VECTOR)
700 + ADDTYPE(T_VECTOR);
701 + else
702 +#endif /* ALTIVEC */
703 ADDUARG();
704 break;
705 default: /* "%?" prints ?, unless ? is NUL */
706 @@ -1552,6 +1948,12 @@
707 (*argtable) [n].longdoublearg = va_arg (ap, long double);
708 break;
709 #endif
710 +#ifdef ALTIVEC
711 + case T_VECTOR:
712 + if (hasAltivec)
713 + ap = getvec( &((*argtable) [n]), NULL, 0, ap );
714 + break;
715 +#endif /* ALTIVEC */
716 case TP_CHAR:
717 (*argtable) [n].pchararg = va_arg (ap, char *);
718 break;