(getsourcefilter): Free memory if socket level value cannot be retrieved.
[kopensolaris-gnu/glibc.git] / sysdeps / ia64 / memmove.S
index 11fd2b3..7b8c86b 100644 (file)
@@ -1,25 +1,37 @@
-/*
- *
- * Optimized version of the standard memmove() function
- *
- * Contributed by Dan Pop <Dan.Pop@cern.ch>
- *
- * Return: dest
- *
- * Inputs:
- *      in0:    dest
- *      in1:    src
- *      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 
- * all arguments are multiples of 8, is optimised.
- *
- * In this form, it assumes little endian mode.  For big endian mode,
- * sh1 must be computed using an extra instruction: sub sh1 = 64, sh1
- * or the UM.be bit should be cleared at the beginning and set at the end.
- *
- */
+/* Optimized version of the standard memmove() function.
+   This file is part of the GNU C Library.
+   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 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.  */
+
+/* Return: dest
+
+   Inputs:
+        in0:    dest
+        in1:    src
+        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
+   all arguments are multiples of 8, is optimised.
+
+   In this form, it assumes little endian mode.  For big endian mode,
+   sh1 must be computed using an extra instruction: sub sh1 = 64, sh1
+   or the UM.be bit should be cleared at the beginning and set at the end.  */
 
 #include <sysdep.h>
 #undef ret
@@ -27,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
@@ -75,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
 
@@ -98,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
@@ -107,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
@@ -125,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
@@ -134,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
@@ -160,7 +182,7 @@ ENTRY(memmove)
        LOOP(40)
        LOOP(48)
        LOOP(56)
-       
+
 .src_aligned:
 .l3:
 (p[0])         ld8     r[0] = [src], 8
@@ -177,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
@@ -207,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
@@ -223,4 +248,4 @@ ENTRY(memmove)
        data8   .loop56 - .loop48
        data8   .loop56 - .loop56
 
-END(memmove)
+libc_hidden_builtin_def (memmove)