From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5947 invoked by alias); 10 Jan 2004 20:31:45 -0000 Mailing-List: contact libc-hacker-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sources.redhat.com Received: (qmail 5931 invoked from network); 10 Jan 2004 20:31:45 -0000 Received: from unknown (HELO e1.ny.us.ibm.com) (32.97.182.101) by sources.redhat.com with SMTP; 10 Jan 2004 20:31:45 -0000 Received: from northrelay04.pok.ibm.com (northrelay04.pok.ibm.com [9.56.224.206]) by e1.ny.us.ibm.com (8.12.10/NS PXFA) with ESMTP id i0AKVeKc370726; Sat, 10 Jan 2004 15:31:41 -0500 Received: from us.ibm.com (d01av02.pok.ibm.com [9.56.224.216]) by northrelay04.pok.ibm.com (8.12.10/NCO/VER6.6) with ESMTP id i0AKVd4O123882; Sat, 10 Jan 2004 15:31:40 -0500 Message-ID: <40006121.9070903@us.ibm.com> Date: Sat, 10 Jan 2004 20:31:00 -0000 From: Steve Munroe Reply-To: sjmunroe@vnet.ibm.com Organization: IBM LTC User-Agent: Mozilla/5.0 (X11; U; Linux ppc64; en-US; rv:1.4) Gecko/20030922 MIME-Version: 1.0 To: libc-hacker@sources.redhat.com CC: Paul Mackerras , Benjamin Herrenschmidt Subject: [PATCH] PPC enable Alitvec hardware, part 1 Content-Type: multipart/mixed; boundary="------------080003020408080506040502" X-SW-Source: 2004-01/txt/msg00027.txt.bz2 This is a multi-part message in MIME format. --------------080003020408080506040502 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 524 The attached patch provides base enabling for PowerPC Altivec (AKA VMX) and for versioning effected functions. 2.6.0 kernels provide a PPC_FEATURE_HAS_ALTIVEC status in the AT_HWCAP. We need to capture this status as a static flag (__has_altivec) so functions enabled for altivec can run safely on PowerPC hardware without the Altivec feature. And now for the fun part. I think this requires a new glibc version because GLIBC_2.3.3 symbols are already defined for these (get/setcontext) functions in shipped distros. --------------080003020408080506040502 Content-Type: text/plain; name="ppcvmx-base-20040104.txt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ppcvmx-base-20040104.txt" Content-length: 11895 2004-01-09 Steven Munroe * elf/elf.h: Define PPC_FEATURE_* masks for Aux Vector AT_HWCAP. * include/libc-symbols.h [HAVE_ASM_GLOBAL_DOT_NAME] (_symbol_version): Use C_SYMBOL_DOT_NAME to create '.'ed symbols. (_default_symbol_version): Use C_SYMBOL_DOT_NAME to create '.'ed symbols. * sysdeps/powerpc/Versions: Add __has_altivec symbol for GLIBC_2.3.4. * sysdeps/powerpc/elf/libc-start.c [!SHARED]: Add extern for __has_altivec. (libc_start_main)[!SHARED]: Initialize __has_altivec from dl_hwcap. * sysdeps/powerpc/longjmp.c: New file. * sysdeps/powerpc/sysdep.h: Define v# symbols for vector registers. * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_ALTIVEC_SIGCONTEXT): Define for PPC and 2.6.0 kernels. * sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c (DL_PLATFORM_INIT): Initialize __has_altivec from dl_hwcap. * sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h [!__ASSUME_ALTIVEC_SIGCONTEXT]: Insure altivec state is defined in sigcontext for old kernels. diff -urN libc23-cvstip-20040102/elf/elf.h libc23/elf/elf.h --- libc23-cvstip-20040102/elf/elf.h 2003-12-29 12:50:21.000000000 -0600 +++ libc23/elf/elf.h 2004-01-07 14:25:55.000000000 -0600 @@ -1854,6 +1854,17 @@ #define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ #define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib flag */ +/* from linux/asm/cputable.h. */ +#define PPC_FEATURE_32 0x80000000 +#define PPC_FEATURE_64 0x40000000 +#define PPC_FEATURE_601_INSTR 0x20000000 +#define PPC_FEATURE_HAS_ALTIVEC 0x10000000 +#define PPC_FEATURE_HAS_FPU 0x08000000 +#define PPC_FEATURE_HAS_MMU 0x04000000 +#define PPC_FEATURE_HAS_4xxMAC 0x02000000 +#define PPC_FEATURE_UNIFIED_CACHE 0x01000000 + + /* PowerPC relocations defined by the ABIs */ #define R_PPC_NONE 0 diff -urN libc23-cvstip-20040102/include/libc-symbols.h libc23/include/libc-symbols.h --- libc23-cvstip-20040102/include/libc-symbols.h 2003-07-22 14:24:48.000000000 -0500 +++ libc23/include/libc-symbols.h 2004-01-07 14:25:55.000000000 -0600 @@ -420,10 +420,10 @@ # ifdef HAVE_ASM_GLOBAL_DOT_NAME # define _symbol_version(real, name, version) \ .symver real, name##@##version ASM_LINE_SEP \ - .symver .##real, .##name##@##version + .symver C_SYMBOL_DOT_NAME(real), C_SYMBOL_DOT_NAME(name##@##version) # define _default_symbol_version(real, name, version) \ .symver real, name##@##@##version ASM_LINE_SEP \ - .symver .##real, .##name##@##@##version + .symver C_SYMBOL_DOT_NAME(real), C_SYMBOL_DOT_NAME(name##@##@##version) # else # define _symbol_version(real, name, version) \ .symver real, name##@##version diff -urN libc23-cvstip-20040102/sysdeps/powerpc/Versions libc23/sysdeps/powerpc/Versions --- libc23-cvstip-20040102/sysdeps/powerpc/Versions 2002-09-05 04:54:59.000000000 -0500 +++ libc23/sysdeps/powerpc/Versions 2004-01-10 11:29:00.000000000 -0600 @@ -4,3 +4,9 @@ __fe_dfl_env; __fe_enabled_env; __fe_nonieee_env; __fe_nomask_env; } } + +ld { + GLIBC_2.3.4 { + __has_altivec; + } +} diff -urN libc23-cvstip-20040102/sysdeps/powerpc/elf/libc-start.c libc23/sysdeps/powerpc/elf/libc-start.c --- libc23-cvstip-20040102/sysdeps/powerpc/elf/libc-start.c 2003-03-15 17:09:18.000000000 -0600 +++ libc23/sysdeps/powerpc/elf/libc-start.c 2004-01-07 14:25:55.000000000 -0600 @@ -25,6 +25,10 @@ extern int __cache_line_size; weak_extern (__cache_line_size) +#ifndef SHARED +extern int __has_altivec; +#endif + /* Scan the Aux Vector for the "Data Cache Block Size" entry. If found verify that the static extern __cache_line_size is defined by checking for not NULL. If it is defined then assign the cache block size @@ -104,7 +108,9 @@ /* Initialize the __cache_line_size variable from the aux vector. */ __aux_init_cache (auxvec); - +#ifndef SHARED + __has_altivec=((GL(dl_hwcap) & PPC_FEATURE_HAS_ALTIVEC) ? 1:0); +#endif return generic_start_main (stinfo->main, argc, ubp_av, auxvec, stinfo->init, stinfo->fini, rtld_fini, stack_on_entry); diff -urN libc23-cvstip-20040102/sysdeps/powerpc/longjmp.c libc23/sysdeps/powerpc/longjmp.c --- libc23-cvstip-20040102/sysdeps/powerpc/longjmp.c Wed Dec 31 18:00:00 1969 +++ libc23/sysdeps/powerpc/longjmp.c Sat Jan 10 11:29:58 2004 @@ -0,0 +1,56 @@ +/* Copyright (C) 1991,92,94,95,97,98,2000,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ +/* + Versioned copy of sysdeps/generic/longjmp.c modified for altivec support. + */ +#include +#include +#include +#include + +#if defined(NOT_IN_libc) || !defined(SHARED) +/* We don't want this variable both in ld.so & libc.so as + we would then have duplicate variable linker confusion. */ +int vec__has_altivec=0; +default_symbol_version (vec__has_altivec,__has_altivec,GLIBC_2.3.4); +#endif + +/* Set the signal mask to the one specified in ENV, and jump + to the position specified in ENV, causing the setjmp + call there to return VAL, or 1 if VAL is 0. */ +void +__libc_siglongjmp (sigjmp_buf env, int val) +{ + /* Perform any cleanups needed by the frames being unwound. */ + _longjmp_unwind (env, val); + + if (env[0].__mask_was_saved) + /* Restore the saved signal mask. */ + (void) __sigprocmask (SIG_SETMASK, &env[0].__saved_mask, + (sigset_t *) NULL); + + /* Call the machine-dependent function to restore machine state. */ + __longjmp (env[0].__jmpbuf, val ?: 1); +} + +strong_alias (__libc_siglongjmp, __libc_longjmp) +libc_hidden_def (__libc_longjmp) +weak_alias (__libc_siglongjmp, _longjmp) +weak_alias (__libc_siglongjmp, longjmp) +weak_alias (__libc_siglongjmp, siglongjmp) + diff -urN libc23-cvstip-20040102/sysdeps/powerpc/sysdep.h libc23/sysdeps/powerpc/sysdep.h --- libc23-cvstip-20040102/sysdeps/powerpc/sysdep.h 2002-09-20 18:44:55.000000000 -0500 +++ libc23/sysdeps/powerpc/sysdep.h 2004-01-07 14:25:55.000000000 -0600 @@ -100,6 +100,42 @@ #define cr6 6 #define cr7 7 +/* Vector registers. */ +#define v0 0 +#define v1 1 +#define v2 2 +#define v3 3 +#define v4 4 +#define v5 5 +#define v6 6 +#define v7 7 +#define v8 8 +#define v9 9 +#define v10 10 +#define v11 11 +#define v12 12 +#define v13 13 +#define v14 14 +#define v15 15 +#define v16 16 +#define v17 17 +#define v18 18 +#define v19 19 +#define v20 20 +#define v21 21 +#define v22 22 +#define v23 23 +#define v24 24 +#define v25 25 +#define v26 26 +#define v27 27 +#define v28 28 +#define v29 29 +#define v30 30 +#define v31 31 + +#define VRSAVE 256 + #ifdef __ELF__ diff -urN libc23-cvstip-20040102/sysdeps/unix/sysv/linux/kernel-features.h libc23/sysdeps/unix/sysv/linux/kernel-features.h --- libc23-cvstip-20040102/sysdeps/unix/sysv/linux/kernel-features.h 2003-12-11 22:31:39.000000000 -0600 +++ libc23/sysdeps/unix/sysv/linux/kernel-features.h 2004-01-09 19:38:30.000000000 -0600 @@ -247,6 +247,15 @@ # define __ASSUME_NEW_RT_SIGRETURN_SYSCALL 1 #endif +/* Starting with 2.6.0 PowerPC adds signal/swapcontext support for Vector + SIMD (AKA Altivec, VMX) instructions and register state. This changes + the overall size of the sigcontext and adds the swapcontext syscall. + This requires versioning of the setjmp/longjmp and get/make/set/swapcontext + functions */ +#if __LINUX_KERNEL_VERSION >= (132608) && defined __powerpc__ +# define __ASSUME_ALTIVEC_SIGCONTEXT 1 +#endif + /* On x86, the set_thread_area syscall was introduced in 2.5.29, but its semantics was changed in 2.5.30, and again after 2.5.31. */ #if __LINUX_KERNEL_VERSION >= 132384 && defined __i386__ diff -urN libc23-cvstip-20040102/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c libc23/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c --- libc23-cvstip-20040102/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c 2003-03-15 18:40:44.000000000 -0600 +++ libc23/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c 2004-01-07 14:25:55.000000000 -0600 @@ -69,4 +69,8 @@ } while (0) #endif +int __has_altivec=0; +#define DL_PLATFORM_INIT \ +__has_altivec=((GL(dl_hwcap) & PPC_FEATURE_HAS_ALTIVEC) ? 1:0); + #include diff -urN libc23-cvstip-20040102/sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h libc23/sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h --- libc23-cvstip-20040102/sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h 2003-12-17 17:11:15.000000000 -0600 +++ libc23/sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h 2004-01-10 12:34:56.000000000 -0600 @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1998, 1999, 2002, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,7 +29,7 @@ #if __WORDSIZE == 32 /* Number of general registers. */ -#define NGREG 48 +# define NGREG 48 /* Container for all general registers. */ typedef unsigned long gregset_t[NGREG]; @@ -62,8 +62,53 @@ #else -/* For 64-bit, a machine context is exactly a sigcontext. */ +# ifdef __ASSUME_ALTIVEC_SIGCONTEXT +/* For 64-bit kernels with Altivec support, a machine context is exactly + a sigcontext. */ typedef struct sigcontext mcontext_t; +# else +/* We have old kernel headers. So we need to allocate space for the + Altivec state here so programs will run correctly when they do run + a new kernel. */ + +#include + +typedef __vector128 elf_vrreg_t; + +struct vmx_sigcontext { + unsigned long _unused[4]; + int signal; + int _pad0; + unsigned long handler; + unsigned long oldmask; + struct pt_regs *regs; + elf_gregset_t gp_regs; + elf_fpregset_t fp_regs; +/* + * To maintain compatibility with current implementations the sigcontext is + * extended by appending a pointer (v_regs) to a quadword type (elf_vrreg_t) + * followed by an unstructured (vmx_reserve) field of 69 doublewords. This + * allows the array of vector registers to be quadword aligned independent of + * the alignment of the containing sigcontext or ucontext. It is the + * responsibility of the code setting the sigcontext to set this pointer to + * either NULL (if this processor does not support the VMX feature) or the + * address of the first quadword within the allocated (vmx_reserve) area. + * + * The pointer (v_regs) of vector type (elf_vrreg_t) is type compatible with + * an array of 34 quadword entries (elf_vrregset_t). The entries with + * indexes 0-31 contain the corresponding vector registers. The entry with + * index 32 contains the vscr as the last word (offset 12) within the + * quadword. This allows the vscr to be stored as either a quadword (since + * it must be copied via a vector register to/from storage) or as a word. + * The entry with index 33 contains the vrsave as the first word (offset 0) + * within the quadword. + */ + elf_vrreg_t *v_regs; + long vmx_reserve[69]; +}; + +typedef struct vmx_sigcontext mcontext_t; +# endif #endif --------------080003020408080506040502--