(getsourcefilter): Free memory if socket level value cannot be retrieved.
[kopensolaris-gnu/glibc.git] / sysdeps / ia64 / memmove.S
index 3fc38b9..7b8c86b 100644 (file)
@@ -1,22 +1,22 @@
 /* Optimized version of the standard memmove() function.
    This file is part of the GNU C Library.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
    Contributed by Dan Pop <Dan.Pop@cern.ch>.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
+   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
-   Library General Public License for more details.
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   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.  */
 
 /* Return: dest
 
@@ -26,7 +26,7 @@
         in2:    byte count
 
    The core of the function is the memcpy implementation used in memcpy.S.
-   When bytes have to be copied backwards, only the easy case, when 
+   When bytes have to be copied backwards, only the easy case, when
    all arguments are multiples of 8, is optimised.
 
    In this form, it assumes little endian mode.  For big endian mode,
@@ -39,7 +39,6 @@
 #define OP_T_THRES     16
 #define OPSIZ           8
 
-#define saved_pfs      r14
 #define adest          r15
 #define saved_pr       r17
 #define saved_lc       r18
 #define loopcnt                r30
 #define        value           r31
 
+#ifdef GAS_ALIGN_BREAKS_UNWIND_INFO
+# define ALIGN(n)      { nop 0 }
+#else
+# define ALIGN(n)      .align n
+#endif
+
 #define LOOP(shift)                                                    \
-               .align  32 ;                                            \
+               ALIGN(32);                                              \
 .loop##shift##:                                                                \
 (p[0])         ld8     r[0] = [asrc], 8 ;      /* w1 */                \
 (p[MEMLAT+1])  st8     [dest] = value, 8 ;                             \
-(p[MEMLAT])    shrp    value = r[MEMLAT], r[MEMLAT+1], shift ; \
+(p[MEMLAT])    shrp    value = r[MEMLAT], r[MEMLAT+1], shift ;         \
                nop.b   0 ;                                             \
                nop.b   0 ;                                             \
                br.ctop.sptk .loop##shift ;                             \
                br.cond.sptk .cpyfew ; /* deal with the remaining bytes */
 
+#define MEMLAT 21
+#define Nrot   (((2*MEMLAT+3) + 7) & ~7)
+
 ENTRY(memmove)
-       alloc   saved_pfs = ar.pfs, 3, 29, 0, 32
-#include "softpipe.h"
+       .prologue
+       alloc   r2 = ar.pfs, 3, Nrot - 3, 0, Nrot
        .rotr   r[MEMLAT + 2], q[MEMLAT + 1]
        .rotp   p[MEMLAT + 2]
        mov     ret0 = in0              // return value = dest
+       .save pr, saved_pr
        mov     saved_pr = pr           // save the predicate registers
+       .save ar.lc, saved_lc
         mov    saved_lc = ar.lc        // save the loop counter
+       .body
        or      tmp3 = in0, in1 ;;      // tmp3 = dest | src
        or      tmp3 = tmp3, in2        // tmp3 = dest | src | len
        mov     dest = in0              // dest
@@ -87,7 +98,7 @@ ENTRY(memmove)
        and     tmp4 = 7, tmp3          // tmp4 = (dest | src | len) & 7
        cmp.le  p6, p0 = dest, src      // if dest <= src it's always safe
 (p6)   br.cond.spnt .forward           // to copy forward
-       add     tmp3 = src, len;;       
+       add     tmp3 = src, len;;
        cmp.lt  p6, p0 = dest, tmp3     // if dest > src && dest < src + len
 (p6)   br.cond.spnt .backward          // we have to copy backward
 
@@ -110,7 +121,7 @@ ENTRY(memmove)
 (p6)   br.cond.spnt .restore_and_exit;;// the one-word special case
        adds    adest = 8, dest         // set adest one word ahead of dest
        adds    asrc = 8, src ;;        // set asrc one word ahead of src
-       nop.b   0                       // get the "golden" alignment for 
+       nop.b   0                       // get the "golden" alignment for
        nop.b   0                       // the next loop
 .l0:
 (p[0])         ld8     r[0] = [src], 16
@@ -119,7 +130,6 @@ ENTRY(memmove)
 (p[MEMLAT])    st8     [adest] = q[MEMLAT], 16
                br.ctop.dptk .l0 ;;
 
-       mov     ar.pfs = saved_pfs      // restore the PFS
        mov     pr = saved_pr, -1       // restore the predicate registers
        mov     ar.lc = saved_lc        // restore the loop counter
        br.ret.sptk.many b0
@@ -137,8 +147,8 @@ ENTRY(memmove)
 .l1:                                   // copy -dest % 8 bytes
        ld1     value = [src], 1        // value = *src++
        ;;
-       st1     [dest] = value, 1       // *dest++ = value  
-       br.cloop.dptk .l1       
+       st1     [dest] = value, 1       // *dest++ = value
+       br.cloop.dptk .l1
 .dest_aligned:
        and     sh1 = 7, src            // sh1 = src % 8
        and     tmp2 = -8, len          // tmp2 = len & -OPSIZ
@@ -146,7 +156,7 @@ ENTRY(memmove)
        shr.u   loopcnt = len, 3        // loopcnt = len / 8
        and     len = 7, len;;          // len = len % 8
        adds    loopcnt = -1, loopcnt   // --loopcnt
-       addl    tmp4 = @ltoff(.table), gp 
+       addl    tmp4 = @ltoff(.table), gp
        addl    tmp3 = @ltoff(.loop56), gp
        mov     ar.ec = MEMLAT + 1      // set EC
        mov     pr.rot = 1 << 16;;      // set rotating predicates
@@ -172,7 +182,7 @@ ENTRY(memmove)
        LOOP(40)
        LOOP(48)
        LOOP(56)
-       
+
 .src_aligned:
 .l3:
 (p[0])         ld8     r[0] = [src], 8
@@ -189,7 +199,6 @@ ENTRY(memmove)
        st1     [dest] = value, 1
        br.cloop.dptk   .l4 ;;
 .restore_and_exit:
-       mov     ar.pfs = saved_pfs      // restore the PFS
        mov     pr = saved_pr, -1       // restore the predicate registers
        mov     ar.lc = saved_lc        // restore the loop counter
        br.ret.sptk.many b0
@@ -219,12 +228,16 @@ ENTRY(memmove)
        adds    src = -1, src           // src points to the last byte
        adds    dest = -1, dest         // dest points to the last byte
        adds    loopcnt = -1, len;;     // loopcnt = len - 1
-       mov     ar.lc = loopcnt;;       // set the loop counter 
+       mov     ar.lc = loopcnt;;       // set the loop counter
 .l6:
 (p[0])         ld1     r[0] = [src], -1
 (p[MEMLAT])    st1     [dest] = r[MEMLAT], -1
                br.ctop.dptk .l6
                br.cond.sptk .restore_and_exit
+END(memmove)
+
+       .rodata
+       .align 8
 .table:
        data8   0                       // dummy entry
        data8   .loop56 - .loop8
@@ -235,4 +248,4 @@ ENTRY(memmove)
        data8   .loop56 - .loop48
        data8   .loop56 - .loop56
 
-END(memmove)
+libc_hidden_builtin_def (memmove)