source:
patches/inetutils-1.5-memcpy_sparc64-1.patch@
42546b79
Last change on this file since 42546b79 was c90a839, checked in by , 16 years ago | |
---|---|
|
|
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 109 109 PROGRAMS = $(bin_PROGRAMS) 110 110 am_ping_OBJECTS = ping.$(OBJEXT) ping_common.$(OBJEXT) \ 111 111 ping_echo.$(OBJEXT) ping_address.$(OBJEXT) \ 112 ping_router.$(OBJEXT) ping_timestamp.$(OBJEXT) 112 ping_router.$(OBJEXT) ping_timestamp.$(OBJEXT) \ 113 wordcopy.$(OBJEXT) 113 114 ping_OBJECTS = $(am_ping_OBJECTS) 114 115 ping_DEPENDENCIES = 115 116 am_ping6_OBJECTS = ping6.$(OBJEXT) ping_common.$(OBJEXT) … … 333 334 ping_LDADD = -L../libinetutils -linetutils -L../libicmp -licmp -L../lib -lgnu 334 335 ping6_LDADD = -L../lib -lgnu -L../libinetutils -linetutils 335 336 INCLUDES = -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 337 ping_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 338 340 339 341 ping6_SOURCES = ping6.c ping_common.c ping_common.h ping6.h 340 342 SUIDMODE = -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. */ 63 typedef 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. */ 114 extern void _wordcopy_fwd_aligned (long int, long int, size_t) __THROW; 115 extern 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. */ 134 extern void _wordcopy_bwd_aligned (long int, long int, size_t) __THROW; 135 extern 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 57 57 58 58 #include <xalloc.h> 59 59 60 #ifndef memcpy 61 #include "memcopy.h" 62 #include "pagecopy.h" 63 #endif 64 60 65 static int handler (int code, void *closure, 61 66 struct sockaddr_in *dest, struct sockaddr_in *from, 62 67 struct ip *ip, icmphdr_t *icmp, int datalen); … … 68 73 void print_icmp_header (struct sockaddr_in *from, 69 74 struct ip *ip, icmphdr_t *icmp, int len); 70 75 static void print_ip_opt (struct ip *ip, int hlen); 71 72 76 int 73 77 ping_echo (int argc, char **argv) 74 78 { … … 169 173 timing++; 170 174 tp = (struct timeval *) icmp->icmp_data; 171 175 176 #define OP_T_THRES 16 177 #undef memcpy 178 void * 179 memcpy (dstpp, srcpp, len) 180 void *dstpp; 181 const void *srcpp; 182 size_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 172 216 /* Avoid unaligned data: */ 173 217 memcpy (&tv1, tp, sizeof (tv1)); 174 218 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 30 void 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 138 void 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 225 void 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 333 void 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.