2002-04-19 Jeff Johnston <jjohnstn@redhat.com>
* configure.host: Add support for powerpc-eabialtivec*. * libc/include/malloc.h: Add include of <machine/malloc.h>. * libc/include/stdlib.h: Add include of <machine/stdlib.h>. * libc/include/machine/malloc.h: New file. * libc/include/machine/stdlib.h: Ditto. * libc/include/machine/setjmp.h: Add support for powerpc altivec. * libc/machine/powerpc/Makefile.am: Add conditional objects and sources based on configuration. * libc/machine/powerpc/Makefile.in: Regenerated. * libc/machine/powerpc/configure: Ditto. * libc/machine/powerpc/configure.in: Add check for powerpc-eabialtivec* in which case add in additional source files. * libc/machine/powerpc/setjmp.S: Add altivec support. * libc/machine/powerpc/vec_calloc.c: New file. * libc/machine/powerpc/vec_free.c: Ditto. * libc/machine/powerpc/vec_malloc.c: Ditto. * libc/machine/powerpc/vec_mallocr.c: Ditto. * libc/machine/powerpc/vec_realloc.c: Ditto. * libc/machine/powerpc/machine/malloc.h: Ditto. * libc/machine/powerpc/machine/stdlib.h: Ditto. * libc/machine/powerpc/vfprintf.c: New file that is vfprintf.c with added altivec format specifiers. * libc/machine/powerpc/vfscanf.c: New file that is vfscanf.c with added altivec format specifiers.
This commit is contained in:
parent
d413aadcaf
commit
0d844014bf
|
@ -1,3 +1,30 @@
|
|||
2002-04-19 Jeff Johnston <jjohnstn@redhat.com>
|
||||
|
||||
* configure.host: Add support for powerpc-eabialtivec*.
|
||||
* libc/include/malloc.h: Add include of <machine/malloc.h>.
|
||||
* libc/include/stdlib.h: Add include of <machine/stdlib.h>.
|
||||
* libc/include/machine/malloc.h: New file.
|
||||
* libc/include/machine/stdlib.h: Ditto.
|
||||
* libc/include/machine/setjmp.h: Add support for powerpc altivec.
|
||||
* libc/machine/powerpc/Makefile.am: Add conditional objects and
|
||||
sources based on configuration.
|
||||
* libc/machine/powerpc/Makefile.in: Regenerated.
|
||||
* libc/machine/powerpc/configure: Ditto.
|
||||
* libc/machine/powerpc/configure.in: Add check for
|
||||
powerpc-eabialtivec* in which case add in additional source files.
|
||||
* libc/machine/powerpc/setjmp.S: Add altivec support.
|
||||
* libc/machine/powerpc/vec_calloc.c: New file.
|
||||
* libc/machine/powerpc/vec_free.c: Ditto.
|
||||
* libc/machine/powerpc/vec_malloc.c: Ditto.
|
||||
* libc/machine/powerpc/vec_mallocr.c: Ditto.
|
||||
* libc/machine/powerpc/vec_realloc.c: Ditto.
|
||||
* libc/machine/powerpc/machine/malloc.h: Ditto.
|
||||
* libc/machine/powerpc/machine/stdlib.h: Ditto.
|
||||
* libc/machine/powerpc/vfprintf.c: New file that is vfprintf.c
|
||||
with added altivec format specifiers.
|
||||
* libc/machine/powerpc/vfscanf.c: New file that is vfscanf.c with
|
||||
added altivec format specifiers.
|
||||
|
||||
2002-04-19 Joel Sherrill <joel@OARcorp.com>
|
||||
|
||||
* libs/sys/rtems/crt0.c: Satisfy gcc's references to libc functions
|
||||
|
|
|
@ -477,6 +477,9 @@ case "${host}" in
|
|||
mn10?00-*-*)
|
||||
syscall_dir=syscalls
|
||||
;;
|
||||
powerpc*-*-eabialtivec*)
|
||||
newlib_cflags="${newlib_cflags} -DMISSING_SYSCALL_NAMES -DWANT_PRINTF_LONG_LONG"
|
||||
;;
|
||||
powerpc*-*-eabi* | \
|
||||
powerpc*-*-elf* | \
|
||||
powerpc*-*-linux* | \
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef _MACHMALLOC_H_
|
||||
#define _MACHMALLOC_H_
|
||||
|
||||
/* place holder so platforms may add malloc.h extensions */
|
||||
|
||||
#endif /* _MACHMALLOC_H_ */
|
||||
|
||||
|
|
@ -106,7 +106,11 @@ typedef int jmp_buf[_JBLEN];
|
|||
#endif
|
||||
|
||||
#ifdef __PPC__
|
||||
#ifdef __ALTIVEC__
|
||||
#define _JBLEN 64
|
||||
#else
|
||||
#define _JBLEN 32
|
||||
#endif
|
||||
#define _JBTYPE double
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef _MACHSTDLIB_H_
|
||||
#define _MACHSTDLIB_H_
|
||||
|
||||
/* place holder so platforms may add stdlib.h extensions */
|
||||
|
||||
#endif /* _MACHSTDLIB_H_ */
|
||||
|
||||
|
|
@ -9,6 +9,9 @@
|
|||
#define __need_size_t
|
||||
#include <stddef.h>
|
||||
|
||||
/* include any machine-specific extensions */
|
||||
#include <machine/malloc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
|
@ -17,7 +17,7 @@ extern "C" {
|
|||
#include <stddef.h>
|
||||
|
||||
#include <sys/reent.h>
|
||||
|
||||
#include <machine/stdlib.h>
|
||||
#ifndef __STRICT_ANSI__
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
|
|
@ -7,6 +7,19 @@ INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
|
|||
noinst_LIBRARIES = lib.a
|
||||
|
||||
lib_a_SOURCES = setjmp.S
|
||||
lib_a_LIBADD = @extra_objs@
|
||||
EXTRA_lib_a_SOURCES = @extra_sources@
|
||||
lib_a_DEPENDENCIES = @extra_objs@
|
||||
|
||||
ACLOCAL_AMFLAGS = -I ../../..
|
||||
AM_CFLAGS = -I $(srcdir)/../../stdio
|
||||
CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host
|
||||
|
||||
VEC_MALLOC_COMPILE = $(COMPILE) -DINTERNAL_NEWLIB
|
||||
|
||||
vec_reallocr.o: vec_mallocr.c
|
||||
$(VEC_MALLOC_COMPILE) -DDEFINE_VECREALLOC -c $(srcdir)/vec_mallocr.c -o $@
|
||||
|
||||
vec_callocr.o: vec_mallocr.c
|
||||
$(VEC_MALLOC_COMPILE) -DDEFINE_VECCALLOC -c $(srcdir)/vec_mallocr.c -o $@
|
||||
|
||||
|
|
|
@ -72,6 +72,8 @@ PACKAGE = @PACKAGE@
|
|||
RANLIB = @RANLIB@
|
||||
VERSION = @VERSION@
|
||||
aext = @aext@
|
||||
extra_objs = @extra_objs@
|
||||
extra_sources = @extra_sources@
|
||||
libm_machine_dir = @libm_machine_dir@
|
||||
machine_dir = @machine_dir@
|
||||
newlib_basedir = @newlib_basedir@
|
||||
|
@ -85,9 +87,15 @@ INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
|
|||
noinst_LIBRARIES = lib.a
|
||||
|
||||
lib_a_SOURCES = setjmp.S
|
||||
lib_a_LIBADD = @extra_objs@
|
||||
EXTRA_lib_a_SOURCES = @extra_sources@
|
||||
lib_a_DEPENDENCIES = @extra_objs@
|
||||
|
||||
ACLOCAL_AMFLAGS = -I ../../..
|
||||
AM_CFLAGS = -I $(srcdir)/../../stdio
|
||||
CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host
|
||||
|
||||
VEC_MALLOC_COMPILE = $(COMPILE) -DINTERNAL_NEWLIB
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../mkinstalldirs
|
||||
CONFIG_CLEAN_FILES =
|
||||
|
@ -97,7 +105,6 @@ LIBRARIES = $(noinst_LIBRARIES)
|
|||
DEFS = @DEFS@ -I. -I$(srcdir)
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
LIBS = @LIBS@
|
||||
lib_a_LIBADD =
|
||||
lib_a_OBJECTS = setjmp.o
|
||||
CFLAGS = @CFLAGS@
|
||||
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
|
@ -110,7 +117,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
|||
|
||||
TAR = gtar
|
||||
GZIP_ENV = --best
|
||||
SOURCES = $(lib_a_SOURCES)
|
||||
SOURCES = $(lib_a_SOURCES) $(EXTRA_lib_a_SOURCES)
|
||||
OBJECTS = $(lib_a_OBJECTS)
|
||||
|
||||
all: all-redirect
|
||||
|
@ -316,6 +323,12 @@ mostlyclean-generic distclean-generic clean-generic \
|
|||
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
|
||||
|
||||
|
||||
vec_reallocr.o: vec_mallocr.c
|
||||
$(VEC_MALLOC_COMPILE) -DDEFINE_VECREALLOC -c $(srcdir)/vec_mallocr.c -o $@
|
||||
|
||||
vec_callocr.o: vec_mallocr.c
|
||||
$(VEC_MALLOC_COMPILE) -DDEFINE_VECCALLOC -c $(srcdir)/vec_mallocr.c -o $@
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
|
|
|
@ -1440,6 +1440,17 @@ fi
|
|||
|
||||
|
||||
|
||||
extra_objs=
|
||||
extra_sources=
|
||||
case $host in
|
||||
powerpc*-*altivec*)
|
||||
extra_objs="vfprintf.o vfscanf.o vec_malloc.o vec_calloc.o vec_free.o vec_realloc.o vec_reallocr.o vec_callocr.o"
|
||||
extra_sources="vfprintf.c vfscanf.c vec_malloc.c vec_calloc.c vec_free.c vec_realloc.c vec_mallocr.c"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
|
||||
trap '' 1 2 15
|
||||
cat > confcache <<\EOF
|
||||
# This file is a shell script that caches the results of configure
|
||||
|
@ -1623,6 +1634,8 @@ s%@aext@%$aext%g
|
|||
s%@libm_machine_dir@%$libm_machine_dir%g
|
||||
s%@machine_dir@%$machine_dir%g
|
||||
s%@sys_dir@%$sys_dir%g
|
||||
s%@extra_objs@%$extra_objs%g
|
||||
s%@extra_sources@%$extra_sources%g
|
||||
|
||||
CEOF
|
||||
EOF
|
||||
|
|
|
@ -9,4 +9,15 @@ AC_CONFIG_AUX_DIR(../../../..)
|
|||
|
||||
NEWLIB_CONFIGURE(../../..)
|
||||
|
||||
extra_objs=
|
||||
extra_sources=
|
||||
case $host in
|
||||
powerpc*-*altivec*)
|
||||
extra_objs="vfprintf.o vfscanf.o vec_malloc.o vec_calloc.o vec_free.o vec_realloc.o vec_reallocr.o vec_callocr.o"
|
||||
extra_sources="vfprintf.c vfscanf.c vec_malloc.c vec_calloc.c vec_free.c vec_realloc.c vec_mallocr.c"
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(extra_objs)
|
||||
AC_SUBST(extra_sources)
|
||||
|
||||
AC_OUTPUT(Makefile)
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef _MACHMALLOC_H_
|
||||
#define _MACHMALLOC_H_
|
||||
|
||||
# if defined(__ALTIVEC__)
|
||||
|
||||
_PTR _EXFUN(vec_calloc,(size_t __nmemb, size_t __size));
|
||||
_PTR _EXFUN(_vec_calloc_r,(struct _reent *, size_t __nmemb, size_t __size));
|
||||
_VOID _EXFUN(vec_free,(_PTR));
|
||||
#define _vec_freer _freer
|
||||
_PTR _EXFUN(vec_malloc,(size_t __size));
|
||||
#define _vec_mallocr _memalign_r
|
||||
_PTR _EXFUN(vec_realloc,(_PTR __r, size_t __size));
|
||||
_PTR _EXFUN(_vec_realloc_r,(struct _reent *, _PTR __r, size_t __size));
|
||||
|
||||
# endif /* __ALTIVEC__ */
|
||||
|
||||
|
||||
#endif /* _MACHMALLOC_H_ */
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef _MACHSTDLIB_H_
|
||||
#define _MACHSTDLIB_H_
|
||||
|
||||
#ifndef __STRICT_ANSI__
|
||||
|
||||
# if defined(__ALTIVEC__)
|
||||
|
||||
_PTR _EXFUN(vec_calloc,(size_t __nmemb, size_t __size));
|
||||
_PTR _EXFUN(_vec_calloc_r,(struct _reent *, size_t __nmemb, size_t __size));
|
||||
_VOID _EXFUN(vec_free,(_PTR));
|
||||
#define _vec_freer _freer
|
||||
_PTR _EXFUN(vec_malloc,(size_t __size));
|
||||
#define _vec_mallocr _memalign_r
|
||||
_PTR _EXFUN(vec_realloc,(_PTR __r, size_t __size));
|
||||
_PTR _EXFUN(_vec_realloc_r,(struct _reent *, _PTR __r, size_t __size));
|
||||
|
||||
# endif /* __ALTIVEC__ */
|
||||
|
||||
#endif /* !__STRICT_ANSI__ */
|
||||
|
||||
|
||||
#endif /* _MACHSTDLIB_H_ */
|
||||
|
||||
|
|
@ -1,11 +1,17 @@
|
|||
/* This is a simple version of setjmp and longjmp for the PowerPC.
|
||||
Ian Lance Taylor, Cygnus Support, 9 Feb 1994. */
|
||||
Ian Lance Taylor, Cygnus Support, 9 Feb 1994.
|
||||
Modified by Jeff Johnston, Red Hat Inc. 2 Oct 2001. */
|
||||
|
||||
#include "ppc-asm.h"
|
||||
|
||||
FUNC_START(setjmp)
|
||||
#ifdef __ALTIVEC__
|
||||
addi 3,3,15 # align Altivec to 16 byte boundary
|
||||
rlwinm 3,3,0,0,27
|
||||
#else
|
||||
addi 3,3,7 # align to 8 byte boundary
|
||||
rlwinm 3,3,0,0,28
|
||||
#endif
|
||||
stw 1,0(3) # offset 0
|
||||
stwu 2,4(3) # offset 4
|
||||
stwu 13,4(3) # offset 8
|
||||
|
@ -56,14 +62,50 @@ FUNC_START(setjmp)
|
|||
/* This requires a total of 21 * 4 + 18 * 8 + 4 + 4 + 4
|
||||
bytes == 60 * 4 bytes == 240 bytes. */
|
||||
|
||||
#ifdef __ALTIVEC__
|
||||
/* save Altivec vrsave and vr20-vr31 registers */
|
||||
mfspr 4,256 # vrsave register
|
||||
stwu 4,16(3) # offset 248
|
||||
addi 3,3,8
|
||||
stvx 20,0,3 # offset 256
|
||||
addi 3,3,16
|
||||
stvx 21,0,3 # offset 272
|
||||
addi 3,3,16
|
||||
stvx 22,0,3 # offset 288
|
||||
addi 3,3,16
|
||||
stvx 23,0,3 # offset 304
|
||||
addi 3,3,16
|
||||
stvx 24,0,3 # offset 320
|
||||
addi 3,3,16
|
||||
stvx 25,0,3 # offset 336
|
||||
addi 3,3,16
|
||||
stvx 26,0,3 # offset 352
|
||||
addi 3,3,16
|
||||
stvx 27,0,3 # offset 368
|
||||
addi 3,3,16
|
||||
stvx 28,0,3 # offset 384
|
||||
addi 3,3,16
|
||||
stvx 29,0,3 # offset 400
|
||||
addi 3,3,16
|
||||
stvx 30,0,3 # offset 416
|
||||
addi 3,3,16
|
||||
stvx 31,0,3 # offset 432
|
||||
|
||||
/* This requires a total of 240 + 8 + 8 + 12 * 16 == 448 bytes. */
|
||||
#endif
|
||||
li 3,0
|
||||
blr
|
||||
FUNC_END(setjmp)
|
||||
|
||||
|
||||
FUNC_START(longjmp)
|
||||
#ifdef __ALTIVEC__
|
||||
addi 3,3,15 # align Altivec to 16 byte boundary
|
||||
rlwinm 3,3,0,0,27
|
||||
#else
|
||||
addi 3,3,7 # align to 8 byte boundary
|
||||
rlwinm 3,3,0,0,28
|
||||
#endif
|
||||
lwz 1,0(3) # offset 0
|
||||
lwzu 2,4(3) # offset 4
|
||||
lwzu 13,4(3) # offset 8
|
||||
|
@ -111,6 +153,36 @@ FUNC_START(longjmp)
|
|||
lfdu 31,8(3) # offset 232
|
||||
#endif
|
||||
|
||||
#ifdef __ALTIVEC__
|
||||
/* restore Altivec vrsave and v20-v31 registers */
|
||||
lwzu 5,16(3) # offset 248
|
||||
mtspr 256,5 # vrsave
|
||||
addi 3,3,8
|
||||
lvx 20,0,3 # offset 256
|
||||
addi 3,3,16
|
||||
lvx 21,0,3 # offset 272
|
||||
addi 3,3,16
|
||||
lvx 22,0,3 # offset 288
|
||||
addi 3,3,16
|
||||
lvx 23,0,3 # offset 304
|
||||
addi 3,3,16
|
||||
lvx 24,0,3 # offset 320
|
||||
addi 3,3,16
|
||||
lvx 25,0,3 # offset 336
|
||||
addi 3,3,16
|
||||
lvx 26,0,3 # offset 352
|
||||
addi 3,3,16
|
||||
lvx 27,0,3 # offset 368
|
||||
addi 3,3,16
|
||||
lvx 28,0,3 # offset 384
|
||||
addi 3,3,16
|
||||
lvx 29,0,3 # offset 400
|
||||
addi 3,3,16
|
||||
lvx 30,0,3 # offset 416
|
||||
addi 3,3,16
|
||||
lvx 31,0,3 # offset 432
|
||||
#endif
|
||||
|
||||
mr. 3,4
|
||||
bclr+ 4,2
|
||||
li 3,1
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
FUNCTION
|
||||
<<vec_calloc>>---allocate space for arrays
|
||||
|
||||
INDEX
|
||||
vec_calloc
|
||||
|
||||
INDEX
|
||||
_vec_calloc_r
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdlib.h>
|
||||
void *vec_calloc(size_t <[n]>, size_t <[s]>);
|
||||
void *vec_calloc_r(void *<[reent]>, size_t <n>, <size_t> <[s]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdlib.h>
|
||||
char *vec_calloc(<[n]>, <[s]>)
|
||||
size_t <[n]>, <[s]>;
|
||||
|
||||
char *_vec_calloc_r(<[reent]>, <[n]>, <[s]>)
|
||||
char *<[reent]>;
|
||||
size_t <[n]>;
|
||||
size_t <[s]>;
|
||||
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
Use <<vec_calloc>> to request a block of memory sufficient to hold an
|
||||
array of <[n]> elements, each of which has size <[s]>.
|
||||
|
||||
The memory allocated by <<vec_calloc>> comes out of the same memory pool
|
||||
used by <<vec_malloc>>, but the memory block is initialized to all zero
|
||||
bytes. (To avoid the overhead of initializing the space, use
|
||||
<<vec_malloc>> instead.)
|
||||
|
||||
The alternate function <<_vec_calloc_r>> is reentrant.
|
||||
The extra argument <[reent]> is a pointer to a reentrancy structure.
|
||||
|
||||
RETURNS
|
||||
If successful, a pointer to the newly allocated space.
|
||||
|
||||
If unsuccessful, <<NULL>>.
|
||||
|
||||
PORTABILITY
|
||||
<<vec_calloc>> is an non-ANSI extension described in the AltiVec Programming
|
||||
Interface Manual.
|
||||
|
||||
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
|
||||
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
|
||||
_PTR
|
||||
_DEFUN (vec_calloc, (n, size),
|
||||
size_t n _AND
|
||||
size_t size)
|
||||
{
|
||||
return _vec_calloc_r (_REENT, n, size);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,15 @@
|
|||
/* vec_free.c - a wrapper for _free_r */
|
||||
#include <_ansi.h>
|
||||
#include <reent.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
|
||||
void
|
||||
_DEFUN (vec_free, (aptr),
|
||||
_PTR aptr)
|
||||
{
|
||||
_free_r (_REENT, aptr);
|
||||
}
|
||||
|
||||
#endif /* !_REENT_ONLY */
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
FUNCTION
|
||||
<<vec_malloc>>, <<vec_realloc>>, <<vec_free>>---manage vector memory
|
||||
|
||||
INDEX
|
||||
vec_malloc
|
||||
INDEX
|
||||
vec_realloc
|
||||
INDEX
|
||||
vec_free
|
||||
INDEX
|
||||
_vec_malloc_r
|
||||
INDEX
|
||||
_vec_realloc_r
|
||||
INDEX
|
||||
_vec_free_r
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdlib.h>
|
||||
void *vec_malloc(size_t <[nbytes]>);
|
||||
void *vec_realloc(void *<[aptr]>, size_t <[nbytes]>);
|
||||
void vec_free(void *<[aptr]>);
|
||||
|
||||
|
||||
void *_vec_malloc_r(void *<[reent]>, size_t <[nbytes]>);
|
||||
void *_vec_realloc_r(void *<[reent]>,
|
||||
void *<[aptr]>, size_t <[nbytes]>);
|
||||
void _vec_free_r(void *<[reent]>, void *<[aptr]>);
|
||||
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdlib.h>
|
||||
char *vec_malloc(<[nbytes]>)
|
||||
size_t <[nbytes]>;
|
||||
|
||||
char *vec_realloc(<[aptr]>, <[nbytes]>)
|
||||
char *<[aptr]>;
|
||||
size_t <[nbytes]>;
|
||||
|
||||
void vec_free(<[aptr]>)
|
||||
char *<[aptr]>;
|
||||
|
||||
char *_vec_malloc_r(<[reent]>,<[nbytes]>)
|
||||
char *<[reent]>;
|
||||
size_t <[nbytes]>;
|
||||
|
||||
char *_vec_realloc_r(<[reent]>, <[aptr]>, <[nbytes]>)
|
||||
char *<[reent]>;
|
||||
char *<[aptr]>;
|
||||
size_t <[nbytes]>;
|
||||
|
||||
void _vec_free_r(<[reent]>, <[aptr]>)
|
||||
char *<[reent]>;
|
||||
char *<[aptr]>;
|
||||
|
||||
DESCRIPTION
|
||||
These functions manage a pool of system memory that is 16-byte aligned..
|
||||
|
||||
Use <<vec_malloc>> to request allocation of an object with at least
|
||||
<[nbytes]> bytes of storage available and is 16-byte aligned. If the space is
|
||||
available, <<vec_malloc>> returns a pointer to a newly allocated block as its result.
|
||||
|
||||
If you already have a block of storage allocated by <<vec_malloc>>, but
|
||||
you no longer need all the space allocated to it, you can make it
|
||||
smaller by calling <<vec_realloc>> with both the object pointer and the
|
||||
new desired size as arguments. <<vec_realloc>> guarantees that the
|
||||
contents of the smaller object match the beginning of the original object.
|
||||
|
||||
Similarly, if you need more space for an object, use <<vec_realloc>> to
|
||||
request the larger size; again, <<vec_realloc>> guarantees that the
|
||||
beginning of the new, larger object matches the contents of the
|
||||
original object.
|
||||
|
||||
When you no longer need an object originally allocated by <<vec_malloc>>
|
||||
or <<vec_realloc>> (or the related function <<vec_calloc>>), return it to the
|
||||
memory storage pool by calling <<vec_free>> with the address of the object
|
||||
as the argument. You can also use <<vec_realloc>> for this purpose by
|
||||
calling it with <<0>> as the <[nbytes]> argument.
|
||||
|
||||
The alternate functions <<_vec_malloc_r>>, <<_vec_realloc_r>>, <<_vec_free_r>>,
|
||||
are reentrant versions. The extra argument <[reent]> is a pointer to a reentrancy
|
||||
structure.
|
||||
|
||||
If you have multiple threads of execution which may call any of these
|
||||
routines, or if any of these routines may be called reentrantly, then
|
||||
you must provide implementations of the <<__vec_malloc_lock>> and
|
||||
<<__vec_malloc_unlock>> functions for your system. See the documentation
|
||||
for those functions.
|
||||
|
||||
These functions operate by calling the function <<_sbrk_r>> or
|
||||
<<sbrk>>, which allocates space. You may need to provide one of these
|
||||
functions for your system. <<_sbrk_r>> is called with a positive
|
||||
value to allocate more space, and with a negative value to release
|
||||
previously allocated space if it is no longer required.
|
||||
@xref{Stubs}.
|
||||
|
||||
RETURNS
|
||||
<<vec_malloc>> returns a pointer to the newly allocated space, if
|
||||
successful; otherwise it returns <<NULL>>. If your application needs
|
||||
to generate empty objects, you may use <<vec_malloc(0)>> for this purpose.
|
||||
|
||||
<<vec_realloc>> returns a pointer to the new block of memory, or <<NULL>>
|
||||
if a new block could not be allocated. <<NULL>> is also the result
|
||||
when you use `<<vec_realloc(<[aptr]>,0)>>' (which has the same effect as
|
||||
`<<vec_free(<[aptr]>)>>'). You should always check the result of
|
||||
<<vec_realloc>>; successful vec_reallocation is not guaranteed even when
|
||||
you request a smaller object.
|
||||
|
||||
<<vec_free>> does not return a result.
|
||||
|
||||
PORTABILITY
|
||||
<<vec_malloc>>, <<vec_realloc>>, and <<vec_free>> are all extensions
|
||||
specified in the AltiVec Programming Interface Manual.
|
||||
|
||||
Supporting OS subroutines required: <<sbrk>>. */
|
||||
|
||||
#include <_ansi.h>
|
||||
#include <reent.h>
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
|
||||
_PTR
|
||||
_DEFUN (vec_malloc, (nbytes),
|
||||
size_t nbytes) /* get a block */
|
||||
{
|
||||
return _memalign_r (_REENT, 16, nbytes);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,424 @@
|
|||
/* This code is based on mallocr.c written by Doug Lea which is released
|
||||
to the public domain. Any changes to libc/stdlib/mallocr.c
|
||||
should be reflected here as well. */
|
||||
|
||||
/* Preliminaries */
|
||||
|
||||
#ifndef __STD_C
|
||||
#ifdef __STDC__
|
||||
#define __STD_C 1
|
||||
#else
|
||||
#if __cplusplus
|
||||
#define __STD_C 1
|
||||
#else
|
||||
#define __STD_C 0
|
||||
#endif /*__cplusplus*/
|
||||
#endif /*__STDC__*/
|
||||
#endif /*__STD_C*/
|
||||
|
||||
#ifndef Void_t
|
||||
#if __STD_C
|
||||
#define Void_t void
|
||||
#else
|
||||
#define Void_t char
|
||||
#endif
|
||||
#endif /*Void_t*/
|
||||
|
||||
#if __STD_C
|
||||
#include <stddef.h> /* for size_t */
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/config.h>
|
||||
|
||||
/*
|
||||
In newlib, all the publically visible routines take a reentrancy
|
||||
pointer. We don't currently do anything much with it, but we do
|
||||
pass it to the lock routine.
|
||||
*/
|
||||
|
||||
#include <reent.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#define MALLOC_LOCK __malloc_lock(reent_ptr)
|
||||
#define MALLOC_UNLOCK __malloc_unlock(reent_ptr)
|
||||
|
||||
#ifdef SMALL_MEMORY
|
||||
#define malloc_getpagesize (128)
|
||||
#else
|
||||
#define malloc_getpagesize (4096)
|
||||
#endif
|
||||
|
||||
#if __STD_C
|
||||
extern void __malloc_lock(struct _reent *);
|
||||
extern void __malloc_unlock(struct _reent *);
|
||||
#else
|
||||
extern void __malloc_lock();
|
||||
extern void __malloc_unlock();
|
||||
#endif
|
||||
|
||||
#if __STD_C
|
||||
#define RARG struct _reent *reent_ptr,
|
||||
#define RONEARG struct _reent *reent_ptr
|
||||
#else
|
||||
#define RARG reent_ptr
|
||||
#define RONEARG reent_ptr
|
||||
#define RDECL struct _reent *reent_ptr;
|
||||
#endif
|
||||
|
||||
#define RCALL reent_ptr,
|
||||
#define RONECALL reent_ptr
|
||||
|
||||
/*
|
||||
Define MALLOC_LOCK and MALLOC_UNLOCK to C expressions to run to
|
||||
lock and unlock the malloc data structures. MALLOC_LOCK may be
|
||||
called recursively.
|
||||
*/
|
||||
|
||||
#ifndef MALLOC_LOCK
|
||||
#define MALLOC_LOCK
|
||||
#endif
|
||||
|
||||
#ifndef MALLOC_UNLOCK
|
||||
#define MALLOC_UNLOCK
|
||||
#endif
|
||||
|
||||
/*
|
||||
INTERNAL_SIZE_T is the word-size used for internal bookkeeping
|
||||
of chunk sizes. On a 64-bit machine, you can reduce malloc
|
||||
overhead by defining INTERNAL_SIZE_T to be a 32 bit `unsigned int'
|
||||
at the expense of not being able to handle requests greater than
|
||||
2^31. This limitation is hardly ever a concern; you are encouraged
|
||||
to set this. However, the default version is the same as size_t.
|
||||
*/
|
||||
|
||||
#ifndef INTERNAL_SIZE_T
|
||||
#define INTERNAL_SIZE_T size_t
|
||||
#endif
|
||||
|
||||
/*
|
||||
Following is needed on implementations whereby long > size_t.
|
||||
The problem is caused because the code performs subtractions of
|
||||
size_t values and stores the result in long values. In the case
|
||||
where long > size_t and the first value is actually less than
|
||||
the second value, the resultant value is positive. For example,
|
||||
(long)(x - y) where x = 0 and y is 1 ends up being 0x00000000FFFFFFFF
|
||||
which is 2*31 - 1 instead of 0xFFFFFFFFFFFFFFFF. This is due to the
|
||||
fact that assignment from unsigned to signed won't sign extend.
|
||||
*/
|
||||
|
||||
#ifdef SIZE_T_SMALLER_THAN_LONG
|
||||
#define long_sub_size_t(x, y) ( (x < y) ? -((long)(y - x)) : (x - y) );
|
||||
#else
|
||||
#define long_sub_size_t(x, y) ( (long)(x - y) )
|
||||
#endif
|
||||
|
||||
/*
|
||||
REALLOC_ZERO_BYTES_FREES should be set if a call to
|
||||
realloc with zero bytes should be the same as a call to free.
|
||||
Some people think it should. Otherwise, since this malloc
|
||||
returns a unique pointer for malloc(0), so does realloc(p, 0).
|
||||
*/
|
||||
|
||||
/* The following macros are only invoked with (2n+1)-multiples of
|
||||
INTERNAL_SIZE_T units, with a positive integer n. This is exploited
|
||||
for fast inline execution when n is small. */
|
||||
|
||||
#define MALLOC_ZERO(charp, nbytes) \
|
||||
do { \
|
||||
INTERNAL_SIZE_T mzsz = (nbytes); \
|
||||
if(mzsz <= 9*sizeof(mzsz)) { \
|
||||
INTERNAL_SIZE_T* mz = (INTERNAL_SIZE_T*) (charp); \
|
||||
if(mzsz >= 5*sizeof(mzsz)) { *mz++ = 0; \
|
||||
*mz++ = 0; \
|
||||
if(mzsz >= 7*sizeof(mzsz)) { *mz++ = 0; \
|
||||
*mz++ = 0; \
|
||||
if(mzsz >= 9*sizeof(mzsz)) { *mz++ = 0; \
|
||||
*mz++ = 0; }}} \
|
||||
*mz++ = 0; \
|
||||
*mz++ = 0; \
|
||||
*mz = 0; \
|
||||
} else memset((charp), 0, mzsz); \
|
||||
} while(0)
|
||||
|
||||
#define MALLOC_COPY(dest,src,nbytes) \
|
||||
do { \
|
||||
INTERNAL_SIZE_T mcsz = (nbytes); \
|
||||
if(mcsz <= 9*sizeof(mcsz)) { \
|
||||
INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) (src); \
|
||||
INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) (dest); \
|
||||
if(mcsz >= 5*sizeof(mcsz)) { *mcdst++ = *mcsrc++; \
|
||||
*mcdst++ = *mcsrc++; \
|
||||
if(mcsz >= 7*sizeof(mcsz)) { *mcdst++ = *mcsrc++; \
|
||||
*mcdst++ = *mcsrc++; \
|
||||
if(mcsz >= 9*sizeof(mcsz)) { *mcdst++ = *mcsrc++; \
|
||||
*mcdst++ = *mcsrc++; }}} \
|
||||
*mcdst++ = *mcsrc++; \
|
||||
*mcdst++ = *mcsrc++; \
|
||||
*mcdst = *mcsrc ; \
|
||||
} else memcpy(dest, src, mcsz); \
|
||||
} while(0)
|
||||
|
||||
#define vECCALLOc _vec_calloc_r
|
||||
#define fREe _free_r
|
||||
#define mEMALIGn _memalign_r
|
||||
#define vECREALLOc _vec_realloc_r
|
||||
#
|
||||
#if __STD_C
|
||||
|
||||
Void_t* vECREALLOc(RARG Void_t*, size_t);
|
||||
Void_t* vECCALLOc(RARG size_t, size_t);
|
||||
#else
|
||||
Void_t* vECREALLOc();
|
||||
Void_t* vECCALLOc();
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}; /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
/*
|
||||
Type declarations
|
||||
*/
|
||||
|
||||
struct malloc_chunk
|
||||
{
|
||||
INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */
|
||||
INTERNAL_SIZE_T size; /* Size in bytes, including overhead. */
|
||||
struct malloc_chunk* fd; /* double links -- used only if free. */
|
||||
struct malloc_chunk* bk;
|
||||
};
|
||||
|
||||
typedef struct malloc_chunk* mchunkptr;
|
||||
|
||||
/* sizes, alignments */
|
||||
|
||||
#define SIZE_SZ (sizeof(INTERNAL_SIZE_T))
|
||||
#define MALLOC_ALIGN 16
|
||||
#define MALLOC_ALIGNMENT 16
|
||||
#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1)
|
||||
#define MINSIZE (sizeof(struct malloc_chunk))
|
||||
|
||||
/* conversion from malloc headers to user pointers, and back */
|
||||
|
||||
#define chunk2mem(p) ((Void_t*)((char*)(p) + 2*SIZE_SZ))
|
||||
#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*SIZE_SZ))
|
||||
/* pad request bytes into a usable size */
|
||||
|
||||
#define request2size(req) \
|
||||
(((long)((req) + (SIZE_SZ + MALLOC_ALIGN_MASK)) < \
|
||||
(long)(MINSIZE + MALLOC_ALIGN_MASK)) ? ((MINSIZE + MALLOC_ALIGN_MASK) & ~(MALLOC_ALIGN_MASK)) : \
|
||||
(((req) + (SIZE_SZ + MALLOC_ALIGN_MASK)) & ~(MALLOC_ALIGN_MASK)))
|
||||
|
||||
|
||||
/* Check if m has acceptable alignment */
|
||||
|
||||
#define aligned_OK(m) (((unsigned long)((m)) & (MALLOC_ALIGN_MASK)) == 0)
|
||||
|
||||
/*
|
||||
Physical chunk operations
|
||||
*/
|
||||
|
||||
|
||||
/* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */
|
||||
|
||||
#define PREV_INUSE 0x1
|
||||
|
||||
/* size field is or'ed with IS_MMAPPED if the chunk was obtained with mmap() */
|
||||
|
||||
#define IS_MMAPPED 0x2
|
||||
|
||||
/* Bits to mask off when extracting size */
|
||||
|
||||
#define SIZE_BITS (PREV_INUSE|IS_MMAPPED)
|
||||
|
||||
|
||||
/* Ptr to next physical malloc_chunk. */
|
||||
|
||||
#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->size & ~PREV_INUSE) ))
|
||||
|
||||
/* Ptr to previous physical malloc_chunk */
|
||||
|
||||
#define prev_chunk(p)\
|
||||
((mchunkptr)( ((char*)(p)) - ((p)->prev_size) ))
|
||||
|
||||
|
||||
/* Treat space at ptr + offset as a chunk */
|
||||
|
||||
#define chunk_at_offset(p, s) ((mchunkptr)(((char*)(p)) + (s)))
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Dealing with use bits
|
||||
*/
|
||||
|
||||
/* extract p's inuse bit */
|
||||
|
||||
#define inuse(p)\
|
||||
((((mchunkptr)(((char*)(p))+((p)->size & ~PREV_INUSE)))->size) & PREV_INUSE)
|
||||
|
||||
/* extract inuse bit of previous chunk */
|
||||
|
||||
#define prev_inuse(p) ((p)->size & PREV_INUSE)
|
||||
|
||||
/* check for mmap()'ed chunk */
|
||||
|
||||
#define chunk_is_mmapped(p) ((p)->size & IS_MMAPPED)
|
||||
|
||||
/* set/clear chunk as in use without otherwise disturbing */
|
||||
|
||||
#define set_inuse(p)\
|
||||
((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size |= PREV_INUSE
|
||||
|
||||
#define clear_inuse(p)\
|
||||
((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size &= ~(PREV_INUSE)
|
||||
|
||||
/* check/set/clear inuse bits in known places */
|
||||
|
||||
#define inuse_bit_at_offset(p, s)\
|
||||
(((mchunkptr)(((char*)(p)) + (s)))->size & PREV_INUSE)
|
||||
|
||||
#define set_inuse_bit_at_offset(p, s)\
|
||||
(((mchunkptr)(((char*)(p)) + (s)))->size |= PREV_INUSE)
|
||||
|
||||
#define clear_inuse_bit_at_offset(p, s)\
|
||||
(((mchunkptr)(((char*)(p)) + (s)))->size &= ~(PREV_INUSE))
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Dealing with size fields
|
||||
*/
|
||||
|
||||
/* Get size, ignoring use bits */
|
||||
|
||||
#define chunksize(p) ((p)->size & ~(SIZE_BITS))
|
||||
|
||||
/* Set size at head, without disturbing its use bit */
|
||||
|
||||
#define set_head_size(p, s) ((p)->size = (((p)->size & PREV_INUSE) | (s)))
|
||||
|
||||
/* Set size/use ignoring previous bits in header */
|
||||
|
||||
#define set_head(p, s) ((p)->size = (s))
|
||||
|
||||
|
||||
|
||||
#ifdef DEFINE_VECREALLOC
|
||||
|
||||
|
||||
#if __STD_C
|
||||
Void_t* vECREALLOc(RARG Void_t* oldmem, size_t bytes)
|
||||
#else
|
||||
Void_t* vECREALLOc(RARG oldmem, bytes) RDECL Void_t* oldmem; size_t bytes;
|
||||
#endif
|
||||
{
|
||||
INTERNAL_SIZE_T nb; /* padded request size */
|
||||
|
||||
mchunkptr oldp; /* chunk corresponding to oldmem */
|
||||
INTERNAL_SIZE_T oldsize; /* its size */
|
||||
|
||||
mchunkptr newp; /* chunk to return */
|
||||
INTERNAL_SIZE_T newsize; /* its size */
|
||||
Void_t* newmem; /* corresponding user mem */
|
||||
|
||||
mchunkptr remainder; /* holds split off extra space from newp */
|
||||
INTERNAL_SIZE_T remainder_size; /* its size */
|
||||
|
||||
#ifdef REALLOC_ZERO_BYTES_FREES
|
||||
if (bytes == 0) { fREe(RCALL oldmem); return 0; }
|
||||
#endif
|
||||
|
||||
|
||||
/* realloc of null is supposed to be same as malloc */
|
||||
if (oldmem == 0) return mEMALIGn(RCALL 16, bytes);
|
||||
|
||||
MALLOC_LOCK;
|
||||
|
||||
newp = oldp = mem2chunk(oldmem);
|
||||
newsize = oldsize = chunksize(oldp);
|
||||
|
||||
nb = request2size(bytes);
|
||||
|
||||
if ((long)(oldsize) < (long)(nb))
|
||||
{
|
||||
/* Must allocate */
|
||||
|
||||
newmem = mEMALIGn (RCALL 16, bytes);
|
||||
|
||||
if (newmem == 0) /* propagate failure */
|
||||
{
|
||||
MALLOC_UNLOCK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* copy, free, and exit */
|
||||
MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
|
||||
fREe(RCALL oldmem);
|
||||
MALLOC_UNLOCK;
|
||||
return newmem;
|
||||
}
|
||||
|
||||
remainder_size = long_sub_size_t(newsize, nb);
|
||||
|
||||
if (remainder_size >= (long)MINSIZE) /* split off remainder */
|
||||
{
|
||||
remainder = chunk_at_offset(newp, nb);
|
||||
set_head_size(newp, nb);
|
||||
set_head(remainder, remainder_size | PREV_INUSE);
|
||||
set_inuse_bit_at_offset(remainder, remainder_size);
|
||||
fREe(RCALL chunk2mem(remainder)); /* let free() deal with it */
|
||||
}
|
||||
else
|
||||
{
|
||||
set_head_size(newp, newsize);
|
||||
set_inuse_bit_at_offset(newp, newsize);
|
||||
}
|
||||
|
||||
MALLOC_UNLOCK;
|
||||
return chunk2mem(newp);
|
||||
}
|
||||
|
||||
#endif /* DEFINE_VECREALLOC */
|
||||
|
||||
|
||||
#ifdef DEFINE_VECCALLOC
|
||||
|
||||
/*
|
||||
|
||||
calloc calls malloc, then zeroes out the allocated chunk.
|
||||
|
||||
*/
|
||||
|
||||
#if __STD_C
|
||||
Void_t* vECCALLOc(RARG size_t n, size_t elem_size)
|
||||
#else
|
||||
Void_t* vECCALLOc(RARG n, elem_size) RDECL size_t n; size_t elem_size;
|
||||
#endif
|
||||
{
|
||||
INTERNAL_SIZE_T sz = n * elem_size;
|
||||
|
||||
Void_t* mem;
|
||||
|
||||
mem = mEMALIGn (RCALL 16, sz);
|
||||
|
||||
if (mem == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
MALLOC_ZERO(mem, sz);
|
||||
return mem;
|
||||
}
|
||||
|
||||
#endif /* DEFINE_VECCALLOC */
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/* vec_realloc.c -- a wrapper for _vec_realloc_r. */
|
||||
|
||||
#include <_ansi.h>
|
||||
#include <reent.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
|
||||
_PTR
|
||||
_DEFUN (vec_realloc, (ap, nbytes),
|
||||
_PTR ap _AND
|
||||
size_t nbytes)
|
||||
{
|
||||
return _vec_realloc_r (_REENT, ap, nbytes);
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue