.else
CFLAGS += -D__DARWIN_UNIX03=0
.endif
-.if (${MACHINE_ARCH} == i386)
-CFLAGS += -march=prescott -msse3
-.endif
CFLAGS += -D__LIBC__ -DNOID -I${.CURDIR}/include
.ifdef ALTLIBCHEADERS
INCLUDEDIR = ${ALTLIBCHEADERS}
u_int32_t type; /* entry type: see list, 0 invalid */
u_int32_t offset; /* entry data offset from the beginning of the file. */
u_int32_t length; /* entry data length in bytes. */
-} __attribute__((packed)) apple_double_entry_t;
+} apple_double_entry_t;
typedef struct apple_double_header
apple_double_entry_t entries[2]; /* 'finfo' & 'rsrc' always exist */
u_int8_t finfo[FINDERINFOSIZE]; /* Must start with Finder Info (32 bytes) */
u_int8_t pad[2]; /* get better alignment inside attr_header */
-} __attribute__((packed)) apple_double_header_t;
+} apple_double_header_t;
/* Entries are aligned on 4 byte boundaries */
u_int16_t flags;
u_int8_t namelen; /* length of name including NULL termination char */
u_int8_t name[1]; /* NULL-terminated UTF-8 name (up to 128 bytes max) */
-} __attribute__((packed)) attr_entry_t;
+} attr_entry_t;
/* Header + entries must fit into 64K */
u_int32_t reserved[3];
u_int16_t flags;
u_int16_t num_attrs;
-} __attribute__((packed)) attr_header_t;
+} attr_header_t;
#pragma options align=reset
/*
* Fill in the Apple Double Header defaults.
*/
- filehdr->appledouble.magic = ADH_MAGIC;
- filehdr->appledouble.version = ADH_VERSION;
- filehdr->appledouble.numEntries = 2;
- filehdr->appledouble.entries[0].type = AD_FINDERINFO;
- filehdr->appledouble.entries[0].offset = offsetof(apple_double_header_t, finfo);
- filehdr->appledouble.entries[0].length = FINDERINFOSIZE;
- filehdr->appledouble.entries[1].type = AD_RESOURCE;
- filehdr->appledouble.entries[1].offset = offsetof(apple_double_header_t, pad);
+ filehdr->appledouble.magic = SWAP32 (ADH_MAGIC);
+ filehdr->appledouble.version = SWAP32 (ADH_VERSION);
+ filehdr->appledouble.numEntries = SWAP16 (2);
+ filehdr->appledouble.entries[0].type = SWAP32 (AD_FINDERINFO);
+ filehdr->appledouble.entries[0].offset = SWAP32 (offsetof(apple_double_header_t, finfo));
+ filehdr->appledouble.entries[0].length = SWAP32 (FINDERINFOSIZE);
+ filehdr->appledouble.entries[1].type = SWAP32 (AD_RESOURCE);
+ filehdr->appledouble.entries[1].offset = SWAP32 (offsetof(apple_double_header_t, pad));
filehdr->appledouble.entries[1].length = 0;
bcopy(ADH_MACOSX, filehdr->appledouble.filler, sizeof(filehdr->appledouble.filler));
/*
* Fill in the initial Attribute Header.
*/
- filehdr->magic = ATTR_HDR_MAGIC;
- filehdr->debug_tag = s->sb.st_ino;
- filehdr->data_start = sizeof(attr_header_t);
+ filehdr->magic = SWAP32 (ATTR_HDR_MAGIC);
+ filehdr->debug_tag = SWAP32 (s->sb.st_ino);
+ filehdr->data_start = SWAP32 (sizeof(attr_header_t));
/*
* Collect the attribute names.
filehdr->appledouble.entries[0].length =
filehdr->appledouble.entries[1].offset - filehdr->appledouble.entries[0].offset;
- filehdr->total_size = filehdr->appledouble.entries[1].offset;
+ filehdr->total_size = SWAP32 (filehdr->appledouble.entries[1].offset);
}
/* Copy Resource Fork. */
/* Write the header to disk. */
datasize = filehdr->appledouble.entries[1].offset;
- swap_adhdr(&filehdr->appledouble);
- swap_attrhdr(filehdr);
-
if (pwrite(s->dst_fd, filehdr, datasize, 0) != datasize)
{
if (COPYFILE_VERBOSE & s->flags)
---- _ldtoa.c.orig 2004-06-03 15:17:18.000000000 -0700
-+++ _ldtoa.c 2005-10-08 22:43:25.000000000 -0700
+--- _ldtoa.c.orig 2004-12-08 22:50:28.000000000 -0800
++++ _ldtoa.c 2004-12-08 22:52:58.000000000 -0800
@@ -61,14 +61,34 @@
char *ret;
union IEEEl2bits u;
kind = STRTOG_Normal;
#ifdef LDBL_IMPLICIT_NBIT
bits[LDBL_MANT_DIG / 32] |= 1 << ((LDBL_MANT_DIG - 1) % 32);
-@@ -77,12 +97,12 @@
+@@ -77,12 +97,14 @@
case FP_ZERO:
kind = STRTOG_Zero;
break;
+#if !defined(__ppc__) && !defined(__ppc64__)
case FP_SUBNORMAL:
kind = STRTOG_Denormal;
--#ifdef LDBL_IMPLICIT_NBIT
+ #ifdef LDBL_IMPLICIT_NBIT
be++;
--#endif
+ #endif
break;
+#endif /* !defined(__ppc__) && !defined(__ppc64__) */
case FP_INFINITE:
kind = STRTOG_Infinite;
break;
-@@ -96,5 +116,9 @@
+@@ -96,5 +118,9 @@
ret = gdtoa(&fpi, be, (ULong *)bits, &kind, mode, ndigits, decpt, rve);
if (*decpt == -32768)
*decpt = INT_MAX;
* with " at " changed at "@" and " dot " changed to "."). */
#include "gdtoaimp.h"
-#ifndef NO_FENV_H
-#include <fenv.h>
-#endif
#ifdef USE_LOCALE
#include "locale.h"
switch(s[1]) {
case 'x':
case 'X':
- {
-#if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD)
- FPI fpi1 = fpi;
- switch(fegetround()) {
- case FE_TOWARDZERO: fpi1.rounding = 0; break;
- case FE_UPWARD: fpi1.rounding = 2; break;
- case FE_DOWNWARD: fpi1.rounding = 3;
- }
-#else
-#define fpi1 fpi
-#endif
- switch((i = gethex(&s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) {
+ switch((i = gethex(&s, &fpi, &exp, &bb, sign)) & STRTOG_Retmask) {
case STRTOG_NoNumber:
s = s00;
sign = 0;
Bfree(bb);
}
ULtod(((U*)&rv)->L, bits, exp, i);
- }}
+ }
goto ret;
}
}
---- gdtoa-strtod.c.orig 2005-10-08 11:32:33.000000000 -0700
-+++ gdtoa-strtod.c 2005-10-08 11:38:17.000000000 -0700
+--- gdtoa-strtod.c.orig 2005-01-20 20:12:37.000000000 -0800
++++ gdtoa-strtod.c 2005-02-17 01:31:26.000000000 -0800
@@ -29,6 +29,8 @@
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
+#include "xlocale_private.h"
+
#include "gdtoaimp.h"
- #ifndef NO_FENV_H
- #include <fenv.h>
-@@ -59,11 +61,11 @@
+
+ #ifdef USE_LOCALE
+@@ -56,11 +58,11 @@
#endif
double
#endif
{
#ifdef Avoid_Underflow
-@@ -126,7 +128,7 @@
- #else
- #define fpi1 fpi
- #endif
-- switch((i = gethex(&s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) {
-+ switch((i = gethex(&s, &fpi1, &exp, &bb, sign, loc)) & STRTOG_Retmask) {
+@@ -112,7 +114,7 @@
+ switch(s[1]) {
+ case 'x':
+ case 'X':
+- switch((i = gethex(&s, &fpi, &exp, &bb, sign)) & STRTOG_Retmask) {
++ switch((i = gethex(&s, &fpi, &exp, &bb, sign, loc)) & STRTOG_Retmask) {
case STRTOG_NoNumber:
s = s00;
sign = 0;
-@@ -156,8 +158,9 @@
+@@ -142,8 +144,9 @@
else if (nd < 16)
z = 10*z + c - '0';
nd0 = nd;
#else
if (c == '.')
#endif
-@@ -980,3 +983,13 @@
+@@ -966,3 +969,13 @@
return sign ? -dval(rv) : dval(rv);
}
}
bb0 = 0; /* trailing zero bits in rvb */
e2 = rve + rvbits - nbits;
- if (e2 > fpi->emax + 1)
- goto huge;
+ if (e2 > fpi->emax) {
+ rvb->wds = 0;
+ irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
+#ifndef NO_ERRNO
+ errno = ERANGE;
+#endif
+ infnanexp:
+ *exp = fpi->emax + 1;
+ goto ret;
+ }
rve1 = rve + rvbits - nbits;
if (e2 < (emin = fpi->emin)) {
denorm = 1;
Bfree(bs);
Bfree(bd0);
Bfree(delta);
- if (rve > fpi->emax) {
- huge:
- rvb->wds = 0;
- irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
-#ifndef NO_ERRNO
- errno = ERANGE;
-#endif
- infnanexp:
- *exp = fpi->emax + 1;
- }
ret:
if (denorm) {
if (sudden_underflow) {
---- gdtoa-strtodg.c.orig 2005-10-08 11:33:23.000000000 -0700
-+++ gdtoa-strtodg.c 2005-10-08 11:40:57.000000000 -0700
+--- gdtoa-strtodg.c.orig 2005-01-20 20:12:37.000000000 -0800
++++ gdtoa-strtodg.c 2005-02-17 01:32:24.000000000 -0800
@@ -29,6 +29,8 @@
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
#else
if (c == '.')
#endif
-@@ -668,6 +671,9 @@
+@@ -676,6 +679,9 @@
rvb->x[0] = 0;
*exp = emin;
irv = STRTOG_Underflow | STRTOG_Inexlo;
--- gdtoa_strtopx.c.orig 2005-01-20 20:12:37.000000000 -0800
-+++ gdtoa_strtopx.c 2005-10-08 17:10:15.000000000 -0700
++++ gdtoa_strtopx.c 2005-02-17 01:54:02.000000000 -0800
@@ -29,6 +29,8 @@
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
-@@ -87,7 +89,8 @@
-
- case STRTOG_Infinite:
- L[_0] = 0x7fff;
-- L[_1] = L[_2] = L[_3] = L[_4] = 0;
-+ L[_1] = 0x8000;
-+ L[_2] = L[_3] = L[_4] = 0;
- break;
-
- case STRTOG_NaN:
---- popen.c.orig 2003-05-20 15:21:02.000000000 -0700
-+++ popen.c 2005-09-17 16:08:55.000000000 -0700
+--- popen.c.orig Mon May 24 23:50:41 2004
++++ popen.c Tue May 25 00:09:39 2004
@@ -43,6 +43,7 @@
#include "namespace.h"
#include <sys/param.h>
if ((cur = malloc(sizeof(struct pid))) == NULL) {
(void)_close(pdes[0]);
-@@ -104,7 +106,7 @@
- argv[3] = NULL;
-
- THREAD_LOCK();
-- switch (pid = vfork()) {
-+ switch (pid = fork()) {
- case -1: /* Error. */
- THREAD_UNLOCK();
- (void)_close(pdes[0]);
@@ -138,7 +140,7 @@
(void)_close(pdes[1]);
}
---- setprogname.c.orig 2003-05-20 15:21:02.000000000 -0700
-+++ setprogname.c 2005-10-26 00:58:44.000000000 -0700
-@@ -3,6 +3,10 @@
+--- setprogname.c.orig Mon Apr 28 15:05:02 2003
++++ setprogname.c Fri May 16 14:13:59 2003
+@@ -3,6 +3,8 @@
#include <stdlib.h>
#include <string.h>
-+#include <sys/param.h>
-+#include <sys/sysctl.h>
+#include <crt_externs.h>
+#define __progname (*_NSGetProgname())
#include "libc_private.h"
-@@ -10,10 +14,20 @@
- setprogname(const char *progname)
- {
- const char *p;
--
-+ char buf[2*MAXCOMLEN+1];
-+ int mib[2];
-+
+@@ -13,7 +15,7 @@
+
p = strrchr(progname, '/');
if (p != NULL)
- __progname = p + 1;
-+ __progname = (char *)(++p);
++ __progname = (char *)(p + 1);
else
- __progname = progname;
-+ __progname = (char *)(p = progname);
-+
-+ strlcpy(&buf[0], p, sizeof(buf));
-+
-+ mib[0] = CTL_KERN;
-+ mib[1] = KERN_PROCNAME;
-+
-+ /* ignore errors as this is not a hard error */
-+ sysctl(mib, 2, NULL, NULL, &buf[0], 2*MAXCOMLEN);
++ __progname = (char *)progname;
}
#include <errno.h>
#include <uuid/uuid.h>
-/*
- * Versions of copy_int/copy_ext that retain native endianity.
- */
-extern ssize_t acl_copy_ext_native(void *buf_p, acl_t acl, ssize_t size);
-extern acl_t acl_copy_int_native(const void *buf_p);
struct _filesec {
int fs_valid;
if (fsec->fs_aclbuf == _FILESEC_REMOVE_ACL) {
*(acl_t *)propptr = _FILESEC_REMOVE_ACL;
} else {
- *(acl_t *)propptr = acl_copy_int_native(fsec->fs_aclbuf);
+ *(acl_t *)propptr = acl_copy_int(fsec->fs_aclbuf);
if (*(acl_t *)propptr == NULL)
error = errno;
}
error = errno;
break;
}
- copysize = acl_copy_ext_native(aclbuf, acl, aclsize);
+ copysize = acl_copy_ext(aclbuf, acl, aclsize);
if (copysize < 0) {
free(aclbuf);
error = EINVAL;
boolean_t add_guard_pages = debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES;
size_t allocation_size = round_page(size);
size_t delta;
-
+
if (align) add_guard_pages = 0; // too cumbersome to deal with that
if (!allocation_size) allocation_size = 1 << vm_page_shift;
if (add_guard_pages) allocation_size += 2 * (1 << vm_page_shift);
} else {
// large or huge
num_pages = round_page(size) >> vm_page_shift;
- if (num_pages == 0) /* Overflowed */
- ptr = 0;
- else
- ptr = large_and_huge_malloc(szone, num_pages);
+ ptr = large_and_huge_malloc(szone, num_pages);
}
#if DEBUG_MALLOC
if (LOG(szone, ptr))
/*************** Recording stack ***********/
-// The three functions below are marked as noinline to ensure consistent inlining across
-// all versions of GCC and all compiler flags. The malloc stack logging code expects
-// these functions to not be inlined.
-// For details, see <rdar://problem/4199620>.
-//
-// The performance cost of not inlining these functions is negligible, and they're only
-// called when MallocStackLogging is set anyway, so they won't affect normal usage.
-
-static __attribute__((noinline)) void *first_frame_address(void) {
+static void *first_frame_address(void) {
#if defined(__i386__)
- return __builtin_frame_address(0);
+ return __builtin_frame_address(1);
#elif defined(__ppc__) || defined(__ppc64__)
void *addr;
#warning __builtin_frame_address IS BROKEN IN BEAKER: RADAR #2340421
#endif
}
-static __attribute__((noinline)) void *next_frame_address(void *addr) {
+static void *next_frame_address(void *addr) {
void *ret;
#if defined(__MACH__) && defined(__i386__)
__asm__ volatile("movl (%1),%0" : "=r" (ret) : "r" (addr));
#error ********** Unimplemented architecture
#endif
-__attribute__((noinline)) void thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *nb) {
+void thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *nb) {
void *addr;
addr = first_frame_address();
*nb = 0;
* @APPLE_LICENSE_HEADER_END@
*/
-#include <mach/i386/syscall_sw.h>
-
.text
.align 2, 0x90
.globl ___pthread_set_self
pushl 4(%esp)
pushl $0
movl $3,%eax
- MACHDEP_SYSCALL_TRAP
+ lcall $0x3b,$0
addl $8,%esp
movw %ax,%gs
ret
bzero.s \
memcpy.s \
memmove.s \
- strlen.s \
- strcpy.s \
- strcmp.s \
- strncpy.s \
- strncmp.s \
- memcmp.s \
- bcmp.s \
- memset.s
+ strcmp.s
+++ /dev/null
-/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * bcmp() is implemented in memcmp.s, as it is equivalent to memcmp() in OSX.
- * (The two symbols, bcmp and memcmp, have the same value.)
- * This empty file is here to prevent the Free BSD machine independent version
- * from building.
- */
+++ /dev/null
-/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-// *************** ***********
-// * M E M C M P * and * B C M P *
-// *************** ***********
-//
-// int memcmp(const char *s1, const char *s2, size_t len);
-// int bcmp(const char *s1, const char *s2, size_t len);
-//
-// Bcmp returns (+,0,-), whereas memcmp returns the true difference
-// between the first differing bytes, but we treat them identically.
-//
-// We optimize the compare by doing it with SSE. This introduces
-// a complication: if we blindly did vector loads from both sides until
-// finding a difference, we might get a spurious page fault by
-// reading bytes past the difference. To avoid this, we never do a load
-// that crosses a page boundary.
-
-#define kShort 18 // too short for vectors (must be >16)
-
- .text
- .align 4
-
- .globl _memcmp
- .globl _bcmp
-
-_memcmp: // int memcmp(const char *s1,const char *s2,size_t len);
-_bcmp: // int bcmp(const char *s1,const char *s2,size_t len);
- pushl %esi
- pushl %edi
- movl 20(%esp),%ecx // get length
- movl 12(%esp),%esi // get LHS ptr
- movl 16(%esp),%edi // get RHS ptr
- cmpl $(kShort),%ecx // worth accelerating?
- ja LNotShort // yes
-
-
-// Too short to bother with parallel compares. Loop over bytes.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %ecx = length (<= kShort)
-
-LShort:
- testl %ecx,%ecx // 0-length?
- jnz LShortLoop // no
- xorl %eax,%eax // return 0
- jmp LExit
- .align 4,0x90 // align inner loops to optimize I-fetch
-LShortLoop: // loop over bytes
- movzb (%esi),%eax // get LHS byte
- movzb (%edi),%edx // get RHS byte
- incl %esi
- incl %edi
- subl %edx,%eax // compare them
- jnz LExit // done if not equal
- decl %ecx // decrement length
- jnz LShortLoop
-LExit: // return value is in %eax
- popl %edi
- popl %esi
- ret
-
-LNotEqual: // here from LLoopOverBytes with LHS in eax
- movzb (%edi),%edx // get RHS byte
- subl %edx,%eax // generate return value (nonzero)
- popl %edi
- popl %esi
- ret
-
-
-// Loop over bytes until we reach end of a page.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %ecx = length remaining after end of loop (ie, already adjusted)
-// %edx = #bytes until next page (1..15)
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverBytes:
- movzb (%esi),%eax // get LHS byte
- inc %esi
- cmpb (%edi),%al // compare to RHS byte
- jnz LNotEqual // done if not equal
- inc %edi
- dec %edx // more to go?
- jnz LLoopOverBytes
-
-
-// Long enough to justify overhead of setting up vector compares. In order to
-// avoid spurious page faults, we loop over:
-//
-// min( length, bytes_in_LHS_page, bytes_in_RHS_page) >> 4
-//
-// 16-byte chunks. When we near a page end, we have to revert to a byte-by-byte
-// comparison until reaching the next page, then resume the vector comparison.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %ecx = length (> kShort)
-
-LNotShort:
- movl %esi,%eax // copy ptrs
- movl %edi,%edx
- andl $4095,%eax // mask down to page offsets
- andl $4095,%edx
- cmpl %eax,%edx // which is bigger?
- cmova %edx,%eax // %eax = max(LHS offset, RHS offset);
- movl $4096,%edx
- subl %eax,%edx // get #bytes to next page crossing
- cmpl %ecx,%edx // will operand run out first?
- cmova %ecx,%edx // get min(length remaining, bytes to page end)
- movl %edx,%eax
- shrl $4,%edx // get #chunks till end of operand or page
- jnz LLoopOverChunks // enter vector loop
-
-// Too near page end for vectors.
-
- subl %eax,%ecx // adjust length remaining
- movl %eax,%edx // %edx <- #bytes to page end
- cmpl $(kShort),%ecx // will there be enough after we cross page for vectors?
- ja LLoopOverBytes // yes
- addl %eax,%ecx // no, restore total length remaining
- jmp LShortLoop // compare rest byte-by-byte (%ecx != 0)
-
-
-// Loop over 16-byte chunks.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %ecx = length remaining
-// %edx = chunk count
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverChunks:
- movdqu (%esi),%xmm0 // get LHS
- movdqu (%edi),%xmm1 // get RHS
- addl $16,%esi
- pcmpeqb %xmm1,%xmm0 // compare LHS to RHS
- addl $16,%edi
- pmovmskb %xmm0,%eax // collect comparison result bits (1 if equal)
- subl $16,%ecx // adjust length remaining
- xorl $0xFFFF,%eax // all equal?
- jne LDifferent // no, we found differing bytes
- dec %edx // more to go?
- jnz LLoopOverChunks
-
- cmpl $(kShort),%ecx // a lot more to compare?
- jbe LShort // no
- jmp LNotShort // compute distance to next page crossing etc
-
-
-// Found a difference.
-// %esi = LHS ptr, already advanced by 16
-// %edi = RHS ptr, already advanced by 16
-// %eax = complemented compare vector (ie, 0 == equal)
-
-LDifferent:
- bsf %eax,%edx // which byte differed?
- subl $16,%esi // point to byte 0 while we wait for bit scan
- subl $16,%edi
- movzb (%esi,%edx),%eax // get LHS byte
- movzb (%edi,%edx),%ecx // get RHS byte
- subl %ecx,%eax // compute difference (ie, return value)
- popl %edi
- popl %esi
- ret
+++ /dev/null
-/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- *
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-
-
-/* This file contains the following functions:
- *
- * void *memset(void *b, int c, size_t len);
- * void memset_pattern4(void *b, const void *c4, size_t len);
- * void memset_pattern8(void *b, const void *c8, size_t len);
- * void memset_pattern16(void *b, const void *c16, size_t len);
- *
- * Calls of memset() with c==0 are routed to the bzero() routine. Most of the
- * others go to _COMM_PAGE_MEMSET_PATTERN, which is entered as follows:
- * %edi = ptr to memory to set (aligned)
- * %edx = length (which can be short, though we bias in favor of long operands)
- * %xmm0 = the pattern to store
- * Return conditions:
- * %eax, %edi, %esi, %ecx, and %edx all trashed
- *
- * NB: we avoid "stos" family of instructions (stosl, stosb), as they are very slow
- * on P4s and probably other processors.
- */
-
- #define kShort 255 // for nonzero memset(), too short for commpage
-
-
- .text
- .globl _memset
- .align 2
-_memset: // void *memset(void *b, int c, size_t len);
- movl 8(%esp),%eax // get 1-byte pattern
- movl 12(%esp),%edx // get length
- andl $0xFF,%eax // (c==0) ?
- jnz LNonzero // not a bzero
-
- movl $(_COMM_PAGE_BZERO),%eax// map memset(p,0,n) into bzero(p,n)
- movl %edx,8(%esp) // put count where bzero() expects it
- jmp %eax // enter commpage
-
-
- // Handle memset of a nonzero value.
-
-LNonzero:
- pushl %edi // save a few nonvolatiles
- pushl %esi
- movl %eax,%esi // replicate byte in %al into all four bytes
- movl 12(%esp),%edi // point to operand
- shll $8,%esi
- orl %esi,%eax
- movl %eax,%esi
- shll $16,%esi
- orl %esi,%eax // now %eax has "c" in all 4 bytes
- cmpl $(kShort),%edx // is operand too short for SSE?
- ja LCallCommpage // no
-
-// Nonzero memset() too short to call commpage.
-// %eax = replicated 4-byte pattern
-// %edi = ptr
-// %edx = length (<= kShort)
-
- cmpl $16,%edx // long enough to word align?
- jge 3f // yes
- test %edx,%edx // length==0?
- jz 6f
-1:
- movb %al,(%edi) // pack in a byte
- inc %edi
- dec %edx
- jnz 1b
- jmp 6f
-2:
- movb %al,(%edi) // pack in a byte
- inc %edi
- dec %edx
-3:
- test $3,%edi // is ptr doubleword aligned?
- jnz 2b // no
- movl %edx,%ecx // copy length
- shrl $2,%edx // #doublewords to store
-4:
- movl %eax,(%edi) // store aligned doubleword
- addl $4,%edi
- dec %edx
- jnz 4b
- andl $3,%ecx // any leftover bytes?
- jz 6f // no
-5:
- movb %al,(%edi) // pack in a byte
- inc %edi
- dec %ecx
- jnz 5b
-6:
- movl 12(%esp),%eax // get return value (ie, original ptr)
- popl %esi
- popl %edi
- ret
-
-// Nonzero memset() is long enough to call commpage.
-// %eax = replicated 4-byte pattern
-// %edi = ptr
-// %edx = length (> kShort)
-
-LCallCommpage:
- movd %eax,%xmm0 // move %eax to low 4 bytes of %xmm0
- pshufd $(0x00),%xmm0,%xmm0 // replicate across the vector
- movl %edi,%ecx // copy dest ptr
- negl %ecx
- andl $15,%ecx // get #bytes to align ptr
- jz 2f // skip if already aligned
- subl %ecx,%edx // decrement length
-1:
- movb %al,(%edi) // pack in a byte
- inc %edi
- dec %ecx
- jnz 1b
-2: // ptr aligned, length long enough to justify
- movl $(_COMM_PAGE_MEMSET_PATTERN),%eax
- call %eax // call commpage to do the heavy lifting
- movl 12(%esp),%eax // get return value (ie, original ptr)
- popl %esi
- popl %edi
- ret
-
-
-// Handle memset of a 16-byte pattern.
-
- .globl _memset_pattern16
- .align 2, 0x90
-_memset_pattern16: // void memset_pattern16(void *b, const void *c16, size_t len);
- pushl %edi
- pushl %esi
- movl 20(%esp),%edx // get length
- movl 16(%esp),%esi // get ptr to 16-byte pattern
- movl 12(%esp),%edi // point to operand
- movdqu (%esi),%xmm0 // load the pattern
- jmp LAlignPtr
-
-
-// Handle memset of an 8-byte pattern.
-
- .globl _memset_pattern8
- .align 2, 0x90
-_memset_pattern8: // void memset_pattern8(void *b, const void *c8, size_t len);
- pushl %edi
- pushl %esi
- movl 20(%esp),%edx // get length
- movl 16(%esp),%esi // get ptr to 8-byte pattern
- movl 12(%esp),%edi // point to operand
- movq (%esi),%xmm0 // load pattern into low 8 bytes
- punpcklqdq %xmm0,%xmm0 // replicate into all 16
- jmp LAlignPtr
-
-// Handle memset of a 4-byte pattern.
-
- .globl _memset_pattern4
- .align 2, 0x90
-_memset_pattern4: // void memset_pattern4(void *b, const void *c4, size_t len);
- pushl %edi
- pushl %esi
- movl 20(%esp),%edx // get length
- movl 16(%esp),%esi // get ptr to 4-byte pattern
- movl 12(%esp),%edi // point to operand
- movd (%esi),%xmm0 // load pattern into low 4 bytes
- pshufd $(0x00),%xmm0,%xmm0 // replicate the 4 bytes across the vector
-
-
-// Align ptr if necessary. We must rotate the pattern right for each byte we
-// store while aligning the ptr. Since there is no rotate instruction in SSE3,
-// we have to synthesize the rotates.
-// %edi = ptr
-// %edx = length
-// %xmm0 = pattern
-
-LAlignPtr: // NB: can drop down to here!
- cmpl $100,%edx // long enough to bother aligning ptr?
- movl %edi,%ecx // copy ptr
- jb LReady // not long enough
- negl %ecx
- andl $15,%ecx // get #bytes to align ptr
- jz LReady // already aligned
- subl %ecx,%edx // adjust length
-
- test $1,%cl // 1-byte store required?
- movd %xmm0,%eax // get 4 low bytes in %eax
- jz 2f // no
- movdqa %xmm0,%xmm1 // copy pattern so we can shift in both directions
- movb %al,(%edi) // pack in the low-order byte
- psrldq $1,%xmm0 // shift pattern right 1 byte
- inc %edi
- pslldq $15,%xmm1 // shift pattern left 15 bytes
- shrl $8,%eax // in case 2-byte store is required
- por %xmm1,%xmm0 // complete right rotate of pattern by 1 byte
-2:
- test $2,%cl // 2-byte store required?
- jz 4f // no
- psrldq $2,%xmm0 // shift pattern down 2 bytes
- movw %ax,(%edi) // pack in next two bytes
- pinsrw $7,%eax,%xmm0 // insert low word of %eax into high word of %xmm0
- addl $2,%edi // adjust ptr
-4:
- test $4,%cl // 4-byte store required?
- jz 8f // no
- movd %xmm0,(%edi) // store low 4 bytes of %xmm0
- pshufd $(0x39),%xmm0,%xmm0 // rotate %xmm0 right 4 bytes (mask == 00 11 10 01)
- addl $4,%edi // adjust ptr
-8:
- test $8,%cl // 8-byte store required?
- jz LReady // no
- movq %xmm0,(%edi) // store low 8 bytes of %xmm0
- pshufd $(0x4e),%xmm0,%xmm0 // rotate %xmm0 right 8 bytes (mask == 01 00 11 10)
- addl $8,%edi // adjust ptr
-
-// Ptr is aligned if practical, we're ready to call commpage to do the heavy lifting.
-
-LReady:
- movl $(_COMM_PAGE_MEMSET_PATTERN),%eax
- call %eax // call commpage to do the heavy lifting
- popl %esi
- popl %edi
- ret
/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
*
* @APPLE_LICENSE_HEADER_END@
*/
-
-
-// ***************
-// * S T R C M P *
-// ***************
-//
-// int strcmp(const char *s1, const char *s2);
-//
-// We optimize the compare by doing it in parallel, using SSE. This introduces
-// a complication: if we blindly did vector loads from both sides until
-// finding a difference (or 0), we might get a spurious page fault by
-// reading bytes past the difference. To avoid this, we never do a load
-// that crosses a page boundary.
-
- .text
- .globl _strcmp
-
- .align 4
-_strcmp: // int strcmp(const char *s1,const char *s2);
- pushl %esi
- pushl %edi
- movl 12(%esp),%esi // get LHS ptr
- movl 16(%esp),%edi // get RHS ptr
-
-
-// In order to avoid spurious page faults, we loop over:
-//
-// min( bytes_in_LHS_page, bytes_in_RHS_page) >> 4
-//
-// 16-byte chunks. When we near a page end, we have to revert to a byte-by-byte
-// comparison until reaching the next page, then resume the vector comparison.
-// %esi = LHS ptr
-// %edi = RHS ptr
-
-LNextChunk:
- movl %esi,%eax // copy ptrs
- movl %edi,%edx
- andl $4095,%eax // mask down to page offsets
- andl $4095,%edx
- cmpl %eax,%edx // which is bigger?
- cmova %edx,%eax // %eax = max(LHS offset, RHS offset);
- movl $4096,%edx
- subl %eax,%edx // get #bytes to next page crossing
- movl %edx,%eax
- shrl $4,%edx // get #chunks till end of operand or page
- jnz LLoopOverChunks // enter vector loop
- movl %eax,%edx // no chunks...
- jmp LLoopOverBytes // ...so loop over bytes until page end
-
-
-// Loop over bytes.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %edx = byte count
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverBytes:
- movzb (%esi),%eax // get LHS byte
- movzb (%edi),%ecx // get RHS byte
- inc %esi
- inc %edi
- testl %eax,%eax // 0?
- jz LExit0 // yes, we're done
- subl %ecx,%eax // compare them
- jnz LExit // done if not equal
- dec %edx // more to go?
- jnz LLoopOverBytes
-
- jmp LNextChunk // we've come to end of page
-
-
-// Loop over 16-byte chunks.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %edx = chunk count
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverChunks:
- movdqu (%esi),%xmm1 // get LHS
- movdqu (%edi),%xmm2 // get RHS
- pxor %xmm0,%xmm0 // get some 0s in the shadow of the loads
- addl $16,%esi
- pcmpeqb %xmm1,%xmm2 // compare LHS to RHS
- pcmpeqb %xmm1,%xmm0 // compare LHS to 0s
- addl $16,%edi
- pmovmskb %xmm2,%eax // get result mask for comparison of LHS and RHS
- pmovmskb %xmm0,%ecx // get result mask for 0 check
- xorl $0xFFFF,%eax // complement compare mask so 1 means "not equal"
- orl %ecx,%eax // combine the masks and check for 1-bits
- jnz LFoundDiffOr0 // we found differing bytes or a 0-byte
- dec %edx // more to go?
- jnz LLoopOverChunks
-
- jmp LNextChunk // compare up to next page boundary
-
-
-// Found a zero and/or a difference in vector compare.
-// %esi = LHS ptr, already advanced by 16
-// %edi = RHS ptr, already advanced by 16
-// %eax = bit n set if bytes n differed or were 0
-
-LFoundDiffOr0:
- bsf %eax,%edx // which byte differed or was 0?
- subl $16,%esi // point to start of vectors while we wait for bit scan
- subl $16,%edi
- movzb (%esi,%edx),%eax // get LHS byte
- movzb (%edi,%edx),%ecx // get RHS byte
- subl %ecx,%eax // compute difference (ie, return value)
- popl %edi
- popl %esi
- ret
-
-
-// Found a zero and/or difference in byte loop.
-// %eax = LHS byte
-// %ecx = RHS byte
-
-LExit0:
- subl %ecx,%eax // compute difference (ie, return value)
-LExit: // here with difference already in %eax
- popl %edi
- popl %esi
- ret
+.text
+.globl _strcmp
+_strcmp:
+ movl 0x04(%esp),%eax
+ movl 0x08(%esp),%edx
+ jmp L2 /* Jump into the loop! */
+
+ .align 2,0x90
+L1: incl %eax
+ incl %edx
+L2: movb (%eax),%cl
+ testb %cl,%cl /* null terminator??? */
+ jz L3
+ cmpb %cl,(%edx) /* chars match??? */
+ jne L3
+ incl %eax
+ incl %edx
+ movb (%eax),%cl
+ testb %cl,%cl
+ jz L3
+ cmpb %cl,(%edx)
+ jne L3
+ incl %eax
+ incl %edx
+ movb (%eax),%cl
+ testb %cl,%cl
+ jz L3
+ cmpb %cl,(%edx)
+ jne L3
+ incl %eax
+ incl %edx
+ movb (%eax),%cl
+ testb %cl,%cl
+ jz L3
+ cmpb %cl,(%edx)
+ jne L3
+ incl %eax
+ incl %edx
+ movb (%eax),%cl
+ testb %cl,%cl
+ jz L3
+ cmpb %cl,(%edx)
+ jne L3
+ incl %eax
+ incl %edx
+ movb (%eax),%cl
+ testb %cl,%cl
+ jz L3
+ cmpb %cl,(%edx)
+ jne L3
+ incl %eax
+ incl %edx
+ movb (%eax),%cl
+ testb %cl,%cl
+ jz L3
+ cmpb %cl,(%edx)
+ jne L3
+ incl %eax
+ incl %edx
+ movb (%eax),%cl
+ testb %cl,%cl
+ jz L3
+ cmpb %cl,(%edx)
+ je L1
+ .align 2, 0x90
+L3: movzbl (%eax),%eax /* unsigned comparison */
+ movzbl (%edx),%edx
+ subl %edx,%eax
+ ret
+++ /dev/null
-/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-// ***************
-// * S T R C P Y *
-// ***************
-//
-// char *strcpy(const char *dst, const char *src);
-//
-// We optimize the move by doing it vector parallel. This introduces
-// a complication: if we blindly did vector load/stores until finding
-// a 0, we might get a spurious page fault by touching bytes past it.
-// To avoid this, we never do a load that crosses a page boundary,
-// and never store a byte we don't have to.
-//
-// We align the destination, because unaligned vector stores are slow.
-
- .text
- .globl _strcpy
-
- .align 4
-_strcpy: // char *strcpy(const char *dst, const char *src);
- pushl %edi
- movl 8(%esp),%edi // get dest ptr
- movl 12(%esp),%ecx // get source ptr
- movl %edi,%edx // copy dest ptr
- negl %edx
- andl $15,%edx // how many bytes to align dest ptr?
- jnz LLoopOverBytes // not aligned, so go do so
-
-
-// In order to avoid spurious page faults, we loop until nearing the source page
-// end. Then we revert to a byte-by-byte loop for 16 bytes until the page is crossed,
-// then resume the vector loop.
-// %ecx = source ptr (unaligned)
-// %edi = dest ptr (aligned)
-
-LNextChunk:
- movl %ecx,%eax // copy source ptr
- movl $4096,%edx
- andl $4095,%eax // get offset into source page
- subl %eax,%edx // get #bytes remaining in source page
- shrl $4,%edx // get #chunks till end of page
- jnz LLoopOverChunks // enter vector loop
- movl $16,%edx // move 16 bytes to cross page but keep dest aligned
- jmp LLoopOverBytes
-
-
-// Loop over bytes.
-// %ecx = source ptr
-// %edi = dest ptr
-// %edx = byte count
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverBytes:
- movzb (%ecx),%eax // get source byte
- inc %ecx
- movb %al,(%edi) // pack into dest
- inc %edi
- testl %eax,%eax // 0?
- jz LDone // yes, we're done
- dec %edx // more to go?
- jnz LLoopOverBytes
-
- jmp LNextChunk // we've come to end of page
-
-
-// Loop over 16-byte chunks.
-// %ecx = source ptr (unaligned)
-// %edi = dest ptr (aligned)
-// %edx = chunk count
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverChunks:
- movdqu (%ecx),%xmm1 // get source
- pxor %xmm0,%xmm0 // get some 0s
- addl $16,%ecx
- pcmpeqb %xmm1,%xmm0 // compare source to 0s
- pmovmskb %xmm0,%eax // get result mask for 0 check
- testl %eax,%eax // any 0s?
- jnz LFound0 // yes, exit loop
- movdqa %xmm1,(%edi) // no 0s so do aligned store into destination
- addl $16,%edi
- dec %edx // more to go?
- jnz LLoopOverChunks
-
- movl $16,%edx // move 16 bytes
- jmp LLoopOverBytes // cross page but keep dest aligned
-
-
-// Found a zero in the vector. Figure out where it is, and store the bytes
-// up to it.
-// %edi = dest ptr (aligned)
-// %eax = result mask
-// %xmm1 = source vector
-
-LFound0:
- bsf %eax,%edx // find first 0
- inc %edx // we need to store the 0 too
- test $16,%dl // was 0 last byte?
- jz 8f // no
- movdqa %xmm1,(%edi) // yes, store entire vector
- jmp LDone
-8:
- test $8,%dl // 8-byte store required?
- jz 4f // no
- movq %xmm1,(%edi) // pack in 8 low bytes
- psrldq $8,%xmm1 // then shift vector down 8 bytes
- addl $8,%edi
-4:
- test $4,%dl // 4-byte store required?
- jz 3f // no
- movd %xmm1,(%edi) // pack in 4 low bytes
- psrldq $4,%xmm1 // then shift vector down 4 bytes
- addl $4,%edi
-3:
- andl $3,%edx // more to go?
- jz LDone // no
- movd %xmm1,%eax // move remainders out of vector into %eax
-1: // loop on up to three bytes
- movb %al,(%edi) // pack in next byte
- shrl $8,%eax // shift next byte into position
- inc %edi
- dec %edx
- jnz 1b
-
-LDone:
- movl 8(%esp),%eax // original dest ptr is return value
- popl %edi
- ret
+++ /dev/null
-/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- *
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * Strlen, for processors with SSE3.
- *
- * Note that all memory references must be aligned, in order to avoid spurious
- * page faults. Thus we have to load the aligned 16-byte chunk containing the
- * first byte of the operand, then mask out false 0s that may occur before the
- * first byte.
- *
- * We favor the fall-through (ie, short operand) path.
- */
-
- .text
- .globl _strlen
- .align 4, 0x90
-_strlen: // size_t strlen(char *b);
- movl 4(%esp),%edx // get ptr to string
- pxor %xmm0,%xmm0 // zero %xmm0
- movl %edx,%ecx // copy ptr
- andl $(-16),%edx // 16-byte align ptr
- orl $(-1),%eax
- pcmpeqb (%edx),%xmm0 // check whole qw for 0s
- andl $15,%ecx // get #bytes in aligned dq before operand
- shl %cl,%eax // create mask for the bytes of aligned dq in operand
- pmovmskb %xmm0,%ecx // collect mask of 0-bytes
- andl %eax,%ecx // mask out any 0s that occur before 1st byte
- jz LEnterLoop // no 0-bytes (ie, 1-bits), so enter by-16 loop
-
-// We've found a 0-byte.
-// %edx = aligned address of 16-byte block containing the terminating 0-byte
-// %ecx = compare bit vector
-
-LFoundIt:
- bsf %ecx,%eax // find first 1-bit (ie, first 0-byte)
- movl 4(%esp),%ecx // recover ptr to 1st byte in string
- addl %edx,%eax // get address of the 0-byte
- subl %ecx,%eax // subtract address of 1st byte to get string length
- ret
-
-// Loop over aligned 16-byte blocks:
-// %edx = address of previous block
-
-LEnterLoop:
- pxor %xmm0,%xmm0 // get some 0-bytes
- addl $16,%edx // advance ptr
-LLoop:
- movdqa (%edx),%xmm1 // get next chunk
- addl $16,%edx
- pcmpeqb %xmm0,%xmm1 // check for 0s
- pmovmskb %xmm1,%ecx // collect mask of 0-bytes
- test %ecx,%ecx // any 0-bytes?
- jz LLoop // no 0-bytes, so get next dq
-
- subl $16,%edx // back up ptr
- jmp LFoundIt
-
-
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-// *****************
-// * S T R N C M P *
-// *****************
-//
-// int strncmp(const char *s1, const char *s2, size_t len);
-//
-// We optimize the compare by doing it vector parallel. This introduces
-// a complication: if we blindly did vector loads from both sides until
-// finding a difference (or 0), we might get a spurious page fault by
-// reading bytes past the difference. To avoid this, we never do a load
-// that crosses a page boundary.
-
-#define kShort 20 // too short for vectors (must be >16)
-
- .text
- .globl _strncmp
-
- .align 4
-_strncmp: // int strncmp(const char *s1, const char *s2, size_t len);
- pushl %esi
- pushl %edi
- movl 20(%esp),%ecx // get length
- movl 12(%esp),%esi // get LHS ptr
- movl 16(%esp),%edi // get RHS ptr
- push %ebx
- cmpl $(kShort),%ecx // worth accelerating?
- ja LNotShort // yes
-
-
-// Too short to bother with parallel compares. Loop over bytes.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %ecx = length (<= kShort)
-
-LShort:
- testl %ecx,%ecx // 0-length?
- jnz LShortLoop // no
- jmp LReturn0 // yes, return 0
- .align 4,0x90 // align inner loops to optimize I-fetch
-LShortLoop: // loop over bytes
- movzb (%esi),%eax // get LHS byte
- movzb (%edi),%ebx // get RHS byte
- incl %esi
- incl %edi
- testl %eax,%eax // LHS==0 ?
- jz LNotEqual // yes, this terminates comparison
- subl %ebx,%eax // compare them
- jnz LExit // done if not equal
- decl %ecx // decrement length
- jnz LShortLoop
-LReturn0:
- xorl %eax,%eax // all bytes equal, so return 0
-LExit: // return value is in %eax
- popl %ebx
- popl %edi
- popl %esi
- ret
-
-LNotEqual: // LHS in eax, RHS in ebx
- subl %ebx,%eax // generate return value (nonzero)
- popl %ebx
- popl %edi
- popl %esi
- ret
-
-
-// Loop over bytes until we reach end of a page.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %ecx = length remaining after end of loop (ie, already adjusted)
-// %edx = #bytes until next page (1..15)
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverBytes:
- movzb (%esi),%eax // get LHS byte
- movzb (%edi),%ebx // get RHS byte
- inc %esi
- inc %edi
- testl %eax,%eax // LHS==0 ?
- jz LNotEqual // yes, this terminates comparison
- subl %ebx,%eax // compare them
- jnz LExit // done if not equal
- dec %edx // more to go?
- jnz LLoopOverBytes
-
-
-// Long enough to justify overhead of setting up vector compares. In order to
-// avoid spurious page faults, we loop over:
-//
-// min( length, bytes_in_LHS_page, bytes_in_RHS_page) >> 4
-//
-// 16-byte chunks. When we near a page end, we have to revert to a byte-by-byte
-// comparison until reaching the next page, then resume the vector comparison.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %ecx = length (> kShort)
-
-LNotShort:
- movl %esi,%eax // copy ptrs
- movl %edi,%edx
- andl $4095,%eax // mask down to page offsets
- andl $4095,%edx
- cmpl %eax,%edx // which is bigger?
- cmova %edx,%eax // %eax = max(LHS offset, RHS offset);
- movl $4096,%edx
- subl %eax,%edx // get #bytes to next page crossing
- cmpl %ecx,%edx // will operand run out first?
- cmova %ecx,%edx // get min(length remaining, bytes to page end)
- movl %edx,%eax
- shrl $4,%edx // get #chunks till end of operand or page
- jnz LLoopOverChunks // enter vector loop
-
-// Too near page end for vectors.
-
- subl %eax,%ecx // adjust length remaining
- movl %eax,%edx // %edx <- #bytes to page end
- cmpl $(kShort),%ecx // will there be enough after we cross page for vectors?
- ja LLoopOverBytes // yes
- addl %eax,%ecx // no, restore total length remaining
- jmp LShortLoop // compare rest byte-by-byte (%ecx != 0)
-
-
-// Loop over 16-byte chunks.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %ecx = length remaining
-// %edx = chunk count
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverChunks:
- movdqu (%esi),%xmm1 // get LHS
- movdqu (%edi),%xmm2 // get RHS
- pxor %xmm0,%xmm0 // get some 0s in the shadow of the loads
- addl $16,%esi
- pcmpeqb %xmm1,%xmm2 // compare LHS to RHS
- pcmpeqb %xmm1,%xmm0 // compare LHS to 0s
- addl $16,%edi
- pmovmskb %xmm2,%eax // get result mask for comparison of LHS and RHS
- pmovmskb %xmm0,%ebx // get result mask for 0 check
- subl $16,%ecx // decrement length remaining
- xorl $0xFFFF,%eax // complement compare mask so 1 means "not equal"
- orl %ebx,%eax // combine the masks and check for 1-bits
- jnz LFoundDiffOr0 // we found differing bytes or a 0-byte
- dec %edx // more to go?
- jnz LLoopOverChunks // yes
-
- cmpl $(kShort),%ecx // a lot more to compare?
- jbe LShort // no
- jmp LNotShort // compute distance to next page crossing etc
-
-
-// Found a zero and/or a difference in vector compare.
-// %esi = LHS ptr, already advanced by 16
-// %edi = RHS ptr, already advanced by 16
-// %eax = bit n set if bytes n differed or were 0
-
-LFoundDiffOr0:
- bsf %eax,%edx // which byte differed or was 0?
- subl $16,%esi // point to start of vectors while we wait for bit scan
- subl $16,%edi
- movzb (%esi,%edx),%eax // get LHS byte
- movzb (%edi,%edx),%ecx // get RHS byte
- popl %ebx
- popl %edi
- subl %ecx,%eax // compute difference (ie, return value)
- popl %esi
- ret
+++ /dev/null
-/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-
-
-// *****************
-// * S T R N C P Y *
-// *****************
-//
-// char *strncpy(const char *dst, const char *src, size_t n);
-//
-// We optimize the move by doing it vector parallel. This introduces
-// a complication: if we blindly did vector load/stores until finding
-// a 0, we might get a spurious page fault by touching bytes past it.
-// To avoid this, we never do a load that crosses a page boundary,
-// and never store a byte we don't have to.
-//
-// We align the destination, because unaligned vector stores are slow.
-//
-// Recall that strncpy() zero fills the remainder of the dest buffer,
-// and does not terminate the string if it's length is greater than or
-// equal to n.
-
-#define kShort 31 // too short to bother with vector loop
-
- .text
- .globl _strncpy
-
- .align 4
-_strncpy: // char *strncpy(const char *dst, const char *src, size_t n);
- pushl %edi
- pushl %esi
- movl 12(%esp),%edi // get dest ptr
- movl 16(%esp),%esi // get source ptr
- movl 20(%esp),%ecx // get length
- movl %edi,%edx // copy dest ptr
- negl %edx
- andl $15,%edx // how many bytes to align dest ptr?
- jnz LCheckShortCopy // align destination first
-
-
-// In order to avoid spurious page faults, we loop until nearing the source page
-// end. Then we revert to a byte-by-byte loop for 16 bytes until the page is crossed,
-// then resume the vector loop.
-// %esi = source ptr (unaligned)
-// %edi = dest ptr (aligned)
-// %ecx = buffer length remaining
-
-LNextChunk: // NB: can drop down to here
- movl %esi,%eax // copy source ptr
- movl $4096,%edx
- andl $4095,%eax // get offset into source page
- subl %eax,%edx // get #bytes remaining in source page
- cmpl %ecx,%edx // will buffer run out before the page end?
- cmova %ecx,%edx // get min(length remaining, bytes to page end)
- shrl $4,%edx // get #chunks till end of page
- jnz LLoopOverChunks // enter vector loop
-
-// We can't use the chunk loop yet. Check for short and empty buffers, then use byte loop.
-
-LCrossPage: // if buffer is large enough, cross source page
- movl $16,%edx // move 16 bytes to cross page but keep dest aligned
-LCheckShortCopy: // we propose to copy %edx bytes in byte loop
- cmpl $(kShort),%ecx // much left?
- ja LLoopOverBytes // yes, loop over bytes then more chunks
- movl %ecx,%edx // no, use the byte loop for everything
- testl %ecx,%ecx // have we filled buffer?
- jnz LLoopOverBytes // no
- jmp LDone
-
-
-// Loop over bytes.
-// %esi = source ptr
-// %edi = dest ptr
-// %ecx = buffer length remaining
-// %edx = count of bytes to loop over (<= buffer length)
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverBytes:
- movzb (%esi),%eax // get source byte
- inc %esi
- dec %ecx // decrement length
- movb %al,(%edi) // pack into dest
- inc %edi
- testl %eax,%eax // 0?
- jz LZeroBuffer // yes, we're done copying string
- dec %edx // more to go?
- jnz LLoopOverBytes
-
- testl %ecx,%ecx // at end of buffer?
- jnz LNextChunk // no, xfer chunks
- jmp LDone // yes
-
-
-// Loop over 16-byte chunks.
-// %esi = source ptr (unaligned)
-// %edi = dest ptr (aligned)
-// %ecx = buffer length remaining
-// %edx = chunk count
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverChunks:
- movdqu (%esi),%xmm1 // get source
- pxor %xmm0,%xmm0 // get some 0s
- addl $16,%esi
- pcmpeqb %xmm1,%xmm0 // compare source to 0s
- pmovmskb %xmm0,%eax // get result mask for 0 check
- testl %eax,%eax // any 0s?
- jnz LFound0 // yes, exit loop
- movdqa %xmm1,(%edi) // no 0s so do aligned store into destination
- addl $16,%edi
- subl $16,%ecx // decrement length remaining
- dec %edx // more to go?
- jnz LLoopOverChunks
-
- jmp LCrossPage // cross page but keep dest aligned
-
-
-// Found a zero in the vector. Figure out where it is, and store the bytes
-// up to it. It is possible that we should check to be sure (%ecx >= 16), and
-// just do an aligned store of %xmm1 if so. But if we did, we'd be doing byte
-// stores into the same double quadword in bzero(), which might hit a hazard.
-// Experimentation needed.
-// %edi = dest ptr (aligned)
-// %eax = result mask
-// %ecx = buffer length remaining
-// %xmm1 = source vector
-
-LFound0:
- bsf %eax,%edx // find first 0
- subl %edx,%ecx // decrement remaining buffer length
- test $8,%dl // 8-byte store required?
- jz 4f // no
- movq %xmm1,(%edi) // pack in 8 low bytes
- psrldq $8,%xmm1 // then shift vector down 8 bytes
- addl $8,%edi
-4:
- test $4,%dl // 4-byte store required?
- jz 3f // no
- movd %xmm1,(%edi) // pack in 4 low bytes
- psrldq $4,%xmm1 // then shift vector down 4 bytes
- addl $4,%edi
-3:
- andl $3,%edx // more to go?
- jz LZeroBuffer // no
- movd %xmm1,%eax // move remainders out of vector into %eax
-1: // loop on up to three bytes
- movb %al,(%edi) // pack in next byte
- shrl $8,%eax // shift next byte into position
- inc %edi
- dec %edx
- jnz 1b
-
-// We've copied the string. Now zero the rest of the buffer, using commpage bzero().
-// %edi = dest ptr
-// %ecx = buffer length remaining
-
-LZeroBuffer:
- pushl %ecx // remaining buffer size
- pushl %edi // ptr to 1st unstored byte
- movl $(_COMM_PAGE_BZERO),%eax
- call %eax
- addl $8,%esp // pop off the arguments
-
-LDone:
- movl 12(%esp),%eax // original dest ptr is return value
- popl %esi
- popl %edi
- ret
__pthread_canceled.s \
__pthread_markcancel.s \
__semwait_signal.s \
- __sysenter_trap.s \
_setjmp.s \
_setlogin.s \
_sysctl.s \
chflags.s \
chmod.s \
chown.s \
- commpage.c \
chroot.s \
close.s \
connect.s \
getsockopt.s \
getuid.s \
getxattr.s \
- i386_gettimeofday.s \
- i386_get_ldt.s \
- i386_set_ldt.s \
ioctl.s \
issetugid.s \
kevent.s \
DECLARE(_OSAtomicTestAndSet)
movl 4(%esp), %eax
movl 8(%esp), %edx
- movl %eax, %ecx
- andl $-8, %ecx
- notl %eax
- andl $7, %eax
- orl %ecx, %eax
call *_COMM_PAGE_BTS
setc %al
ret
DECLARE(_OSAtomicTestAndClear)
movl 4(%esp), %eax
movl 8(%esp), %edx
- movl %eax, %ecx
- andl $-8, %ecx
- notl %eax
- andl $7, %eax
- orl %ecx, %eax
call *_COMM_PAGE_BTC
setc %al
ret
/*
- * Copyright (c) 1999-2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <architecture/i386/asm_help.h>
#include <mach/i386/syscall_sw.h>
-/*
- * We have two entry points. int's is used for syscalls which need to preserve
- * %ecx across the call, or return a 64-bit value in %eax:%edx. sysenter is used
- * for the majority of syscalls which just return a value in %eax.
- */
-#define UNIX_SYSCALL_SYSENTER SYSENTER_PAD call __sysenter_trap
+#define UNIX_SYSCALL_TRAP lcall $0x2b, $0
+#define MACHDEP_SYSCALL_TRAP lcall $0x7, $0
+
/*
* This is the same as UNIX_SYSCALL, but it can call an alternate error
.globl error_ret ;\
LEAF(_##name, 0) ;\
movl $ SYS_##name, %eax ;\
- UNIX_SYSCALL_SYSENTER ;\
+ UNIX_SYSCALL_TRAP ;\
jnb 2f ;\
BRANCH_EXTERN(error_ret) ;\
2:
#define UNIX_SYSCALL(name, nargs) \
.globl cerror ;\
-LEAF(_##name, 0) ;\
- movl $ SYS_##name, %eax ;\
- UNIX_SYSCALL_SYSENTER ;\
- jnb 2f ;\
- BRANCH_EXTERN(cerror) ;\
-2:
-
-#define UNIX_SYSCALL_INT(name, nargs) \
- .globl cerror ;\
LEAF(_##name, 0) ;\
movl $ SYS_##name, %eax ;\
UNIX_SYSCALL_TRAP ;\
2:
#define UNIX_SYSCALL_NONAME(name, nargs) \
- .globl cerror ;\
- movl $ SYS_##name, %eax ;\
- UNIX_SYSCALL_SYSENTER ;\
- jnb 2f ;\
- BRANCH_EXTERN(cerror) ;\
-2:
-
-#define UNIX_SYSCALL_INT_NONAME(name, nargs) \
.globl cerror ;\
movl $ SYS_##name, %eax ;\
UNIX_SYSCALL_TRAP ;\
+++ /dev/null
-/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-.text
-.align 2,0x90
-.private_extern __sysenter_trap
-__sysenter_trap:
- popl %edx
- movl %esp, %ecx
- sysenter
#define JB_FS 64
#define JB_GS 68
-#define SAVE_SEG_REGS 1
LEAF(__setjmp, 0)
movl 4(%esp), %ecx // jmp_buf (struct sigcontext *)
#if SAVE_SEG_REGS
// segment registers
mov JB_SS(%ecx), %ss
- // mov JB_CS(%ecx), %cs // can't set cs?
+ mov JB_CS(%ecx), %cs
mov JB_DS(%ecx), %ds
mov JB_ES(%ecx), %es
mov JB_FS(%ecx), %fs
movl $45, %eax /* Yes; make ENOTSUP for compatibility */
LABEL(cerror)
REG_TO_EXTERN(%eax, _errno)
- mov %esp,%edx
- andl $0xfffffff0,%esp
- subl $16,%esp
- movl %edx,4(%esp)
- movl %eax,(%esp)
+ pushl %eax
CALL_EXTERN(_cthread_set_errno_self)
- movl 4(%esp),%esp
+ addl $4,%esp
movl $-1,%eax
movl $-1,%edx /* in case a 64-bit value is returned */
ret
+++ /dev/null
-/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
*/
#include "SYS.h"
-LEAF(_fork, 0)
- subl $28, %esp // Align the stack, with 16 bytes of extra padding that we'll need
+LEAF(_fork, 0)
CALL_EXTERN(__cthread_fork_prepare)
#if defined(__DYNAMIC__)
// Just like __cthread_fork_prepare we need to prevent threads on the child's
LC1:
.ascii "__dyld_fork_prepare\0"
.text
- // Put a pointer to 8(%esp) in 4(%esp) for _dyld_func_lookup to fill in.
- leal 0x8(%esp),%eax // get the address where we're going to store the pointer
- movl %eax, 0x4(%esp) // copy the address of the pointer
+ subl $4,%esp // allocate space for the address parameter
+ leal 0(%esp),%eax // get the address of the allocated space
+ pushl %eax // push the address of the allocated space
call 1f
1: popl %eax
leal LC1-1b(%eax),%eax
- movl %eax, 0x0(%esp) // copy the name of the function to look up
+ pushl %eax // push the name of the function to look up
call __dyld_func_lookup
- movl 0x8(%esp),%eax // move the value returned in address parameter
+ addl $8,%esp // remove parameters to __dyld_func_lookup
+ movl 0(%esp),%eax // move the value returned in address parameter
+ addl $4,%esp // deallocate the space for the address param
call *%eax // call __dyld_fork_prepare indirectly
#endif
movl $ SYS_fork,%eax; // code for fork -> eax
- UNIX_SYSCALL_TRAP // do the system call
+ UNIX_SYSCALL_TRAP; // do the system call
jnc L1 // jump if CF==0
#if defined(__DYNAMIC__)
LC2:
.ascii "__dyld_fork_parent\0"
.text
- movl %eax, 0xc(%esp) // save the return value (errno)
- leal 0x8(%esp),%eax // get the address where we're going to store the pointer
- movl %eax, 0x4(%esp) // copy the address of the pointer
+ pushl %eax // save the return value (errno)
+ subl $4,%esp // allocate space for the address parameter
+ leal 0(%esp),%eax // get the address of the allocated space
+ pushl %eax // push the address of the allocated space
call 1f
1: popl %eax
leal LC2-1b(%eax),%eax
- movl %eax, 0x0(%esp) // copy the name of the function to look up
+ pushl %eax // push the name of the function to look up
call __dyld_func_lookup
- movl 0x8(%esp),%eax // move the value returned in address parameter
+ addl $8,%esp // remove parameters to __dyld_func_lookup
+ movl 0(%esp),%eax // move the value returned in address parameter
+ addl $4,%esp // deallocate the space for the address param
call *%eax // call __dyld_fork_parent indirectly
- movl 0xc(%esp), %eax // restore the return value (errno)
+ popl %eax // restore the return value (errno)
#endif
CALL_EXTERN(cerror)
CALL_EXTERN(__cthread_fork_parent)
movl $-1,%eax
- addl $28, %esp // restore the stack
ret
L1:
#if defined(__DYNAMIC__)
// Here on the child side of the fork we need to tell the dynamic linker that
// we have forked. To do this we call __dyld_fork_child in the dyanmic
-// linker. But since we can't dynamically bind anything until this is done we
+// linker. But since we can't dynamicly bind anything until this is done we
// do this by using the private extern __dyld_func_lookup() function to get the
// address of __dyld_fork_child (the 'C' code equivlent):
//
.ascii "__dyld_fork_child\0"
.text
- leal 0x8(%esp),%eax // get the address where we're going to store the pointer
- movl %eax, 0x4(%esp) // copy the address of the pointer
+ subl $4,%esp // allocate space for the address parameter
+ leal 0(%esp),%eax // get the address of the allocated space
+ pushl %eax // push the address of the allocated space
call 1f
1: popl %eax
leal LC0-1b(%eax),%eax
- movl %eax, 0x0(%esp) // copy the name of the function to look up
+ pushl %eax // push the name of the function to look up
call __dyld_func_lookup
- movl 0x8(%esp),%eax // move the value returned in address parameter
+ addl $8,%esp // remove parameters to __dyld_func_lookup
+ movl 0(%esp),%eax // move the value returned in address parameter
+ addl $4,%esp // deallocate the space for the address param
call *%eax // call __dyld_fork_child indirectly
#endif
xorl %eax, %eax
.ascii "__dyld_fork_child_final\0"
.text
- leal 0x8(%esp),%eax // get the address where we're going to store the pointer
- movl %eax, 0x4(%esp) // copy the address of the pointer
+ subl $4,%esp // allocate space for the address parameter
+ leal 0(%esp),%eax // get the address of the allocated space
+ pushl %eax // push the address of the allocated space
call 1f
1: popl %eax
leal LC10-1b(%eax),%eax
- movl %eax, 0x0(%esp) // copy the name of the function to look up
+ pushl %eax // push the name of the function to look up
call __dyld_func_lookup
- movl 0x8(%esp),%eax // move the value returned in address parameter
+ addl $8,%esp // remove parameters to __dyld_func_lookup
+ movl 0(%esp),%eax // move the value returned in address parameter
+ addl $4,%esp // deallocate the space for the address param
call *%eax // call __dyld_fork_child_final indirectly
#endif
xorl %eax,%eax // zero eax
- addl $28, %esp // restore the stack
ret
//parent here...
L2:
- movl %eax, 0xc(%esp) // save pid
+ push %eax // save pid
#if defined(__DYNAMIC__)
// __dyld_fork_parent() is called by the parent process after a fork syscall.
// This releases the dyld lock acquired by __dyld_fork_prepare().
- leal 0x8(%esp),%eax // get the address where we're going to store the pointer
- movl %eax, 0x4(%esp) // copy the address of the allocated space
+ subl $4,%esp // allocate space for the address parameter
+ leal 0(%esp),%eax // get the address of the allocated space
+ pushl %eax // push the address of the allocated space
call 1f
1: popl %eax
leal LC2-1b(%eax),%eax
- movl %eax, 0x0(%esp) // copy the name of the function to look up
+ pushl %eax // push the name of the function to look up
call __dyld_func_lookup
- movl 0x8(%esp),%eax // move the value returned in address parameter
+ addl $8,%esp // remove parameters to __dyld_func_lookup
+ movl 0(%esp),%eax // move the value returned in address parameter
+ addl $4,%esp // deallocate the space for the address param
call *%eax // call __dyld_fork_parent indirectly
#endif
CALL_EXTERN_AGAIN(__cthread_fork_parent)
- movl 0xc(%esp), %eax // return pid
- addl $28, %esp // restore the stack
+ pop %eax
ret
UNIX_SYSCALL_NONAME(getpid, 0)
movl %eax, %edx
xorl %eax, %eax
- GET_CURRENT_PID
lock
cmpxchgl %edx, __current_pid
movl %edx, %eax
+++ /dev/null
-/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <sys/syscall.h>
-#include <architecture/i386/asm_help.h>
-#include <mach/i386/syscall_sw.h>
-
-.text
-.globl cerror
-LEAF(_i386_get_ldt, 0)
- movl $6,%eax
- MACHDEP_SYSCALL_TRAP
- jnb 2f
- BRANCH_EXTERN(cerror)
-2: ret
+++ /dev/null
-/*
- * Copyright (c) 1999-2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/* Copyright 1998 Apple Computer, Inc. */
-
-#include "SYS.h"
-
-#define __APPLE_API_PRIVATE
-#include <machine/cpu_capabilities.h>
-#undef __APPLE_API_PRIVATE
-
-LABEL(___commpage_gettimeofday)
- mov $ _COMM_PAGE_GETTIMEOFDAY,%eax
- jmp %eax
-
-/*
- * This syscall is special cased: the timeval is returned in eax/edx.
- */
-LABEL(___gettimeofday)
- UNIX_SYSCALL_INT_NONAME(gettimeofday,0)
- mov 4(%esp),%ecx
- mov %eax,(%ecx)
- mov %edx,4(%ecx)
- xor %eax,%eax
- ret
+++ /dev/null
-/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <sys/syscall.h>
-#include <architecture/i386/asm_help.h>
-#include <mach/i386/syscall_sw.h>
-
-.text
-.globl cerror
-LEAF(_i386_set_ldt, 0)
- movl $5,%eax
- MACHDEP_SYSCALL_TRAP
- jnb 2f
- BRANCH_EXTERN(cerror)
-2: ret
*/
#include "SYS.h"
-UNIX_SYSCALL_INT(lseek, 3)
+UNIX_SYSCALL(lseek, 3)
ret
*/
#include "SYS.h"
-UNIX_SYSCALL_INT(pipe, 0)
+UNIX_SYSCALL(pipe, 0)
movl 4(%esp),%ecx
movl %eax,(%ecx)
movl %edx,4(%ecx)
movl %ecx, JB_SAVEMASK(%eax) // jmpbuf[_JBLEN] = savemask;
cmpl $0, %ecx // if savemask != 0
jne _setjmp // setjmp(jmpbuf);
- jmp L_do__setjmp // else _setjmp(jmpbuf);
+ BRANCH_EXTERN(__setjmp) // else
+ // _setjmp(jmpbuf);
LEAF(_setjmp, 0)
- subl $4, %esp // make space for return from sigprocmask
- pushl %esp // oset
- pushl $0 // set = NULL
- pushl $1 // how = SIG_BLOCK
- CALL_EXTERN(_sigprocmask)
- movl 12(%esp),%eax // save the mask
- addl $16, %esp // restore original esp
movl 4(%esp), %ecx // jmp_buf (struct sigcontext *)
+ pushl %ecx // save ecx
+
+ // call sigstack to get the current signal stack
+ subl $12, %esp // space for return structure
+ pushl %esp
+ pushl $0
+ CALL_EXTERN(_sigaltstack)
+ movl 12(%esp), %eax // save stack pointer
+ movl %eax, JB_ONSTACK(%ecx)
+ addl $20, %esp
+
+ // call sigblock to get signal mask
+ pushl $0
+ CALL_EXTERN(_sigblock)
+ addl $4, %esp
+ popl %ecx // restore ecx
movl %eax, JB_MASK(%ecx)
-L_do__setjmp:
- BRANCH_EXTERN(__setjmp)
+
+ // now build sigcontext
+ movl %ebx, JB_EBX(%ecx)
+ movl %edi, JB_EDI(%ecx)
+ movl %esi, JB_ESI(%ecx)
+ movl %ebp, JB_EBP(%ecx)
+
+ // EIP is set to the frame return address value
+ movl (%esp), %eax
+ movl %eax, JB_EIP(%ecx)
+ // ESP is set to the frame return address plus 4
+ movl %esp, %eax
+ addl $4, %eax
+ movl %eax, JB_ESP(%ecx)
+
+ // segment registers
+ movl $0, JB_SS(%ecx)
+ mov %ss, JB_SS(%ecx)
+ movl $0, JB_CS(%ecx)
+ mov %cs, JB_CS(%ecx)
+ movl $0, JB_DS(%ecx)
+ mov %ds, JB_DS(%ecx)
+ movl $0, JB_ES(%ecx)
+ mov %es, JB_ES(%ecx)
+ movl $0, JB_FS(%ecx)
+ mov %fs, JB_FS(%ecx)
+ movl $0, JB_GS(%ecx)
+ mov %gs, JB_GS(%ecx)
+
+ // save eflags - you can't use movl
+ pushf
+ popl %eax
+ movl %eax, JB_EFLAGS(%ecx)
+
+ // return 0
+ xorl %eax, %eax
+ ret
LEAF(_siglongjmp, 0)
movl 4(%esp), %eax // sigjmp_buf * jmpbuf;
cmpl $0, JB_SAVEMASK(%eax) // if jmpbuf[_JBLEN] != 0
jne _longjmp // longjmp(jmpbuf, var);
- jmp L_do__longjmp // else _longjmp(jmpbuf, var);
+ BRANCH_EXTERN(__longjmp) // else
+ // _longjmp(jmpbuf, var);
LEAF(_longjmp, 0)
- movl 4(%esp), %ecx // address of jmp_buf (saved context)
- movl JB_MASK(%ecx),%eax // get the mask
- pushl %eax // store the mask
- movl %esp, %edx // save the address where we stored the mask
- pushl $0 // oset = NULL
- pushl %edx // set
- pushl $3 // how = SIG_SETMASK
- CALL_EXTERN_AGAIN(_sigprocmask)
- addl $16, %esp // restore original esp
-L_do__longjmp:
- BRANCH_EXTERN(__longjmp) // else
+ subl $2,%esp
+ fnstcw (%esp) // save FP control word
+ fninit // reset FP coprocessor
+ fldcw (%esp) // restore FP control word
+ addl $2,%esp
+ movl 4(%esp), %eax // address of jmp_buf (saved context)
+ movl 8(%esp), %edx // return value
+ movl %edx, JB_EAX(%eax) // return value into saved context
+ movl $ SYS_sigreturn, %eax // sigreturn system call
+ UNIX_SYSCALL_TRAP
+ addl $8, %esp
+ CALL_EXTERN(_longjmperror)
+ CALL_EXTERN(_abort)
END(_longjmp)
*/
#include "SYS.h"
-UNIX_SYSCALL_INT(sigaltstack, 3)
+UNIX_SYSCALL(sigaltstack, 3)
ret
*/
#include "SYS.h"
-UNIX_SYSCALL_INT(sigreturn, 2)
+UNIX_SYSCALL(sigreturn, 1)
ret
/* 23.1.6.4 ACL Format translation */
extern ssize_t acl_copy_ext(void *buf_p, acl_t acl, ssize_t size);
-extern ssize_t acl_copy_ext_native(void *buf_p, acl_t acl, ssize_t size);
extern acl_t acl_copy_int(const void *buf_p);
-extern acl_t acl_copy_int_native(const void *buf_p);
extern acl_t acl_from_text(const char *buf_p);
extern ssize_t acl_size(acl_t acl);
extern char *acl_to_text(acl_t acl, ssize_t *len_p);
__END_DECLS
-#endif /* _SYS_ACL_H */
+#endif _SYS_ACL_H
#define RB_DEBUGGER 0x1000 /* enter debugger NOW */
(void) host_reboot(master_host_port, RB_DEBUGGER);
-
- /* 4279008 - don't return */
- abort();
}
#include <pwd.h>
#include <grp.h>
-#include <libkern/OSByteOrder.h>
-
#include "aclvar.h"
-/*
- * NOTE: the copy_int/copy_ext functions are duplicated here, one version of each for
- * each of native and portable endianity. A more elegant solution might be called for
- * if the functions become much more complicated.
- */
-
-/*
- * acl_t -> external representation, portable endianity
- */
ssize_t
acl_copy_ext(void *buf, acl_t acl, ssize_t size)
{
return(-1);
}
- /* export the header */
- ext->fsec_magic = OSSwapHostToBigInt32(KAUTH_FILESEC_MAGIC);
- ext->fsec_entrycount = OSSwapHostToBigInt32(acl->a_entries);
- ext->fsec_flags = OSSwapHostToBigInt32(acl->a_flags);
-
- /* copy ACEs */
- for (i = 0; i < acl->a_entries; i++) {
- /* ACE contents are almost identical */
- ext->fsec_ace[i].ace_applicable = acl->a_ace[i].ae_applicable;
- ext->fsec_ace[i].ace_flags =
- OSSwapHostToBigInt32((acl->a_ace[i].ae_tag & KAUTH_ACE_KINDMASK) | (acl->a_ace[i].ae_flags & ~KAUTH_ACE_KINDMASK));
- ext->fsec_ace[i].ace_rights = OSSwapHostToBigInt32(acl->a_ace[i].ae_perms);
- }
-
- return(reqsize);
-}
-
-/*
- * acl_t -> external representation, native system endianity
- */
-ssize_t
-acl_copy_ext_native(void *buf, acl_t acl, ssize_t size)
-{
- struct kauth_filesec *ext = (struct kauth_filesec *)buf;
- ssize_t reqsize;
- int i;
-
- /* validate arguments, compute required size */
- reqsize = acl_size(acl);
- if (reqsize < 0)
- return(-1);
- if (reqsize > size) {
- errno = ERANGE;
- return(-1);
- }
-
/* export the header */
ext->fsec_magic = KAUTH_FILESEC_MAGIC;
ext->fsec_entrycount = acl->a_entries;
return(reqsize);
}
-/*
- * external representation, portable system endianity -> acl_t
- *
- * Unlike acl_copy_ext, we can't mung the buffer as it doesn't belong to us.
- */
acl_t
acl_copy_int(const void *buf)
{
acl_t ap;
int i;
- if (ext->fsec_magic != OSSwapHostToBigInt32(KAUTH_FILESEC_MAGIC)) {
- errno = EINVAL;
- return(NULL);
- }
-
- if ((ap = acl_init(OSSwapBigToHostInt32(ext->fsec_entrycount))) != NULL) {
- /* copy useful header fields */
- ap->a_flags = OSSwapBigToHostInt32(ext->fsec_flags);
- ap->a_entries = OSSwapBigToHostInt32(ext->fsec_entrycount);
- /* copy ACEs */
- for (i = 0; i < ap->a_entries; i++) {
- /* ACE contents are literally identical */
- ap->a_ace[i].ae_magic = _ACL_ENTRY_MAGIC;
- ap->a_ace[i].ae_applicable = ext->fsec_ace[i].ace_applicable;
- ap->a_ace[i].ae_flags = OSSwapBigToHostInt32(ext->fsec_ace[i].ace_flags) & ~KAUTH_ACE_KINDMASK;
- ap->a_ace[i].ae_tag = OSSwapBigToHostInt32(ext->fsec_ace[i].ace_flags) & KAUTH_ACE_KINDMASK;
- ap->a_ace[i].ae_perms = OSSwapBigToHostInt32(ext->fsec_ace[i].ace_rights);
- }
- }
- return(ap);
-}
-
-/*
- * external representation, native system endianity -> acl_t
- */
-acl_t
-acl_copy_int_native(const void *buf)
-{
- struct kauth_filesec *ext = (struct kauth_filesec *)buf;
- acl_t ap;
- int i;
-
if (ext->fsec_magic != KAUTH_FILESEC_MAGIC) {
errno = EINVAL;
return(NULL);
/* copy ACEs */
for (i = 0; i < ap->a_entries; i++) {
/* ACE contents are literally identical */
+/* XXX Consider writing the magic out to the persistent store
+ * to detect corruption
+ */
ap->a_ace[i].ae_magic = _ACL_ENTRY_MAGIC;
ap->a_ace[i].ae_applicable = ext->fsec_ace[i].ace_applicable;
ap->a_ace[i].ae_flags = ext->fsec_ace[i].ace_flags & ~KAUTH_ACE_KINDMASK;
/*
- * Copyright (c) 1999-2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* Note also that the "seconds" field of the timeval is a long, so
* it's size is mode dependent.
*/
-MI_ENTRY_POINT(___gettimeofday)
+MI_ENTRY_POINT(___ppc_gettimeofday)
mr r12,r3 // save ptr to timeval
SYSCALL_NONAME(gettimeofday,0)
+ mr. r12,r12 // was timeval ptr null?
+ beq 3f
stg r3,0(r12) // "stw" in 32-bit mode, "std" in 64-bit mode
stw r4,GPR_BYTES(r12)
li r3,0
+3:
blr
TEXT
ALIGN
+.globl _spin_lock_try
LEAF(__spin_lock_try, 0)
+_spin_lock_try:
movl $(_COMM_PAGE_SPINLOCK_TRY), %eax
jmpl %eax
void (*destructor)(void *);
} _pthread_keys[_POSIX_THREAD_KEYS_MAX];
static pthread_lock_t tds_lock = LOCK_INITIALIZER;
-/*
- * Partition _pthread_keys in a lower part that dyld can use, and an upper
- * part for libSystem. The libSystem part starts at __pthread_tsd_first = 4.
- * dyld will set this value to 1.
- */
-__private_extern__ int __pthread_tsd_first = 4;
/*
* Create a new key for thread specific data
LOCK(tds_lock);
res = ENOMEM; /* No 'free' keys */
/* The first slot is reserved for pthread_self() */
- for (i = __pthread_tsd_first; i < _POSIX_THREAD_KEYS_MAX; i++)
+ for (i = 1; i < _POSIX_THREAD_KEYS_MAX; i++)
{
if (_pthread_keys[i].created == FALSE)
{
int res;
LOCK(tds_lock);
/* The first slot is reserved for pthread_self() */
- if ((key >= __pthread_tsd_first) && (key < _POSIX_THREAD_KEYS_MAX))
+ if ((key > 0) && (key < _POSIX_THREAD_KEYS_MAX))
{
if (_pthread_keys[key].created)
{
int res;
pthread_t self;
/* The first slot is reserved for pthread_self() */
- if ((key >= __pthread_tsd_first) && (key < _POSIX_THREAD_KEYS_MAX))
+ if ((key > 0) && (key < _POSIX_THREAD_KEYS_MAX))
{
if (_pthread_keys[key].created)
{
for (j = 0; j < PTHREAD_DESTRUCTOR_ITERATIONS; j++)
{
/* The first slot is reserved for pthread_self() */
- for (i = __pthread_tsd_first; i < _POSIX_THREAD_KEYS_MAX; i++)
+ for (i = 1; i < _POSIX_THREAD_KEYS_MAX; i++)
{
if (_pthread_keys[i].created && (param = self->tsd[i]))
{
---- printf.3.orig 2004-11-25 11:38:35.000000000 -0800
-+++ printf.3 2005-08-09 22:37:08.000000000 -0700
+--- printf.3.orig Fri Mar 11 17:08:43 2005
++++ printf.3 Fri Mar 11 17:04:50 2005
@@ -101,6 +101,12 @@
dynamically allocate a new string with
.Xr malloc 3 .
.It
+An optional separator character (
+.Cm \ , | \; | \ : | _
-+) used for separating multiple values when printing an AltiVec or SSE vector,
++) used for separating multiple values when printing an AltiVec vector,
+or other multi-value unit.
+.Pp
-+NOTE: This is an extension to the
++NOTE: This is an AltiVec only extension onto the
+.Fn printf
+specification.
+Behaviour of these values for
An optional decimal digit string specifying a minimum field width.
If the converted value has fewer characters than the field width, it will
be padded with spaces on the left (or right, if the left-adjustment
-@@ -379,6 +399,34 @@
+@@ -379,6 +399,28 @@
.It Sy Modifier Ta Cm c Ta Cm s
.It Cm l No (ell) Ta Vt wint_t Ta Vt "wchar_t *"
.El
+.Pp
+The AltiVec Technology Programming Interface Manual also defines five additional length modifiers
-+which can be used (in place of the conventional length modifiers) for the printing of AltiVec or SSE vectors:
++which can be used (in place of the conventional length modifiers) for the printing of AltiVec vectors:
+.Bl -tag -compact
+.It Cm v
+Treat the argument as a vector value, unit length will be determined by the conversion
+Treat the argument as a vector of 4 32-bit units.
+.El
+.Pp
-+NOTE: The vector length specifiers are extensions to the
++NOTE: The vector length specifiers are AltiVec only extensions onto the
+.Fn printf
+specification.
+Behaviour of these values for
+is only defined for operating systems conforming to the
+AltiVec Technology Programming Interface Manual.
+(At time of writing this includes only Mac OS X 10.2 and later.)
-+.Pp
-+As a further extension, for SSE2 64-bit units:
-+.Bl -tag -compact
-+.It Cm vll, llv
-+Treat the argument as a vector of 2 64-bit units.
-+.El
.It
A character that specifies the type of conversion to be applied.
.El
-@@ -792,12 +840,8 @@
+@@ -792,12 +834,8 @@
.Xr fmtcheck 3 ,
.Xr scanf 3 ,
.Xr setlocale 3 ,
--- vfprintf.c.orig 2004-11-25 11:38:35.000000000 -0800
-+++ vfprintf.c 2005-11-08 22:43:11.000000000 -0800
++++ vfprintf.c 2005-02-24 15:16:20.000000000 -0800
@@ -40,6 +40,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.68 2004/08/26 06:25:28 des Exp $");
#include <stdarg.h>
#include "un-namespace.h"
-@@ -66,6 +69,13 @@
+@@ -66,6 +69,12 @@
#include "local.h"
#include "fvwrite.h"
-+#ifdef VECTORS
-+typedef __attribute__ ((vector_size(16))) unsigned char VECTORTYPE;
-+#ifdef __SSE2__
-+#define V64TYPE
-+#endif /* __SSE2__ */
-+#endif /* VECTORS */
++#ifdef ALTIVEC
++#include <machine/cpu_capabilities.h>
++
++#define VECTORTYPE vector unsigned char
++#endif /* ALTIVEC */
+
union arg {
int intarg;
u_int uintarg;
-@@ -93,6 +103,21 @@
+@@ -93,6 +102,16 @@
#endif
wint_t wintarg;
wchar_t *pwchararg;
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ VECTORTYPE vectorarg;
+ unsigned char vuchararg[16];
+ signed char vchararg[16];
+ unsigned int vuintarg[4];
+ signed int vintarg[4];
+ float vfloatarg[4];
-+#ifdef V64TYPE
-+ double vdoublearg[2];
-+ unsigned long long vulonglongarg[2];
-+ long long vlonglongarg[2];
-+#endif /* V64TYPE */
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
};
/*
-@@ -103,16 +128,20 @@
+@@ -103,19 +122,56 @@
T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG,
T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET,
T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR,
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR, T_VECTOR
-+#else /* ! VECTORS */
++#else /* ! ALTIVEC */
T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
};
static int __sprint(FILE *, struct __suio *);
static void __find_arguments(const char *, va_list, union arg **);
static void __grow_type_table(int, enum typeid **, int *);
-@@ -141,7 +170,7 @@
++ /*
++ * Get the argument indexed by nextarg. If the argument table is
++ * built, use it to get the argument. If its not, get the next
++ * argument (and arguments must be gotten sequentially).
++ */
++#define GETARG(type) \
++ ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
++ (nextarg++, va_arg(ap, type)))
++
++#ifdef ALTIVEC
++#define hasAltivec (_cpu_capabilities & kHasAltivec)
++/*-----------------------------------------------------------------------
++ * getvec() must be a real subroutine. If it is a #define, then __vfprintf()
++ * would have its calling sequence changed by Altivec so that a non-Altivec
++ * processor would crash on illegal instruction. By isolating the calling
++ * sequence in getvec(), __vprintf() is callable by a non-Altivec processor.
++ *-----------------------------------------------------------------------*/
++static va_list getvec(union arg *, const union arg *, int, va_list) __attribute__((noinline));
++
++static va_list
++getvec(union arg *dst, const union arg *argtable, int nextarg, va_list ap)
++{
++ dst->vectorarg = GETARG(VECTORTYPE);
++ return ap;
++}
++
++#define SETVEC(dst) \
++{ \
++ ap = getvec(&dst, argtable, nextarg, ap); \
++ nextarg++; \
++}
++#endif /* ALTIVEC */
++
+ /*
+ * Flush out all the vectors defined by the given uio,
+ * then reset it so that it can be reused.
+@@ -141,7 +197,7 @@
* worries about ungetc buffers and so forth.
*/
static int
{
int ret;
FILE fake;
-@@ -160,7 +189,7 @@
+@@ -160,7 +216,7 @@
fake._lbfsize = 0; /* not actually used, but Just In Case */
/* do the work, then copy any error status */
if (ret >= 0 && __fflush(&fake))
ret = EOF;
if (fake._flags & __SERR)
-@@ -336,7 +365,7 @@
+@@ -336,7 +392,7 @@
* that the wide char. string ends in a null character.
*/
static char *
{
static const mbstate_t initial;
mbstate_t mbs;
-@@ -354,7 +383,7 @@
+@@ -354,7 +410,7 @@
p = wcsarg;
mbs = initial;
for (;;) {
if (clen == 0 || clen == (size_t)-1 ||
nbytes + clen > prec)
break;
-@@ -363,7 +392,7 @@
+@@ -363,7 +419,7 @@
} else {
p = wcsarg;
mbs = initial;
if (nbytes == (size_t)-1)
return (NULL);
}
-@@ -378,7 +407,7 @@
+@@ -378,7 +434,7 @@
p = wcsarg;
mbs = initial;
while (mbp - convbuf < nbytes) {
if (clen == 0 || clen == (size_t)-1)
break;
mbp += clen;
-@@ -402,7 +431,21 @@
+@@ -402,7 +458,21 @@
int ret;
FLOCKFILE(fp);
FUNLOCKFILE(fp);
return (ret);
}
-@@ -451,12 +494,15 @@
+@@ -451,12 +521,15 @@
#define PTRDIFFT 0x800 /* ptrdiff_t */
#define INTMAXT 0x1000 /* intmax_t */
#define CHARINT 0x2000 /* print char using int format */
-+#ifdef VECTORS
-+#define VECTOR 0x4000 /* Altivec or SSE vector */
-+#endif /* VECTORS */
++#ifdef ALTIVEC
++#define VECTOR 0x4000 /* Altivec vector */
++#endif /* ALTIVEC */
/*
* Non-MT-safe version
{
char *fmt; /* format string */
int ch; /* character from fmt */
-@@ -502,6 +548,11 @@
+@@ -502,6 +575,11 @@
int nseps; /* number of group separators with ' */
int nrepeats; /* number of repeats of the last group */
#endif
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ union arg vval; /* Vector argument. */
+ char *pct; /* Pointer to '%' at beginning of specifier. */
+ char vsep; /* Vector separator character. */
u_long ulval; /* integer arguments %[diouxX] */
uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */
int base; /* base for [diouxX] conversion */
-@@ -633,22 +684,23 @@
+@@ -574,15 +652,6 @@
+ }
+
+ /*
+- * Get the argument indexed by nextarg. If the argument table is
+- * built, use it to get the argument. If its not, get the next
+- * argument (and arguments must be gotten sequentially).
+- */
+-#define GETARG(type) \
+- ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
+- (nextarg++, va_arg(ap, type)))
+-
+- /*
+ * To extend shorts properly, we need both signed and unsigned
+ * argument extraction methods.
+ */
+@@ -633,22 +702,23 @@
val = GETARG (int); \
}
fmt = (char *)fmt0;
argtable = NULL;
-@@ -675,6 +727,9 @@
+@@ -675,6 +745,9 @@
}
if (ch == '\0')
goto done;
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ pct = fmt;
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
fmt++; /* skip over '%' */
flags = 0;
-@@ -683,6 +738,9 @@
+@@ -683,6 +756,9 @@
prec = -1;
sign = '\0';
ox[1] = '\0';
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ vsep = 'X'; /* Illegal value, changed to defaults later. */
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
rflag: ch = *fmt++;
reswitch: switch (ch) {
-@@ -698,6 +756,11 @@
+@@ -698,6 +774,11 @@
case '#':
flags |= ALT;
goto rflag;
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ case ',': case ';': case ':': case '_':
+ vsep = ch;
+ goto rflag;
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
case '*':
/*-
* ``A negative field width argument is taken as a
-@@ -718,8 +781,8 @@
+@@ -718,8 +799,8 @@
goto rflag;
case '\'':
flags |= GROUPING;
goto rflag;
case '.':
if ((ch = *fmt++) == '*') {
-@@ -793,14 +856,18 @@
+@@ -793,14 +874,20 @@
flags |= LONGINT;
/*FALLTHROUGH*/
case 'c':
-+#ifdef VECTORS
-+ if (flags & VECTOR)
++#ifdef ALTIVEC
++ if (flags & VECTOR) {
++ SETVEC(vval);
+ break;
-+#endif /* VECTORS */
++ }
++#endif /* ALTIVEC */
if (flags & LONGINT) {
static const mbstate_t initial;
mbstate_t mbs;
if (mbseqlen == (size_t)-1) {
fp->_flags |= __SERR;
goto error;
-@@ -817,6 +884,10 @@
+@@ -817,6 +904,12 @@
/*FALLTHROUGH*/
case 'd':
case 'i':
-+#ifdef VECTORS
-+ if (flags & VECTOR)
++#ifdef ALTIVEC
++ if (flags & VECTOR) {
++ SETVEC(vval);
+ break;
-+#endif /* VECTORS */
++ }
++#endif /* ALTIVEC */
if (flags & INTMAX_SIZE) {
ujval = SJARG();
if ((intmax_t)ujval < 0) {
-@@ -835,6 +906,12 @@
+@@ -835,6 +928,13 @@
#ifndef NO_FLOATING_POINT
case 'a':
case 'A':
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ if (flags & VECTOR) {
+ flags |= FPT;
++ SETVEC(vval);
+ break;
+ }
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
if (ch == 'a') {
ox[1] = 'x';
xdigs = xdigs_lower;
-@@ -848,6 +925,12 @@
+@@ -848,6 +948,12 @@
prec++;
if (dtoaresult != NULL)
freedtoa(dtoaresult);
if (flags & LONGDBL) {
fparg.ldbl = GETARG(long double);
dtoaresult = cp =
-@@ -859,6 +942,7 @@
+@@ -859,6 +965,7 @@
__hdtoa(fparg.dbl, xdigs, prec,
&expt, &signflag, &dtoaend);
}
if (prec < 0)
prec = dtoaend - cp;
if (expt == INT_MAX)
-@@ -866,6 +950,12 @@
+@@ -866,6 +973,13 @@
goto fp_common;
case 'e':
case 'E':
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ if (flags & VECTOR) {
+ flags |= FPT;
++ SETVEC(vval);
+ break;
+ }
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
expchar = ch;
if (prec < 0) /* account for digit before decpt */
prec = DEFPREC + 1;
-@@ -874,10 +964,22 @@
+@@ -874,10 +988,24 @@
goto fp_begin;
case 'f':
case 'F':
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ if (flags & VECTOR) {
+ flags |= FPT;
++ SETVEC(vval);
+ break;
+ }
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
expchar = '\0';
goto fp_begin;
case 'g':
case 'G':
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ if (flags & VECTOR) {
+ flags |= FPT;
++ SETVEC(vval);
+ break;
+ }
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
expchar = ch - ('g' - 'e');
if (prec == 0)
prec = 1;
-@@ -886,6 +988,14 @@
+@@ -886,6 +1014,14 @@
prec = DEFPREC;
if (dtoaresult != NULL)
freedtoa(dtoaresult);
if (flags & LONGDBL) {
fparg.ldbl = GETARG(long double);
dtoaresult = cp =
-@@ -899,6 +1009,7 @@
+@@ -899,6 +1035,7 @@
if (expt == 9999)
expt = INT_MAX;
}
fp_common:
if (signflag)
sign = '-';
-@@ -993,6 +1104,10 @@
+@@ -993,6 +1130,12 @@
flags |= LONGINT;
/*FALLTHROUGH*/
case 'o':
-+#ifdef VECTORS
-+ if (flags & VECTOR)
++#ifdef ALTIVEC
++ if (flags & VECTOR) {
++ SETVEC(vval);
+ break;
-+#endif /* VECTORS */
++ }
++#endif /* ALTIVEC */
if (flags & INTMAX_SIZE)
ujval = UJARG();
else
-@@ -1007,6 +1122,10 @@
+@@ -1007,6 +1150,12 @@
* defined manner.''
* -- ANSI X3J11
*/
-+#ifdef VECTORS
-+ if (flags & VECTOR)
++#ifdef ALTIVEC
++ if (flags & VECTOR) {
++ SETVEC(vval);
+ break;
-+#endif /* VECTORS */
++ }
++#endif /* ALTIVEC */
ujval = (uintmax_t)(uintptr_t)GETARG(void *);
base = 16;
xdigs = xdigs_lower;
-@@ -1025,7 +1144,7 @@
+@@ -1025,7 +1174,7 @@
if ((wcp = GETARG(wchar_t *)) == NULL)
cp = "(null)";
else {
if (convbuf == NULL) {
fp->_flags |= __SERR;
goto error;
-@@ -1056,6 +1175,10 @@
+@@ -1056,6 +1205,12 @@
flags |= LONGINT;
/*FALLTHROUGH*/
case 'u':
-+#ifdef VECTORS
-+ if (flags & VECTOR)
++#ifdef ALTIVEC
++ if (flags & VECTOR) {
++ SETVEC(vval);
+ break;
-+#endif /* VECTORS */
++ }
++#endif /* ALTIVEC */
if (flags & INTMAX_SIZE)
ujval = UJARG();
else
-@@ -1068,6 +1191,10 @@
+@@ -1068,6 +1223,12 @@
case 'x':
xdigs = xdigs_lower;
hex:
-+#ifdef VECTORS
-+ if (flags & VECTOR)
++#ifdef ALTIVEC
++ if (flags & VECTOR) {
++ SETVEC(vval);
+ break;
-+#endif /* VECTORS */
++ }
++#endif /* ALTIVEC */
if (flags & INTMAX_SIZE)
ujval = UJARG();
else
-@@ -1112,6 +1239,11 @@
+@@ -1112,6 +1273,14 @@
if (size > BUF) /* should never happen */
abort();
break;
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ case 'v':
-+ flags |= VECTOR;
-+ goto rflag;
-+#endif /* VECTORS */
++ if (hasAltivec) {
++ flags |= VECTOR;
++ goto rflag;
++ }
++ /* drap through */
++#endif /* ALTIVEC */
default: /* "%?" prints ?, unless ? is NUL */
if (ch == '\0')
goto done;
-@@ -1123,6 +1255,290 @@
+@@ -1123,6 +1292,184 @@
break;
}
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ if (flags & VECTOR) {
+ /*
+ * Do the minimum amount of work necessary to construct
+ int i, j; /* Counter. */
+ int vcnt; /* Number of elements in vector. */
+ char *vfmt; /* Pointer to format specifier. */
-+#define EXTRAHH 2
-+ char vfmt_buf[32 + EXTRAHH]; /* Static buffer for format spec. */
++ char vfmt_buf[32]; /* Static buffer for format spec. */
+ int vwidth = 0; /* Width specified via '*'. */
+ int vprec = 0; /* Precision specified via '*'. */
++ union { /* Element. */
++ int i;
++ float f;
++ } velm;
+ char *vstr; /* Used for asprintf(). */
+ int vlen; /* Length returned by asprintf(). */
-+ enum {
-+ V_CHAR, V_SHORT, V_INT,
-+ V_PCHAR, V_PSHORT, V_PINT,
-+ V_FLOAT,
-+#ifdef V64TYPE
-+ V_LONGLONG, V_PLONGLONG,
-+ V_DOUBLE,
-+#endif /* V64TYPE */
-+ } vtype;
+
-+ vval.vectorarg = GETARG(VECTORTYPE);
+ /*
+ * Set vfmt. If vfmt_buf may not be big enough,
+ * malloc() space, taking care to free it later.
-+ * (EXTRAHH is for possible extra "hh")
+ */
-+ if (&fmt[-1] - pct + EXTRAHH < sizeof(vfmt_buf))
++ if (&fmt[-1] - pct < sizeof(vfmt_buf))
+ vfmt = vfmt_buf;
+ else
-+ vfmt = (char *)malloc(&fmt[-1] - pct + EXTRAHH + 1);
++ vfmt = (char *)malloc(&fmt[-1] - pct + 1);
+
+ /* Set the separator character, if not specified. */
+ if (vsep == 'X') {
+ * finish up the format specifier.
+ */
+ if (flags & SHORTINT) {
-+ switch (ch) {
-+ case 'c':
-+ vtype = V_SHORT;
-+ break;
-+ case 'p':
-+ vtype = V_PSHORT;
-+ break;
-+ default:
++ if (ch != 'c')
+ vfmt[j++] = 'h';
-+ vtype = V_SHORT;
-+ break;
-+ }
+ vcnt = 8;
+ } else if (flags & LONGINT) {
-+ vcnt = 4;
-+ vtype = (ch == 'p') ? V_PINT : V_INT;
-+#ifdef V64TYPE
-+ } else if (flags & LLONGINT) {
-+ switch (ch) {
-+ case 'a':
-+ case 'A':
-+ case 'e':
-+ case 'E':
-+ case 'f':
-+ case 'g':
-+ case 'G':
-+ vcnt = 2;
-+ vtype = V_DOUBLE;
-+ break;
-+ case 'd':
-+ case 'i':
-+ case 'u':
-+ case 'o':
-+ case 'p':
-+ case 'x':
-+ case 'X':
-+ vfmt[j++] = 'l';
++ if (ch != 'c')
+ vfmt[j++] = 'l';
-+ vcnt = 2;
-+ vtype = (ch == 'p') ? V_PLONGLONG : V_LONGLONG;
-+ break;
-+ default:
-+ /*
-+ * The default case should never
-+ * happen.
-+ */
-+ case 'c':
-+ vcnt = 16;
-+ vtype = V_CHAR;
-+ }
-+#endif /* V64TYPE */
++ vcnt = 4;
+ } else {
+ switch (ch) {
+ case 'a':
+ case 'g':
+ case 'G':
+ vcnt = 4;
-+ vtype = V_FLOAT;
+ break;
+ default:
+ /*
+ * The default case should never
+ * happen.
+ */
++ case 'c':
+ case 'd':
+ case 'i':
+ case 'u':
+ case 'o':
++ case 'p':
+ case 'x':
+ case 'X':
-+ vfmt[j++] = 'h';
-+ vfmt[j++] = 'h';
-+ /* drop through */
-+ case 'p':
-+ case 'c':
+ vcnt = 16;
-+ vtype = (ch == 'p') ? V_PCHAR : V_CHAR;
+ }
+ }
+ vfmt[j++] = ch;
+ vfmt[j++] = '\0';
+
+/* Get a vector element. */
-+#ifdef V64TYPE
-+#define VPRINT(type, ind, args...) do { \
-+ switch (type) { \
-+ case V_CHAR: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuchararg[ind]); \
-+ break; \
-+ case V_PCHAR: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuchararg[ind]); \
-+ break; \
-+ case V_SHORT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vushortarg[ind]); \
-+ break; \
-+ case V_PSHORT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vushortarg[ind]); \
-+ break; \
-+ case V_INT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuintarg[ind]); \
-+ break; \
-+ case V_PINT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuintarg[ind]); \
-+ break; \
-+ case V_LONGLONG: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vulonglongarg[ind]); \
-+ break; \
-+ case V_PLONGLONG: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vulonglongarg[ind]); \
-+ break; \
-+ case V_FLOAT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \
-+ break; \
-+ case V_DOUBLE: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vdoublearg[ind]); \
-+ break; \
-+ } \
-+ ret += vlen; \
-+ PRINT(vstr, vlen); \
-+ FLUSH(); \
-+ free(vstr); \
-+} while (0)
-+#else /* !V64TYPE */
-+#define VPRINT(type, ind, args...) do { \
-+ switch (type) { \
-+ case V_CHAR: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuchararg[ind]); \
-+ break; \
-+ case V_PCHAR: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuchararg[ind]); \
-+ break; \
-+ case V_SHORT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vushortarg[ind]); \
-+ break; \
-+ case V_PSHORT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vushortarg[ind]); \
-+ break; \
-+ case V_INT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuintarg[ind]); \
-+ break; \
-+ case V_PINT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuintarg[ind]); \
-+ break; \
-+ case V_FLOAT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \
-+ break; \
++#define VPRINT(cnt, ind, args...) do { \
++ if (flags & FPT) { \
++ velm.f = vval.vfloatarg[ind]; \
++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, velm.f); \
++ } else { \
++ switch (cnt) { \
++ default: \
++ /* The default case should never happen. */ \
++ case 4: \
++ velm.i = (unsigned)vval.vintarg[ind]; \
++ break; \
++ case 8: \
++ velm.i = (unsigned short)vval.vshortarg[ind]; \
++ break; \
++ case 16: \
++ velm.i = (unsigned char)vval.vchararg[ind]; \
++ break; \
++ } \
++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, velm.i); \
+ } \
+ ret += vlen; \
+ PRINT(vstr, vlen); \
+ FLUSH(); \
+ free(vstr); \
+} while (0)
-+#endif /* V64TYPE */
+
+ /* Actually print. */
+ if (vwidth == 0) {
+ if (vprec == 0) {
+ /* First element. */
-+ VPRINT(vtype, 0);
++ VPRINT(vcnt, 0);
+ for (i = 1; i < vcnt; i++) {
+ /* Separator. */
-+ if(vsep)
-+ PRINT(&vsep, 1);
++ PRINT(&vsep, 1);
+
+ /* Element. */
-+ VPRINT(vtype, i);
++ VPRINT(vcnt, i);
+ }
+ } else {
+ /* First element. */
-+ VPRINT(vtype, 0, prec);
++ VPRINT(vcnt, 0, prec);
+ for (i = 1; i < vcnt; i++) {
+ /* Separator. */
-+ if(vsep)
-+ PRINT(&vsep, 1);
++ PRINT(&vsep, 1);
+
+ /* Element. */
-+ VPRINT(vtype, i, prec);
++ VPRINT(vcnt, i, prec);
+ }
+ }
+ } else {
+ if (vprec == 0) {
+ /* First element. */
-+ VPRINT(vtype, 0, width);
++ VPRINT(vcnt, 0, width);
+ for (i = 1; i < vcnt; i++) {
+ /* Separator. */
-+ if(vsep)
-+ PRINT(&vsep, 1);
++ PRINT(&vsep, 1);
+
+ /* Element. */
-+ VPRINT(vtype, i, width);
++ VPRINT(vcnt, i, width);
+ }
+ } else {
+ /* First element. */
-+ VPRINT(vtype, 0, width, prec);
++ VPRINT(vcnt, 0, width, prec);
+ for (i = 1; i < vcnt; i++) {
+ /* Separator. */
-+ if(vsep)
-+ PRINT(&vsep, 1);
++ PRINT(&vsep, 1);
+
+ /* Element. */
-+ VPRINT(vtype, i, width, prec);
++ VPRINT(vcnt, i, width, prec);
+ }
+ }
+ }
+
+ continue;
+ }
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
/*
* All reasonable formats wind up here. At this point, `cp'
* points to a string which (if not flags&LADJUST) should be
-@@ -1406,6 +1822,11 @@
+@@ -1406,6 +1753,11 @@
if (flags & LONGINT)
ADDTYPE(T_WINT);
else
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ if (flags & VECTOR)
+ ADDTYPE(T_VECTOR);
+ else
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
ADDTYPE(T_INT);
break;
case 'D':
-@@ -1413,6 +1834,11 @@
+@@ -1413,6 +1765,11 @@
/*FALLTHROUGH*/
case 'd':
case 'i':
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ if (flags & VECTOR)
+ ADDTYPE(T_VECTOR);
+ else
ADDSARG();
break;
#ifndef NO_FLOATING_POINT
-@@ -1423,6 +1849,11 @@
+@@ -1423,6 +1780,11 @@
case 'f':
case 'g':
case 'G':
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ if (flags & VECTOR)
+ ADDTYPE(T_VECTOR);
+ else
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
if (flags & LONGDBL)
ADDTYPE(T_LONG_DOUBLE);
else
-@@ -1451,9 +1882,19 @@
+@@ -1451,9 +1813,19 @@
flags |= LONGINT;
/*FALLTHROUGH*/
case 'o':
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ if (flags & VECTOR)
+ ADDTYPE(T_VECTOR);
+ else
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
ADDUARG();
break;
case 'p':
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ if (flags & VECTOR)
+ ADDTYPE(T_VECTOR);
+ else
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
ADDTYPE(TP_VOID);
break;
case 'S':
-@@ -1471,6 +1912,11 @@
+@@ -1471,6 +1843,11 @@
case 'u':
case 'X':
case 'x':
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ if (flags & VECTOR)
+ ADDTYPE(T_VECTOR);
+ else
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
ADDUARG();
break;
default: /* "%?" prints ?, unless ? is NUL */
-@@ -1537,7 +1983,7 @@
+@@ -1537,7 +1914,7 @@
(*argtable) [n].sizearg = va_arg (ap, size_t);
break;
case TP_SIZET:
break;
case T_INTMAXT:
(*argtable) [n].intmaxarg = va_arg (ap, intmax_t);
-@@ -1556,6 +2002,11 @@
+@@ -1556,6 +1933,12 @@
(*argtable) [n].longdoublearg = va_arg (ap, long double);
break;
#endif
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ case T_VECTOR:
-+ (*argtable) [n].vectorarg = va_arg (ap, VECTORTYPE);
++ if (hasAltivec)
++ ap = getvec( &((*argtable) [n]), NULL, 0, ap );
+ break;
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
case TP_CHAR:
(*argtable) [n].pchararg = va_arg (ap, char *);
break;
--- vfwprintf.c.orig 2004-11-25 11:38:36.000000000 -0800
-+++ vfwprintf.c 2005-11-08 22:46:07.000000000 -0800
++++ vfwprintf.c 2005-02-24 15:17:14.000000000 -0800
@@ -42,6 +42,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.23 2004/08/26 06:25:28 des Exp $");
/*
* Actual wprintf innards.
*
-@@ -63,12 +65,20 @@
+@@ -63,12 +65,19 @@
#include <string.h>
#include <wchar.h>
#include <wctype.h>
#include "local.h"
#include "fvwrite.h"
-+#ifdef VECTORS
-+typedef __attribute__ ((vector_size(16))) unsigned char VECTORTYPE;
-+#ifdef __SSE2__
-+#define V64TYPE
-+#endif /* __SSE2__ */
-+#endif /* VECTORS */
++#ifdef ALTIVEC
++#include <machine/cpu_capabilities.h>
++
++#define VECTORTYPE vector unsigned char
++#endif /* ALTIVEC */
+
union arg {
int intarg;
u_int uintarg;
-@@ -96,6 +106,21 @@
+@@ -96,6 +105,16 @@
#endif
wint_t wintarg;
wchar_t *pwchararg;
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ VECTORTYPE vectorarg;
+ unsigned char vuchararg[16];
+ signed char vchararg[16];
+ unsigned int vuintarg[4];
+ signed int vintarg[4];
+ float vfloatarg[4];
-+#ifdef V64TYPE
-+ double vdoublearg[2];
-+ unsigned long long vulonglongarg[2];
-+ long long vlonglongarg[2];
-+#endif /* V64TYPE */
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
};
/*
-@@ -106,16 +131,20 @@
+@@ -106,26 +125,63 @@
T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG,
T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET,
T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR,
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR, T_VECTOR
-+#else /* ! VECTORS */
++#else /* ! ALTIVEC */
T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
};
-static int __sbprintf(FILE *, const wchar_t *, va_list);
static void __find_arguments(const wchar_t *, va_list, union arg **);
static void __grow_type_table(int, enum typeid **, int *);
-@@ -125,7 +154,7 @@
++ /*
++ * Get the argument indexed by nextarg. If the argument table is
++ * built, use it to get the argument. If its not, get the next
++ * argument (and arguments must be gotten sequentially).
++ */
++#define GETARG(type) \
++ ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
++ (nextarg++, va_arg(ap, type)))
++
++#ifdef ALTIVEC
++#define hasAltivec (_cpu_capabilities & kHasAltivec)
++/*-----------------------------------------------------------------------
++ * getvec() must be a real subroutine. If it is a #define, then __vfprintf()
++ * would have its calling sequence changed by Altivec so that a non-Altivec
++ * processor would crash on illegal instruction. By isolating the calling
++ * sequence in getvec(), __vprintf() is callable by a non-Altivec processor.
++ *-----------------------------------------------------------------------*/
++static va_list getvec(union arg *, const union arg *, int, va_list) __attribute__((noinline));
++
++static va_list
++getvec(union arg *dst, const union arg *argtable, int nextarg, va_list ap)
++{
++ dst->vectorarg = GETARG(VECTORTYPE);
++ return ap;
++}
++
++#define SETVEC(dst) \
++{ \
++ ap = getvec(&dst, argtable, nextarg, ap); \
++ nextarg++; \
++}
++#endif /* ALTIVEC */
++
+ /*
+ * Helper function for `fprintf to unbuffered unix file': creates a
+ * temporary buffer. We only work on write-only files; this avoids
* worries about ungetc buffers and so forth.
*/
static int
{
int ret;
FILE fake;
-@@ -144,7 +173,7 @@
+@@ -144,7 +200,7 @@
fake._lbfsize = 0; /* not actually used, but Just In Case */
/* do the work, then copy any error status */
if (ret >= 0 && __fflush(&fake))
ret = WEOF;
if (fake._flags & __SERR)
-@@ -157,7 +186,7 @@
+@@ -157,7 +213,7 @@
* File must already be locked.
*/
static wint_t
{
static const mbstate_t initial;
mbstate_t mbs;
-@@ -167,10 +196,10 @@
+@@ -167,10 +223,10 @@
size_t len;
if ((fp->_flags & __SSTR) == 0)
fp->_flags |= __SERR;
return (WEOF);
}
-@@ -350,13 +379,14 @@
+@@ -350,13 +406,14 @@
* that the multibyte char. string ends in a null character.
*/
static wchar_t *
if (mbsarg == NULL)
return (NULL);
-@@ -374,7 +404,7 @@
+@@ -374,7 +431,7 @@
insize = nchars = 0;
mbs = initial;
while (nchars != (size_t)prec) {
if (nconv == 0 || nconv == (size_t)-1 ||
nconv == (size_t)-2)
break;
-@@ -399,7 +429,7 @@
+@@ -399,7 +456,7 @@
p = mbsarg;
mbs = initial;
while (insize != 0) {
if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2)
break;
wcp++;
-@@ -425,7 +455,21 @@
+@@ -425,7 +482,21 @@
int ret;
FLOCKFILE(fp);
FUNLOCKFILE(fp);
return (ret);
}
-@@ -474,12 +518,15 @@
+@@ -474,12 +545,15 @@
#define PTRDIFFT 0x800 /* ptrdiff_t */
#define INTMAXT 0x1000 /* intmax_t */
#define CHARINT 0x2000 /* print char using int format */
-+#ifdef VECTORS
-+#define VECTOR 0x4000 /* Altivec or SSE vector */
-+#endif /* VECTORS */
++#ifdef ALTIVEC
++#define VECTOR 0x4000 /* Altivec vector */
++#endif /* ALTIVEC */
/*
* Non-MT-safe version
{
wchar_t *fmt; /* format string */
wchar_t ch; /* character from fmt */
-@@ -524,6 +571,11 @@
+@@ -524,6 +598,11 @@
int nseps; /* number of group separators with ' */
int nrepeats; /* number of repeats of the last group */
#endif
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ union arg vval; /* Vector argument. */
+ wchar_t *pct; /* Pointer to '%' at beginning of specifier. */
+ wchar_t vsep; /* Vector separator character. */
u_long ulval; /* integer arguments %[diouxX] */
uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */
int base; /* base for [diouxX] conversion */
-@@ -560,7 +612,7 @@
+@@ -560,7 +639,7 @@
*/
#define PRINT(ptr, len) do { \
for (n3 = 0; n3 < (len); n3++) \
} while (0)
#define PAD(howmany, with) do { \
if ((n = (howmany)) > 0) { \
-@@ -640,21 +692,22 @@
+@@ -581,15 +660,6 @@
+ } while(0)
+
+ /*
+- * Get the argument indexed by nextarg. If the argument table is
+- * built, use it to get the argument. If its not, get the next
+- * argument (and arguments must be gotten sequentially).
+- */
+-#define GETARG(type) \
+- ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
+- (nextarg++, va_arg(ap, type)))
+-
+- /*
+ * To extend shorts properly, we need both signed and unsigned
+ * argument extraction methods.
+ */
+@@ -640,21 +710,22 @@
val = GETARG (int); \
}
fmt = (wchar_t *)fmt0;
argtable = NULL;
-@@ -678,6 +731,9 @@
+@@ -678,6 +749,9 @@
}
if (ch == '\0')
goto done;
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ pct = fmt;
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
fmt++; /* skip over '%' */
flags = 0;
-@@ -686,6 +742,9 @@
+@@ -686,6 +760,9 @@
prec = -1;
sign = '\0';
ox[1] = '\0';
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ vsep = 'X'; /* Illegal value, changed to defaults later. */
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
rflag: ch = *fmt++;
reswitch: switch (ch) {
-@@ -701,6 +760,11 @@
+@@ -701,6 +778,11 @@
case '#':
flags |= ALT;
goto rflag;
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ case ',': case ';': case ':': case '_':
+ vsep = ch;
+ goto rflag;
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
case '*':
/*-
* ``A negative field width argument is taken as a
-@@ -721,8 +785,8 @@
+@@ -721,8 +803,8 @@
goto rflag;
case '\'':
flags |= GROUPING;
goto rflag;
case '.':
if ((ch = *fmt++) == '*') {
-@@ -796,10 +860,14 @@
+@@ -796,10 +878,16 @@
flags |= LONGINT;
/*FALLTHROUGH*/
case 'c':
-+#ifdef VECTORS
-+ if (flags & VECTOR)
++#ifdef ALTIVEC
++ if (flags & VECTOR) {
++ SETVEC(vval);
+ break;
-+#endif /* VECTORS */
++ }
++#endif /* ALTIVEC */
if (flags & LONGINT)
*(cp = buf) = (wchar_t)GETARG(wint_t);
else
size = 1;
sign = '\0';
break;
-@@ -808,6 +876,10 @@
+@@ -808,6 +896,12 @@
/*FALLTHROUGH*/
case 'd':
case 'i':
-+#ifdef VECTORS
-+ if (flags & VECTOR)
++#ifdef ALTIVEC
++ if (flags & VECTOR) {
++ SETVEC(vval);
+ break;
-+#endif /* VECTORS */
++ }
++#endif /* ALTIVEC */
if (flags & INTMAX_SIZE) {
ujval = SJARG();
if ((intmax_t)ujval < 0) {
-@@ -826,6 +898,12 @@
- #ifndef NO_FLOATING_POINT
- case 'a':
- case 'A':
-+#ifdef VECTORS
-+ if (flags & VECTOR) {
-+ flags |= FPT;
-+ break;
-+ }
-+#endif /* VECTORS */
- if (ch == 'a') {
- ox[1] = 'x';
- xdigs = xdigs_lower;
-@@ -837,6 +915,12 @@
+@@ -837,6 +931,12 @@
}
if (prec >= 0)
prec++;
if (flags & LONGDBL) {
fparg.ldbl = GETARG(long double);
dtoaresult =
-@@ -848,6 +932,7 @@
+@@ -848,6 +948,7 @@
__hdtoa(fparg.dbl, xdigs, prec,
&expt, &signflag, &dtoaend);
}
if (prec < 0)
prec = dtoaend - dtoaresult;
if (expt == INT_MAX)
-@@ -855,11 +940,17 @@
+@@ -855,7 +956,7 @@
if (convbuf != NULL)
free(convbuf);
ndig = dtoaend - dtoaresult;
freedtoa(dtoaresult);
goto fp_common;
case 'e':
- case 'E':
-+#ifdef VECTORS
-+ if (flags & VECTOR) {
-+ flags |= FPT;
-+ break;
-+ }
-+#endif /* VECTORS */
- expchar = ch;
- if (prec < 0) /* account for digit before decpt */
- prec = DEFPREC + 1;
-@@ -868,10 +959,22 @@
+@@ -868,10 +969,24 @@
goto fp_begin;
case 'f':
case 'F':
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ if (flags & VECTOR) {
+ flags |= FPT;
++ SETVEC(vval);
+ break;
+ }
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
expchar = '\0';
goto fp_begin;
case 'g':
case 'G':
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ if (flags & VECTOR) {
+ flags |= FPT;
++ SETVEC(vval);
+ break;
+ }
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
expchar = ch - ('g' - 'e');
if (prec == 0)
prec = 1;
-@@ -880,6 +983,14 @@
+@@ -880,6 +995,14 @@
prec = DEFPREC;
if (convbuf != NULL)
free(convbuf);
if (flags & LONGDBL) {
fparg.ldbl = GETARG(long double);
dtoaresult =
-@@ -893,8 +1004,9 @@
+@@ -893,8 +1016,9 @@
if (expt == 9999)
expt = INT_MAX;
}
freedtoa(dtoaresult);
fp_common:
if (signflag)
-@@ -989,6 +1101,10 @@
+@@ -989,6 +1113,12 @@
flags |= LONGINT;
/*FALLTHROUGH*/
case 'o':
-+#ifdef VECTORS
-+ if (flags & VECTOR)
++#ifdef ALTIVEC
++ if (flags & VECTOR) {
++ SETVEC(vval);
+ break;
-+#endif /* VECTORS */
++ }
++#endif /* ALTIVEC */
if (flags & INTMAX_SIZE)
ujval = UJARG();
else
-@@ -1003,6 +1119,10 @@
+@@ -1003,6 +1133,12 @@
* defined manner.''
* -- ANSI X3J11
*/
-+#ifdef VECTORS
-+ if (flags & VECTOR)
++#ifdef ALTIVEC
++ if (flags & VECTOR) {
++ SETVEC(vval);
+ break;
-+#endif /* VECTORS */
++ }
++#endif /* ALTIVEC */
ujval = (uintmax_t)(uintptr_t)GETARG(void *);
base = 16;
xdigs = xdigs_lower;
-@@ -1024,7 +1144,7 @@
+@@ -1024,7 +1160,7 @@
if ((mbp = GETARG(char *)) == NULL)
cp = L"(null)";
else {
if (convbuf == NULL) {
fp->_flags |= __SERR;
goto error;
-@@ -1055,6 +1175,10 @@
+@@ -1055,6 +1191,12 @@
flags |= LONGINT;
/*FALLTHROUGH*/
case 'u':
-+#ifdef VECTORS
-+ if (flags & VECTOR)
++#ifdef ALTIVEC
++ if (flags & VECTOR) {
++ SETVEC(vval);
+ break;
-+#endif /* VECTORS */
++ }
++#endif /* ALTIVEC */
if (flags & INTMAX_SIZE)
ujval = UJARG();
else
-@@ -1067,6 +1191,10 @@
+@@ -1067,6 +1209,12 @@
case 'x':
xdigs = xdigs_lower;
hex:
-+#ifdef VECTORS
-+ if (flags & VECTOR)
++#ifdef ALTIVEC
++ if (flags & VECTOR) {
++ SETVEC(vval);
+ break;
-+#endif /* VECTORS */
++ }
++#endif /* ALTIVEC */
if (flags & INTMAX_SIZE)
ujval = UJARG();
else
-@@ -1111,6 +1239,11 @@
+@@ -1111,6 +1259,14 @@
if (size > BUF) /* should never happen */
abort();
break;
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ case 'v':
-+ flags |= VECTOR;
-+ goto rflag;
-+#endif /* VECTORS */
++ if (hasAltivec) {
++ flags |= VECTOR;
++ goto rflag;
++ }
++ /* drop through */
++#endif /* ALTIVEC */
default: /* "%?" prints ?, unless ? is NUL */
if (ch == '\0')
goto done;
-@@ -1122,6 +1255,288 @@
+@@ -1122,6 +1278,183 @@
break;
}
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ if (flags & VECTOR) {
+ /*
+ * Do the minimum amount of work necessary to construct
+ int i, j; /* Counter. */
+ int vcnt; /* Number of elements in vector. */
+ char *vfmt; /* Pointer to format specifier. */
-+#define EXTRAHH 2
-+ char vfmt_buf[32 + EXTRAHH]; /* Static buffer for format spec. */
++ char vfmt_buf[32]; /* Static buffer for format spec. */
+ int vwidth = 0; /* Width specified via '*'. */
+ int vprec = 0; /* Precision specified via '*'. */
++ union { /* Element. */
++ int i;
++ float f;
++ } velm;
+ char *vstr; /* Used for asprintf(). */
+ int vlen; /* Length returned by asprintf(). */
-+ enum {
-+ V_CHAR, V_SHORT, V_INT,
-+ V_PCHAR, V_PSHORT, V_PINT,
-+ V_FLOAT,
-+#ifdef V64TYPE
-+ V_LONGLONG, V_PLONGLONG,
-+ V_DOUBLE,
-+#endif /* V64TYPE */
-+ } vtype;
+
-+ vval.vectorarg = GETARG(VECTORTYPE);
+ /*
+ * Set vfmt. If vfmt_buf may not be big enough,
+ * malloc() space, taking care to free it later.
-+ * (EXTRAHH is for possible extra "hh")
+ */
-+ if (&fmt[-1] - pct + EXTRAHH < sizeof(vfmt_buf))
++ if (&fmt[-1] - pct < sizeof(vfmt_buf))
+ vfmt = vfmt_buf;
+ else
-+ vfmt = (char *)malloc(&fmt[-1] - pct + EXTRAHH + 1);
++ vfmt = (char *)malloc(&fmt[-1] - pct + 1);
+
+ /* Set the separator character, if not specified. */
+ if (vsep == 'X') {
+ * finish up the format specifier.
+ */
+ if (flags & SHORTINT) {
-+ switch (ch) {
-+ case 'c':
-+ vtype = V_SHORT;
-+ break;
-+ case 'p':
-+ vtype = V_PSHORT;
-+ break;
-+ default:
++ if (ch != 'c')
+ vfmt[j++] = 'h';
-+ vtype = V_SHORT;
-+ break;
-+ }
+ vcnt = 8;
+ } else if (flags & LONGINT) {
-+ vcnt = 4;
-+ vtype = (ch == 'p') ? V_PINT : V_INT;
-+#ifdef V64TYPE
-+ } else if (flags & LLONGINT) {
-+ switch (ch) {
-+ case 'a':
-+ case 'A':
-+ case 'e':
-+ case 'E':
-+ case 'f':
-+ case 'g':
-+ case 'G':
-+ vcnt = 2;
-+ vtype = V_DOUBLE;
-+ break;
-+ case 'd':
-+ case 'i':
-+ case 'u':
-+ case 'o':
-+ case 'p':
-+ case 'x':
-+ case 'X':
++ if (ch != 'c')
+ vfmt[j++] = 'l';
-+ vfmt[j++] = 'l';
-+ vcnt = 2;
-+ vtype = (ch == 'p') ? V_PLONGLONG : V_LONGLONG;
-+ break;
-+ default:
-+ /*
-+ * The default case should never
-+ * happen.
-+ */
-+ case 'c':
-+ vcnt = 16;
-+ vtype = V_CHAR;
-+ }
-+#endif /* V64TYPE */
++ vcnt = 4;
+ } else {
+ switch (ch) {
+ case 'a':
+ case 'g':
+ case 'G':
+ vcnt = 4;
-+ vtype = V_FLOAT;
+ break;
+ default:
+ /*
+ * The default case should never
+ * happen.
+ */
++ case 'c':
+ case 'd':
+ case 'i':
+ case 'u':
+ case 'o':
++ case 'p':
+ case 'x':
+ case 'X':
-+ vfmt[j++] = 'h';
-+ vfmt[j++] = 'h';
-+ /* drop through */
-+ case 'p':
-+ case 'c':
+ vcnt = 16;
-+ vtype = (ch == 'p') ? V_PCHAR : V_CHAR;
+ }
+ }
+ vfmt[j++] = ch;
+ vfmt[j++] = '\0';
+
+/* Get a vector element. */
-+#ifdef V64TYPE
-+#define VPRINT(type, ind, args...) do { \
-+ switch (type) { \
-+ case V_CHAR: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuchararg[ind]); \
-+ break; \
-+ case V_PCHAR: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuchararg[ind]); \
-+ break; \
-+ case V_SHORT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vushortarg[ind]); \
-+ break; \
-+ case V_PSHORT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vushortarg[ind]); \
-+ break; \
-+ case V_INT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuintarg[ind]); \
-+ break; \
-+ case V_PINT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuintarg[ind]); \
-+ break; \
-+ case V_LONGLONG: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vulonglongarg[ind]); \
-+ break; \
-+ case V_PLONGLONG: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vulonglongarg[ind]); \
-+ break; \
-+ case V_FLOAT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \
-+ break; \
-+ case V_DOUBLE: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vdoublearg[ind]); \
-+ break; \
-+ } \
-+ ret += vlen; \
-+ PRINT(vstr, vlen); \
-+ free(vstr); \
-+} while (0)
-+#else /* !V64TYPE */
-+#define VPRINT(type, ind, args...) do { \
-+ switch (type) { \
-+ case V_CHAR: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuchararg[ind]); \
-+ break; \
-+ case V_PCHAR: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuchararg[ind]); \
-+ break; \
-+ case V_SHORT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vushortarg[ind]); \
-+ break; \
-+ case V_PSHORT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vushortarg[ind]); \
-+ break; \
-+ case V_INT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuintarg[ind]); \
-+ break; \
-+ case V_PINT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuintarg[ind]); \
-+ break; \
-+ case V_FLOAT: \
-+ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \
-+ break; \
++#define VPRINT(cnt, ind, args...) do { \
++ if (flags & FPT) { \
++ velm.f = vval.vfloatarg[ind]; \
++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, velm.f); \
++ } else { \
++ switch (cnt) { \
++ default: \
++ /* The default case should never happen. */ \
++ case 4: \
++ velm.i = (unsigned)vval.vintarg[ind]; \
++ break; \
++ case 8: \
++ velm.i = (unsigned short)vval.vshortarg[ind]; \
++ break; \
++ case 16: \
++ velm.i = (unsigned char)vval.vchararg[ind]; \
++ break; \
++ } \
++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, velm.i); \
+ } \
+ ret += vlen; \
+ PRINT(vstr, vlen); \
+ free(vstr); \
+} while (0)
-+#endif /* V64TYPE */
+
+ /* Actually print. */
+ if (vwidth == 0) {
+ if (vprec == 0) {
+ /* First element. */
-+ VPRINT(vtype, 0);
++ VPRINT(vcnt, 0);
+ for (i = 1; i < vcnt; i++) {
+ /* Separator. */
-+ if(vsep)
-+ PRINT(&vsep, 1);
++ PRINT(&vsep, 1);
+
+ /* Element. */
-+ VPRINT(vtype, i);
++ VPRINT(vcnt, i);
+ }
+ } else {
+ /* First element. */
-+ VPRINT(vtype, 0, prec);
++ VPRINT(vcnt, 0, prec);
+ for (i = 1; i < vcnt; i++) {
+ /* Separator. */
-+ if(vsep)
-+ PRINT(&vsep, 1);
++ PRINT(&vsep, 1);
+
+ /* Element. */
-+ VPRINT(vtype, i, prec);
++ VPRINT(vcnt, i, prec);
+ }
+ }
+ } else {
+ if (vprec == 0) {
+ /* First element. */
-+ VPRINT(vtype, 0, width);
++ VPRINT(vcnt, 0, width);
+ for (i = 1; i < vcnt; i++) {
+ /* Separator. */
-+ if(vsep)
-+ PRINT(&vsep, 1);
++ PRINT(&vsep, 1);
+
+ /* Element. */
-+ VPRINT(vtype, i, width);
++ VPRINT(vcnt, i, width);
+ }
+ } else {
+ /* First element. */
-+ VPRINT(vtype, 0, width, prec);
++ VPRINT(vcnt, 0, width, prec);
+ for (i = 1; i < vcnt; i++) {
+ /* Separator. */
-+ if(vsep)
-+ PRINT(&vsep, 1);
++ PRINT(&vsep, 1);
+
+ /* Element. */
-+ VPRINT(vtype, i, width, prec);
++ VPRINT(vcnt, i, width, prec);
+ }
+ }
+ }
+
+ continue;
+ }
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
/*
* All reasonable formats wind up here. At this point, `cp'
* points to a string which (if not flags&LADJUST) should be
-@@ -1401,6 +1816,11 @@
+@@ -1401,6 +1734,11 @@
if (flags & LONGINT)
ADDTYPE(T_WINT);
else
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ if (flags & VECTOR)
+ ADDTYPE(T_VECTOR);
+ else
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
ADDTYPE(T_INT);
break;
case 'D':
-@@ -1408,6 +1828,11 @@
- /*FALLTHROUGH*/
- case 'd':
- case 'i':
-+#ifdef VECTORS
-+ if (flags & VECTOR)
-+ ADDTYPE(T_VECTOR);
-+ else
-+#endif /* VECTORS */
- ADDSARG();
- break;
- #ifndef NO_FLOATING_POINT
-@@ -1418,6 +1843,11 @@
+@@ -1418,6 +1756,11 @@
case 'f':
case 'g':
case 'G':
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ if (flags & VECTOR)
+ ADDTYPE(T_VECTOR);
+ else
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
if (flags & LONGDBL)
ADDTYPE(T_LONG_DOUBLE);
else
-@@ -1446,9 +1876,19 @@
+@@ -1446,9 +1789,19 @@
flags |= LONGINT;
/*FALLTHROUGH*/
case 'o':
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ if (flags & VECTOR)
+ ADDTYPE(T_VECTOR);
+ else
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
ADDUARG();
break;
case 'p':
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ if (flags & VECTOR)
+ ADDTYPE(T_VECTOR);
+ else
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
ADDTYPE(TP_VOID);
break;
case 'S':
-@@ -1466,6 +1906,11 @@
+@@ -1466,6 +1819,11 @@
case 'u':
case 'X':
case 'x':
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ if (flags & VECTOR)
+ ADDTYPE(T_VECTOR);
+ else
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
ADDUARG();
break;
default: /* "%?" prints ?, unless ? is NUL */
-@@ -1532,7 +1977,7 @@
+@@ -1532,7 +1890,7 @@
(*argtable) [n].sizearg = va_arg (ap, size_t);
break;
case TP_SIZET:
break;
case T_INTMAXT:
(*argtable) [n].intmaxarg = va_arg (ap, intmax_t);
-@@ -1551,6 +1996,11 @@
+@@ -1551,6 +1909,12 @@
(*argtable) [n].longdoublearg = va_arg (ap, long double);
break;
#endif
-+#ifdef VECTORS
++#ifdef ALTIVEC
+ case T_VECTOR:
-+ (*argtable) [n].vectorarg = va_arg (ap, VECTORTYPE);
++ if (hasAltivec)
++ ap = getvec( &((*argtable) [n]), NULL, 0, ap );
+ break;
-+#endif /* VECTORS */
++#endif /* ALTIVEC */
case TP_CHAR:
(*argtable) [n].pchararg = va_arg (ap, char *);
break;
vswscanf.c vwprintf.c vwscanf.c wprintf.c wscanf.c
.for _src in vfprintf-fbsd.c vfwprintf-fbsd.c
-CFLAGS-${_src} += -fshort-enums -DVECTORS
+CFLAGS-${_src} += -fshort-enums
+# add altivec options on per file basis, since it now disables inlining
+.if (${MACHINE_ARCH} == ppc) || (${MACHINE_ARCH} == ppc64)
+CFLAGS-${_src} += -faltivec -DALTIVEC
+.endif
.endfor
UNIX03SRCS+= freopen.c fwrite.c
CFLAGS-${_src} += -D__APPLE_PR3375657_HACK__
.endfor
-.include "Makefile.obsd_begin"
-OBSDMISRCS= stack_protector.c
-.include "Makefile.obsd_end"
-
UNIX03SRCS += mmap.c mprotect.c msgctl.c msync.c munmap.c semctl.c shmctl.c
# Add machine dependent asm sources:
+++ /dev/null
-/*
- * Copyright (c) 2002 Hiroaki Etoh, Federico G. Schwindt, and Miodrag Vallat.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#if defined(LIBC_SCCS) && !defined(list)
-static char rcsid[] = "$OpenBSD: stack_protector.c,v 1.3 2002/12/10 08:53:42 etoh Exp $";
-#endif
-
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#include <syslog.h>
-
-long __guard[8] = {0, 0, 0, 0, 0, 0, 0, 0};
-static void __guard_setup(void) __attribute__ ((constructor));
-void __stack_smash_handler(char func[], int damaged __attribute__((unused)));
-
-static void
-__guard_setup(void)
-{
- int fd;
- if (__guard[0]!=0) return;
- fd = open ("/dev/urandom", 0);
- if (fd != -1) {
- ssize_t size = read (fd, (char*)&__guard, sizeof(__guard));
- close (fd) ;
- if (size == sizeof(__guard)) return;
- }
- /* If a random generator can't be used, the protector switches the guard
- to the "terminator canary" */
- ((char*)__guard)[0] = 0; ((char*)__guard)[1] = 0;
- ((char*)__guard)[2] = '\n'; ((char*)__guard)[3] = 255;
-}
-
-void
-__stack_smash_handler(char func[], int damaged)
-{
- const char message[] = "stack overflow in function %s";
- struct sigaction sa;
-
- /* this may fail on a chroot jail, though luck */
- syslog(LOG_CRIT, message, func);
-
- bzero(&sa, sizeof(struct sigaction));
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_DFL;
- sigaction(SIGABRT, &sa, NULL);
-
- kill(getpid(), SIGABRT);
-
- _exit(127);
-}
/*
- * Copyright (c) 2003-2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
int gettimeofday (struct timeval *tp, struct timezone *tzp)
{
- extern int __gettimeofday(struct timeval *, struct timezone *);
- extern int __commpage_gettimeofday(struct timeval *);
static int validtz = 0;
static struct timezone cached_tz = {0};
- struct timeval atv;
+ struct timeval localtv;
if (tp == NULL) {
if (tzp == NULL)
return (0);
- tp = &atv;
+ tp = &localtv;
}
- if (__commpage_gettimeofday(tp)) { /* first try commpage */
- if (__gettimeofday(tp, tzp) < 0) { /* if it fails, use syscall */
- return (-1);
- }
- }
-
+#if defined(__ppc__) || defined(__ppc64__)
+ {
+ extern int __ppc_gettimeofday(struct timeval *, struct timezone *);
+ extern int __commpage_gettimeofday(struct timeval *);
+
+ if (__commpage_gettimeofday(tp)) { /* first try commpage */
+ if (__ppc_gettimeofday(tp,tzp)) { /* if it fails, use syscall */
+ return (-1);
+ }
+ }
+ }
+#else
+ if (syscall (SYS_gettimeofday, tp, tzp) < 0) {
+ return (-1);
+ }
+#endif
if (tzp) {
if (validtz == 0) {
struct tm *localtm = localtime ((time_t *)&tp->tv_sec);
/* These defn should match the kernel one */
#define UC_TRAD 1
-#define UC_FLAVOR 30
#if defined(__ppc__) || defined(__ppc64__)
#define UC_TRAD64 20
#define UC_TRAD64_VEC 25
+#define UC_FLAVOR 30
#define UC_FLAVOR_VEC 35
#define UC_FLAVOR64 40
#define UC_FLAVOR64_VEC 45
siginfo_t *sinfo,
ucontext_t *uctx
) {
- int ctxstyle = UC_FLAVOR;
#if defined(__ppc__) || defined(__ppc64__)
+ int ctxstyle = UC_FLAVOR;
+#endif
mcontext_t mctx;
mcontext64_t mctx64;
-#endif
#if defined(__DYNAMIC__)
__in_sigtramp++;
#ifdef __i386__
if (sigstyle == UC_TRAD)
sa_handler(sig);
- else {
- sa_sigaction(sig, sinfo, uctx);
- }
#elif defined(__ppc__) || defined(__ppc64__)
if ((sigstyle == UC_TRAD) || (sigstyle == UC_TRAD64) || (sigstyle == UC_TRAD64_VEC))
sa_handler(sig);
#if defined(__DYNAMIC__)
__in_sigtramp--;
#endif
+#if defined(__ppc__) || defined(__ppc64__)
+ {
/* sigreturn(uctx, ctxstyle); */
/* syscall (SYS_SIGRETURN, uctx, ctxstyle); */
syscall (184, uctx, ctxstyle);
+ }
+#else
+ sigreturn(uctx);
+#endif /* __ppc__ || __ppc64__ */
}