source: patches/inetutils-1.5-memcpy_sparc64-1.patch@ cbf293f

clfs-1.2 clfs-2.1 clfs-3.0.0-systemd clfs-3.0.0-sysvinit systemd sysvinit
Last change on this file since cbf293f was 44089f7, checked in by Joe Ciccone <jciccone@…>, 16 years ago

Resolve the bus error when you try and ping on sparc64.

  • Property mode set to 100644
File size: 22.7 KB
  • ping/Makefile.in

    Submitted By: William Harrington <wwh04660 at ucmo dot edu>
    Date: 2008-08-24
    Initial Package Version: 1.5
    Upstream Status: Rejected
    Description: Use a local memcpy instead of the glibc implementation for ping
                 This resolves the bus errors
    
    diff -Naur inetutils-1.5.orig/ping/Makefile.in inetutils-1.5/ping/Makefile.in
    old new  
    109109PROGRAMS = $(bin_PROGRAMS)
    110110am_ping_OBJECTS = ping.$(OBJEXT) ping_common.$(OBJEXT) \
    111111        ping_echo.$(OBJEXT) ping_address.$(OBJEXT) \
    112         ping_router.$(OBJEXT) ping_timestamp.$(OBJEXT)
     112        ping_router.$(OBJEXT) ping_timestamp.$(OBJEXT) \
     113        wordcopy.$(OBJEXT)
    113114ping_OBJECTS = $(am_ping_OBJECTS)
    114115ping_DEPENDENCIES =
    115116am_ping6_OBJECTS = ping6.$(OBJEXT) ping_common.$(OBJEXT)
     
    333334ping_LDADD = -L../libinetutils -linetutils -L../libicmp -licmp -L../lib -lgnu
    334335ping6_LDADD = -L../lib -lgnu -L../libinetutils -linetutils
    335336INCLUDES = -I$(top_srcdir)/lib -I../lib -I$(top_srcdir)/libicmp
    336 ping_SOURCES = ping.c ping_common.c ping_echo.c ping_address.c \
    337   ping_router.c ping_timestamp.c ping_common.h  ping_impl.h
     337ping_SOURCES = memcopy.h pagecopy.h ping.c ping_common.c \
     338  ping_echo.c ping_address.c ping_router.c ping_timestamp.c \
     339  ping_common.h  ping_impl.h wordcopy.c
    338340
    339341ping6_SOURCES = ping6.c ping_common.c ping_common.h ping6.h
    340342SUIDMODE = -o root -m 4775
  • ping/memcopy.h

    diff -Naur inetutils-1.5.orig/ping/memcopy.h inetutils-1.5/ping/memcopy.h
    old new  
     1/* memcopy.h -- definitions for memory copy functions.  Generic C version.
     2   Copyright (C) 1991, 1992, 1993, 1997, 2004 Free Software Foundation, Inc.
     3   This file is part of the GNU C Library.
     4   Contributed by Torbjorn Granlund (tege@sics.se).
     5
     6   The GNU C Library is free software; you can redistribute it and/or
     7   modify it under the terms of the GNU Lesser General Public
     8   License as published by the Free Software Foundation; either
     9   version 2.1 of the License, or (at your option) any later version.
     10
     11   The GNU C Library is distributed in the hope that it will be useful,
     12   but WITHOUT ANY WARRANTY; without even the implied warranty of
     13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14   Lesser General Public License for more details.
     15
     16   You should have received a copy of the GNU Lesser General Public
     17   License along with the GNU C Library; if not, write to the Free
     18   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     19   02111-1307 USA.  */
     20
     21/* The strategy of the memory functions is:
     22
     23     1. Copy bytes until the destination pointer is aligned.
     24
     25     2. Copy words in unrolled loops.  If the source and destination
     26     are not aligned in the same way, use word memory operations,
     27     but shift and merge two read words before writing.
     28
     29     3. Copy the few remaining bytes.
     30
     31   This is fast on processors that have at least 10 registers for
     32   allocation by GCC, and that can access memory at reg+const in one
     33   instruction.
     34
     35   I made an "exhaustive" test of this memmove when I wrote it,
     36   exhaustive in the sense that I tried all alignment and length
     37   combinations, with and without overlap.  */
     38
     39#include <sys/cdefs.h>
     40#include <endian.h>
     41
     42/* The macros defined in this file are:
     43
     44   BYTE_COPY_FWD(dst_beg_ptr, src_beg_ptr, nbytes_to_copy)
     45
     46   BYTE_COPY_BWD(dst_end_ptr, src_end_ptr, nbytes_to_copy)
     47
     48   WORD_COPY_FWD(dst_beg_ptr, src_beg_ptr, nbytes_remaining, nbytes_to_copy)
     49
     50   WORD_COPY_BWD(dst_end_ptr, src_end_ptr, nbytes_remaining, nbytes_to_copy)
     51
     52   MERGE(old_word, sh_1, new_word, sh_2)
     53     [I fail to understand.  I feel stupid.  --roland]
     54*/
     55
     56/* Type to use for aligned memory operations.
     57   This should normally be the biggest type supported by a single load
     58   and store.  */
     59#define op_t    unsigned long int
     60#define OPSIZ   (sizeof(op_t))
     61
     62/* Type to use for unaligned operations.  */
     63typedef unsigned char byte;
     64
     65/* Optimal type for storing bytes in registers.  */
     66#define reg_char        char
     67
     68#if __BYTE_ORDER == __LITTLE_ENDIAN
     69#define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
     70#endif
     71#if __BYTE_ORDER == __BIG_ENDIAN
     72#define MERGE(w0, sh_1, w1, sh_2) (((w0) << (sh_1)) | ((w1) >> (sh_2)))
     73#endif
     74
     75/* Copy exactly NBYTES bytes from SRC_BP to DST_BP,
     76   without any assumptions about alignment of the pointers.  */
     77#define BYTE_COPY_FWD(dst_bp, src_bp, nbytes)                                 \
     78  do                                                                          \
     79    {                                                                         \
     80      size_t __nbytes = (nbytes);                                             \
     81      while (__nbytes > 0)                                                    \
     82        {                                                                     \
     83          byte __x = ((byte *) src_bp)[0];                                    \
     84          src_bp += 1;                                                        \
     85          __nbytes -= 1;                                                      \
     86          ((byte *) dst_bp)[0] = __x;                                         \
     87          dst_bp += 1;                                                        \
     88        }                                                                     \
     89    } while (0)
     90
     91/* Copy exactly NBYTES_TO_COPY bytes from SRC_END_PTR to DST_END_PTR,
     92   beginning at the bytes right before the pointers and continuing towards
     93   smaller addresses.  Don't assume anything about alignment of the
     94   pointers.  */
     95#define BYTE_COPY_BWD(dst_ep, src_ep, nbytes)                                 \
     96  do                                                                          \
     97    {                                                                         \
     98      size_t __nbytes = (nbytes);                                             \
     99      while (__nbytes > 0)                                                    \
     100        {                                                                     \
     101          byte __x;                                                           \
     102          src_ep -= 1;                                                        \
     103          __x = ((byte *) src_ep)[0];                                         \
     104          dst_ep -= 1;                                                        \
     105          __nbytes -= 1;                                                      \
     106          ((byte *) dst_ep)[0] = __x;                                         \
     107        }                                                                     \
     108    } while (0)
     109
     110/* Copy *up to* NBYTES bytes from SRC_BP to DST_BP, with
     111   the assumption that DST_BP is aligned on an OPSIZ multiple.  If
     112   not all bytes could be easily copied, store remaining number of bytes
     113   in NBYTES_LEFT, otherwise store 0.  */
     114extern void _wordcopy_fwd_aligned (long int, long int, size_t) __THROW;
     115extern void _wordcopy_fwd_dest_aligned (long int, long int, size_t) __THROW;
     116#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes)                    \
     117  do                                                                          \
     118    {                                                                         \
     119      if (src_bp % OPSIZ == 0)                                                \
     120        _wordcopy_fwd_aligned (dst_bp, src_bp, (nbytes) / OPSIZ);             \
     121      else                                                                    \
     122        _wordcopy_fwd_dest_aligned (dst_bp, src_bp, (nbytes) / OPSIZ);        \
     123      src_bp += (nbytes) & -OPSIZ;                                            \
     124      dst_bp += (nbytes) & -OPSIZ;                                            \
     125      (nbytes_left) = (nbytes) % OPSIZ;                                       \
     126    } while (0)
     127
     128/* Copy *up to* NBYTES_TO_COPY bytes from SRC_END_PTR to DST_END_PTR,
     129   beginning at the words (of type op_t) right before the pointers and
     130   continuing towards smaller addresses.  May take advantage of that
     131   DST_END_PTR is aligned on an OPSIZ multiple.  If not all bytes could be
     132   easily copied, store remaining number of bytes in NBYTES_REMAINING,
     133   otherwise store 0.  */
     134extern void _wordcopy_bwd_aligned (long int, long int, size_t) __THROW;
     135extern void _wordcopy_bwd_dest_aligned (long int, long int, size_t) __THROW;
     136#define WORD_COPY_BWD(dst_ep, src_ep, nbytes_left, nbytes)                    \
     137  do                                                                          \
     138    {                                                                         \
     139      if (src_ep % OPSIZ == 0)                                                \
     140        _wordcopy_bwd_aligned (dst_ep, src_ep, (nbytes) / OPSIZ);             \
     141      else                                                                    \
     142        _wordcopy_bwd_dest_aligned (dst_ep, src_ep, (nbytes) / OPSIZ);        \
     143      src_ep -= (nbytes) & -OPSIZ;                                            \
     144      dst_ep -= (nbytes) & -OPSIZ;                                            \
     145      (nbytes_left) = (nbytes) % OPSIZ;                                       \
     146    } while (0)
     147
     148
     149/* Threshold value for when to enter the unrolled loops.  */
     150#define OP_T_THRES      16
  • ping/pagecopy.h

    diff -Naur inetutils-1.5.orig/ping/pagecopy.h inetutils-1.5/ping/pagecopy.h
    old new  
     1/* Macros for copying by pages; used in memcpy, memmove.  Generic macros.
     2   Copyright (C) 1995, 1997 Free Software Foundation, Inc.
     3   This file is part of the GNU C Library.
     4
     5   The GNU C Library is free software; you can redistribute it and/or
     6   modify it under the terms of the GNU Lesser General Public
     7   License as published by the Free Software Foundation; either
     8   version 2.1 of the License, or (at your option) any later version.
     9
     10   The GNU C Library is distributed in the hope that it will be useful,
     11   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13   Lesser General Public License for more details.
     14
     15   You should have received a copy of the GNU Lesser General Public
     16   License along with the GNU C Library; if not, write to the Free
     17   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     18   02111-1307 USA.  */
     19
     20/* This file defines the macro:
     21
     22   PAGE_COPY_FWD_MAYBE (dstp, srcp, nbytes_left, nbytes)
     23
     24   which is invoked like WORD_COPY_FWD et al.  The pointers should be at
     25   least word aligned.  This will check if virtual copying by pages can and
     26   should be done and do it if so.
     27
     28   System-specific pagecopy.h files should define these macros and then
     29   #include this file:
     30
     31   PAGE_COPY_THRESHOLD
     32   -- Minimum size for which virtual copying by pages is worthwhile.
     33
     34   PAGE_SIZE
     35   -- Size of a page.
     36
     37   PAGE_COPY_FWD (dstp, srcp, nbytes_left, nbytes)
     38   -- Macro to perform the virtual copy operation.
     39   The pointers will be aligned to PAGE_SIZE bytes.
     40*/
     41
     42
     43#if PAGE_COPY_THRESHOLD
     44
     45#include <assert.h>
     46
     47#define PAGE_COPY_FWD_MAYBE(dstp, srcp, nbytes_left, nbytes)                  \
     48  do                                                                          \
     49    {                                                                         \
     50      if ((nbytes) >= PAGE_COPY_THRESHOLD &&                                  \
     51          PAGE_OFFSET ((dstp) - (srcp)) == 0)                                 \
     52        {                                                                     \
     53          /* The amount to copy is past the threshold for copying             \
     54             pages virtually with kernel VM operations, and the               \
     55             source and destination addresses have the same alignment.  */    \
     56          size_t nbytes_before = PAGE_OFFSET (-(dstp));                       \
     57          if (nbytes_before != 0)                                             \
     58            {                                                                 \
     59              /* First copy the words before the first page boundary.  */     \
     60              WORD_COPY_FWD (dstp, srcp, nbytes_left, nbytes_before);         \
     61              assert (nbytes_left == 0);                                      \
     62              nbytes -= nbytes_before;                                        \
     63            }                                                                 \
     64          PAGE_COPY_FWD (dstp, srcp, nbytes_left, nbytes);                    \
     65        }                                                                     \
     66    } while (0)
     67
     68/* The page size is always a power of two, so we can avoid modulo division.  */
     69#define PAGE_OFFSET(n)  ((n) & (PAGE_SIZE - 1))
     70
     71#else
     72
     73#define PAGE_COPY_FWD_MAYBE(dstp, srcp, nbytes_left, nbytes) /* nada */
     74
     75#endif
  • ping/ping_echo.c

    diff -Naur inetutils-1.5.orig/ping/ping_echo.c inetutils-1.5/ping/ping_echo.c
    old new  
    5757
    5858#include <xalloc.h>
    5959
     60#ifndef memcpy
     61#include "memcopy.h"
     62#include "pagecopy.h"
     63#endif
     64
    6065static int handler (int code, void *closure,
    6166                   struct sockaddr_in *dest, struct sockaddr_in *from,
    6267                   struct ip *ip, icmphdr_t *icmp, int datalen);
     
    6873void print_icmp_header (struct sockaddr_in *from,
    6974                              struct ip *ip, icmphdr_t *icmp, int len);
    7075static void print_ip_opt (struct ip *ip, int hlen);
    71 
    7276int
    7377ping_echo (int argc, char **argv)
    7478{
     
    169173      timing++;
    170174      tp = (struct timeval *) icmp->icmp_data;
    171175
     176#define OP_T_THRES      16
     177#undef memcpy
     178void *
     179        memcpy (dstpp, srcpp, len)
     180        void *dstpp;
     181const void *srcpp;
     182size_t len;
     183{
     184        unsigned long int dstp = (long int) dstpp;
     185        unsigned long int srcp = (long int) srcpp;
     186
     187        /* Copy from the beginning to the end. */
     188
     189        /* If there not too few bytes to copy, use word copy. */
     190        if (len >= OP_T_THRES)
     191        {
     192                /* Copy just a few bytes to make DSTP aligned. */
     193                len -= (-dstp) % OPSIZ;
     194                BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
     195
     196                /* Copy whole pages from SRCP to DSTP by virtual address
     197                   manipulation, as much as possible. */
     198
     199                PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
     200
     201                /* Copy from SRCP to DSTP taking advantage of the known alignment
     202                   of DSTP. Number of bytes remaining is put in the third argument,
     203                   i.e. in LEN. This number may vary from machine to machine. */
     204
     205                WORD_COPY_FWD (dstp, srcp, len, len);
     206
     207                /* Fall out and copy the tail. */
     208        }
     209
     210        /* There are just a few bytes to copy. Use byte memory operations. */
     211        BYTE_COPY_FWD (dstp, srcp, len);
     212
     213        return dstpp;
     214}
     215
    172216      /* Avoid unaligned data: */
    173217      memcpy (&tv1, tp, sizeof (tv1));
    174218      tvsub (&tv, &tv1);
  • ping/wordcopy.c

    diff -Naur inetutils-1.5.orig/ping/wordcopy.c inetutils-1.5/ping/wordcopy.c
    old new  
     1/* _memcopy.c -- subroutines for memory copy functions.
     2   Copyright (C) 1991, 1996 Free Software Foundation, Inc.
     3   This file is part of the GNU C Library.
     4   Contributed by Torbjorn Granlund (tege@sics.se).
     5
     6   The GNU C Library is free software; you can redistribute it and/or
     7   modify it under the terms of the GNU Lesser General Public
     8   License as published by the Free Software Foundation; either
     9   version 2.1 of the License, or (at your option) any later version.
     10
     11   The GNU C Library is distributed in the hope that it will be useful,
     12   but WITHOUT ANY WARRANTY; without even the implied warranty of
     13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14   Lesser General Public License for more details.
     15
     16   You should have received a copy of the GNU Lesser General Public
     17   License along with the GNU C Library; if not, write to the Free
     18   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     19   02111-1307 USA.  */
     20
     21/* BE VERY CAREFUL IF YOU CHANGE THIS CODE...!  */
     22
     23#include <stddef.h>
     24#include <memcopy.h>
     25
     26/* _wordcopy_fwd_aligned -- Copy block beginning at SRCP to
     27   block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
     28   Both SRCP and DSTP should be aligned for memory operations on `op_t's.  */
     29
     30void
     31_wordcopy_fwd_aligned (dstp, srcp, len)
     32     long int dstp;
     33     long int srcp;
     34     size_t len;
     35{
     36  op_t a0, a1;
     37
     38  switch (len % 8)
     39    {
     40    case 2:
     41      a0 = ((op_t *) srcp)[0];
     42      srcp -= 6 * OPSIZ;
     43      dstp -= 7 * OPSIZ;
     44      len += 6;
     45      goto do1;
     46    case 3:
     47      a1 = ((op_t *) srcp)[0];
     48      srcp -= 5 * OPSIZ;
     49      dstp -= 6 * OPSIZ;
     50      len += 5;
     51      goto do2;
     52    case 4:
     53      a0 = ((op_t *) srcp)[0];
     54      srcp -= 4 * OPSIZ;
     55      dstp -= 5 * OPSIZ;
     56      len += 4;
     57      goto do3;
     58    case 5:
     59      a1 = ((op_t *) srcp)[0];
     60      srcp -= 3 * OPSIZ;
     61      dstp -= 4 * OPSIZ;
     62      len += 3;
     63      goto do4;
     64    case 6:
     65      a0 = ((op_t *) srcp)[0];
     66      srcp -= 2 * OPSIZ;
     67      dstp -= 3 * OPSIZ;
     68      len += 2;
     69      goto do5;
     70    case 7:
     71      a1 = ((op_t *) srcp)[0];
     72      srcp -= 1 * OPSIZ;
     73      dstp -= 2 * OPSIZ;
     74      len += 1;
     75      goto do6;
     76
     77    case 0:
     78      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
     79        return;
     80      a0 = ((op_t *) srcp)[0];
     81      srcp -= 0 * OPSIZ;
     82      dstp -= 1 * OPSIZ;
     83      goto do7;
     84    case 1:
     85      a1 = ((op_t *) srcp)[0];
     86      srcp -=-1 * OPSIZ;
     87      dstp -= 0 * OPSIZ;
     88      len -= 1;
     89      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
     90        goto do0;
     91      goto do8;                 /* No-op.  */
     92    }
     93
     94  do
     95    {
     96    do8:
     97      a0 = ((op_t *) srcp)[0];
     98      ((op_t *) dstp)[0] = a1;
     99    do7:
     100      a1 = ((op_t *) srcp)[1];
     101      ((op_t *) dstp)[1] = a0;
     102    do6:
     103      a0 = ((op_t *) srcp)[2];
     104      ((op_t *) dstp)[2] = a1;
     105    do5:
     106      a1 = ((op_t *) srcp)[3];
     107      ((op_t *) dstp)[3] = a0;
     108    do4:
     109      a0 = ((op_t *) srcp)[4];
     110      ((op_t *) dstp)[4] = a1;
     111    do3:
     112      a1 = ((op_t *) srcp)[5];
     113      ((op_t *) dstp)[5] = a0;
     114    do2:
     115      a0 = ((op_t *) srcp)[6];
     116      ((op_t *) dstp)[6] = a1;
     117    do1:
     118      a1 = ((op_t *) srcp)[7];
     119      ((op_t *) dstp)[7] = a0;
     120
     121      srcp += 8 * OPSIZ;
     122      dstp += 8 * OPSIZ;
     123      len -= 8;
     124    }
     125  while (len != 0);
     126
     127  /* This is the right position for do0.  Please don't move
     128     it into the loop.  */
     129 do0:
     130  ((op_t *) dstp)[0] = a1;
     131}
     132
     133/* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to
     134   block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
     135   DSTP should be aligned for memory operations on `op_t's, but SRCP must
     136   *not* be aligned.  */
     137
     138void
     139_wordcopy_fwd_dest_aligned (dstp, srcp, len)
     140     long int dstp;
     141     long int srcp;
     142     size_t len;
     143{
     144  op_t a0, a1, a2, a3;
     145  int sh_1, sh_2;
     146
     147  /* Calculate how to shift a word read at the memory operation
     148     aligned srcp to make it aligned for copy.  */
     149
     150  sh_1 = 8 * (srcp % OPSIZ);
     151  sh_2 = 8 * OPSIZ - sh_1;
     152
     153  /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
     154     it points in the middle of.  */
     155  srcp &= -OPSIZ;
     156
     157  switch (len % 4)
     158    {
     159    case 2:
     160      a1 = ((op_t *) srcp)[0];
     161      a2 = ((op_t *) srcp)[1];
     162      srcp -= 1 * OPSIZ;
     163      dstp -= 3 * OPSIZ;
     164      len += 2;
     165      goto do1;
     166    case 3:
     167      a0 = ((op_t *) srcp)[0];
     168      a1 = ((op_t *) srcp)[1];
     169      srcp -= 0 * OPSIZ;
     170      dstp -= 2 * OPSIZ;
     171      len += 1;
     172      goto do2;
     173    case 0:
     174      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
     175        return;
     176      a3 = ((op_t *) srcp)[0];
     177      a0 = ((op_t *) srcp)[1];
     178      srcp -=-1 * OPSIZ;
     179      dstp -= 1 * OPSIZ;
     180      len += 0;
     181      goto do3;
     182    case 1:
     183      a2 = ((op_t *) srcp)[0];
     184      a3 = ((op_t *) srcp)[1];
     185      srcp -=-2 * OPSIZ;
     186      dstp -= 0 * OPSIZ;
     187      len -= 1;
     188      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
     189        goto do0;
     190      goto do4;                 /* No-op.  */
     191    }
     192
     193  do
     194    {
     195    do4:
     196      a0 = ((op_t *) srcp)[0];
     197      ((op_t *) dstp)[0] = MERGE (a2, sh_1, a3, sh_2);
     198    do3:
     199      a1 = ((op_t *) srcp)[1];
     200      ((op_t *) dstp)[1] = MERGE (a3, sh_1, a0, sh_2);
     201    do2:
     202      a2 = ((op_t *) srcp)[2];
     203      ((op_t *) dstp)[2] = MERGE (a0, sh_1, a1, sh_2);
     204    do1:
     205      a3 = ((op_t *) srcp)[3];
     206      ((op_t *) dstp)[3] = MERGE (a1, sh_1, a2, sh_2);
     207
     208      srcp += 4 * OPSIZ;
     209      dstp += 4 * OPSIZ;
     210      len -= 4;
     211    }
     212  while (len != 0);
     213
     214  /* This is the right position for do0.  Please don't move
     215     it into the loop.  */
     216 do0:
     217  ((op_t *) dstp)[0] = MERGE (a2, sh_1, a3, sh_2);
     218}
     219
     220/* _wordcopy_bwd_aligned -- Copy block finishing right before
     221   SRCP to block finishing right before DSTP with LEN `op_t' words
     222   (not LEN bytes!).  Both SRCP and DSTP should be aligned for memory
     223   operations on `op_t's.  */
     224
     225void
     226_wordcopy_bwd_aligned (dstp, srcp, len)
     227     long int dstp;
     228     long int srcp;
     229     size_t len;
     230{
     231  op_t a0, a1;
     232
     233  switch (len % 8)
     234    {
     235    case 2:
     236      srcp -= 2 * OPSIZ;
     237      dstp -= 1 * OPSIZ;
     238      a0 = ((op_t *) srcp)[1];
     239      len += 6;
     240      goto do1;
     241    case 3:
     242      srcp -= 3 * OPSIZ;
     243      dstp -= 2 * OPSIZ;
     244      a1 = ((op_t *) srcp)[2];
     245      len += 5;
     246      goto do2;
     247    case 4:
     248      srcp -= 4 * OPSIZ;
     249      dstp -= 3 * OPSIZ;
     250      a0 = ((op_t *) srcp)[3];
     251      len += 4;
     252      goto do3;
     253    case 5:
     254      srcp -= 5 * OPSIZ;
     255      dstp -= 4 * OPSIZ;
     256      a1 = ((op_t *) srcp)[4];
     257      len += 3;
     258      goto do4;
     259    case 6:
     260      srcp -= 6 * OPSIZ;
     261      dstp -= 5 * OPSIZ;
     262      a0 = ((op_t *) srcp)[5];
     263      len += 2;
     264      goto do5;
     265    case 7:
     266      srcp -= 7 * OPSIZ;
     267      dstp -= 6 * OPSIZ;
     268      a1 = ((op_t *) srcp)[6];
     269      len += 1;
     270      goto do6;
     271
     272    case 0:
     273      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
     274        return;
     275      srcp -= 8 * OPSIZ;
     276      dstp -= 7 * OPSIZ;
     277      a0 = ((op_t *) srcp)[7];
     278      goto do7;
     279    case 1:
     280      srcp -= 9 * OPSIZ;
     281      dstp -= 8 * OPSIZ;
     282      a1 = ((op_t *) srcp)[8];
     283      len -= 1;
     284      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
     285        goto do0;
     286      goto do8;                 /* No-op.  */
     287    }
     288
     289  do
     290    {
     291    do8:
     292      a0 = ((op_t *) srcp)[7];
     293      ((op_t *) dstp)[7] = a1;
     294    do7:
     295      a1 = ((op_t *) srcp)[6];
     296      ((op_t *) dstp)[6] = a0;
     297    do6:
     298      a0 = ((op_t *) srcp)[5];
     299      ((op_t *) dstp)[5] = a1;
     300    do5:
     301      a1 = ((op_t *) srcp)[4];
     302      ((op_t *) dstp)[4] = a0;
     303    do4:
     304      a0 = ((op_t *) srcp)[3];
     305      ((op_t *) dstp)[3] = a1;
     306    do3:
     307      a1 = ((op_t *) srcp)[2];
     308      ((op_t *) dstp)[2] = a0;
     309    do2:
     310      a0 = ((op_t *) srcp)[1];
     311      ((op_t *) dstp)[1] = a1;
     312    do1:
     313      a1 = ((op_t *) srcp)[0];
     314      ((op_t *) dstp)[0] = a0;
     315
     316      srcp -= 8 * OPSIZ;
     317      dstp -= 8 * OPSIZ;
     318      len -= 8;
     319    }
     320  while (len != 0);
     321
     322  /* This is the right position for do0.  Please don't move
     323     it into the loop.  */
     324 do0:
     325  ((op_t *) dstp)[7] = a1;
     326}
     327
     328/* _wordcopy_bwd_dest_aligned -- Copy block finishing right
     329   before SRCP to block finishing right before DSTP with LEN `op_t'
     330   words (not LEN bytes!).  DSTP should be aligned for memory
     331   operations on `op_t', but SRCP must *not* be aligned.  */
     332
     333void
     334_wordcopy_bwd_dest_aligned (dstp, srcp, len)
     335     long int dstp;
     336     long int srcp;
     337     size_t len;
     338{
     339  op_t a0, a1, a2, a3;
     340  int sh_1, sh_2;
     341
     342  /* Calculate how to shift a word read at the memory operation
     343     aligned srcp to make it aligned for copy.  */
     344
     345  sh_1 = 8 * (srcp % OPSIZ);
     346  sh_2 = 8 * OPSIZ - sh_1;
     347
     348  /* Make srcp aligned by rounding it down to the beginning of the op_t
     349     it points in the middle of.  */
     350  srcp &= -OPSIZ;
     351  srcp += OPSIZ;
     352
     353  switch (len % 4)
     354    {
     355    case 2:
     356      srcp -= 3 * OPSIZ;
     357      dstp -= 1 * OPSIZ;
     358      a2 = ((op_t *) srcp)[2];
     359      a1 = ((op_t *) srcp)[1];
     360      len += 2;
     361      goto do1;
     362    case 3:
     363      srcp -= 4 * OPSIZ;
     364      dstp -= 2 * OPSIZ;
     365      a3 = ((op_t *) srcp)[3];
     366      a2 = ((op_t *) srcp)[2];
     367      len += 1;
     368      goto do2;
     369    case 0:
     370      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
     371        return;
     372      srcp -= 5 * OPSIZ;
     373      dstp -= 3 * OPSIZ;
     374      a0 = ((op_t *) srcp)[4];
     375      a3 = ((op_t *) srcp)[3];
     376      goto do3;
     377    case 1:
     378      srcp -= 6 * OPSIZ;
     379      dstp -= 4 * OPSIZ;
     380      a1 = ((op_t *) srcp)[5];
     381      a0 = ((op_t *) srcp)[4];
     382      len -= 1;
     383      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
     384        goto do0;
     385      goto do4;                 /* No-op.  */
     386    }
     387
     388  do
     389    {
     390    do4:
     391      a3 = ((op_t *) srcp)[3];
     392      ((op_t *) dstp)[3] = MERGE (a0, sh_1, a1, sh_2);
     393    do3:
     394      a2 = ((op_t *) srcp)[2];
     395      ((op_t *) dstp)[2] = MERGE (a3, sh_1, a0, sh_2);
     396    do2:
     397      a1 = ((op_t *) srcp)[1];
     398      ((op_t *) dstp)[1] = MERGE (a2, sh_1, a3, sh_2);
     399    do1:
     400      a0 = ((op_t *) srcp)[0];
     401      ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2);
     402
     403      srcp -= 4 * OPSIZ;
     404      dstp -= 4 * OPSIZ;
     405      len -= 4;
     406    }
     407  while (len != 0);
     408
     409  /* This is the right position for do0.  Please don't move
     410     it into the loop.  */
     411 do0:
     412  ((op_t *) dstp)[3] = MERGE (a0, sh_1, a1, sh_2);
     413}
Note: See TracBrowser for help on using the repository browser.