1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29 .file "%M%" 30 31/* 32 * memcpy(s1, s2, len) 33 * 34 * Copy s2 to s1, always copy n bytes. 35 * Note: this does not work for overlapped copies, bcopy() does 36 * 37 * Added entry __align_cpy_1 is generally for use of the compilers. 38 * 39 * 40 * Fast assembler language version of the following C-program for memcpy 41 * which represents the `standard' for the C-library. 42 * 43 * void * 44 * memcpy(void *s, const void *s0, size_t n) 45 * { 46 * if (n != 0) { 47 * char *s1 = s; 48 * const char *s2 = s0; 49 * do { 50 * *s1++ = *s2++; 51 * } while (--n != 0); 52 * } 53 * return (s); 54 * } 55 */ 56 57#include <sys/asm_linkage.h> 58 59 ANSI_PRAGMA_WEAK(memcpy,function) 60 61 ENTRY(memcpy) 62 ENTRY(__align_cpy_1) 63 mov %o0, %g5 ! save des address for return val 64 cmp %o2, 17 ! for small counts copy bytes 65 bleu,pn %xcc, .dbytecp 66 andcc %o1, 3, %o5 ! is src word aligned 67 bz,pn %icc, .aldst 68 cmp %o5, 2 ! is src half-word aligned 69 be,pt %xcc, .s2algn 70 cmp %o5, 3 ! src is byte aligned 71.s1algn:ldub [%o1], %o3 ! move 1 or 3 bytes to align it 72 inc 1, %o1 73 stb %o3, [%g5] ! move a byte to align src 74 inc 1, %g5 75 bne,pt %icc, .s2algn 76 dec %o2 77 b .ald ! now go align dest 78 andcc %g5, 3, %o5 79 80.s2algn:lduh [%o1], %o3 ! know src is 2 byte alinged 81 inc 2, %o1 82 srl %o3, 8, %o4 83 stb %o4, [%g5] ! have to do bytes, 84 stb %o3, [%g5 + 1] ! don't know dst alingment 85 inc 2, %g5 86 dec 2, %o2 87 88.aldst: andcc %g5, 3, %o5 ! align the destination address 89.ald: bz,pn %icc, .w4cp 90 cmp %o5, 2 91 bz,pn %icc, .w2cp 92 cmp %o5, 3 93.w3cp: lduw [%o1], %o4 94 inc 4, %o1 95 srl %o4, 24, %o5 96 stb %o5, [%g5] 97 bne,pt %icc, .w1cp 98 inc %g5 99 dec 1, %o2 100 andn %o2, 3, %o3 ! o3 is aligned word count 101 dec 4, %o3 ! avoid reading beyond tail of src 102 sub %o1, %g5, %o1 ! o1 gets the difference 103 1041: sll %o4, 8, %g1 ! save residual bytes 105 lduw [%o1+%g5], %o4 106 deccc 4, %o3 107 srl %o4, 24, %o5 ! merge with residual 108 or %o5, %g1, %g1 109 st %g1, [%g5] 110 bnz,pt %xcc, 1b 111 inc 4, %g5 112 sub %o1, 3, %o1 ! used one byte of last word read 113 and %o2, 3, %o2 114 b 7f 115 inc 4, %o2 116 117.w1cp: srl %o4, 8, %o5 118 sth %o5, [%g5] 119 inc 2, %g5 120 dec 3, %o2 121 andn %o2, 3, %o3 ! o3 is aligned word count 122 dec 4, %o3 ! avoid reading beyond tail of src 123 sub %o1, %g5, %o1 ! o1 gets the difference 124 1252: sll %o4, 24, %g1 ! save residual bytes 126 lduw [%o1+%g5], %o4 127 deccc 4, %o3 128 srl %o4, 8, %o5 ! merge with residual 129 or %o5, %g1, %g1 130 st %g1, [%g5] 131 bnz,pt %xcc, 2b 132 inc 4, %g5 133 sub %o1, 1, %o1 ! used three bytes of last word read 134 and %o2, 3, %o2 135 b 7f 136 inc 4, %o2 137 138.w2cp: lduw [%o1], %o4 139 inc 4, %o1 140 srl %o4, 16, %o5 141 sth %o5, [%g5] 142 inc 2, %g5 143 dec 2, %o2 144 andn %o2, 3, %o3 ! o3 is aligned word count 145 dec 4, %o3 ! avoid reading beyond tail of src 146 sub %o1, %g5, %o1 ! o1 gets the difference 147 1483: sll %o4, 16, %g1 ! save residual bytes 149 lduw [%o1+%g5], %o4 150 deccc 4, %o3 151 srl %o4, 16, %o5 ! merge with residual 152 or %o5, %g1, %g1 153 st %g1, [%g5] 154 bnz,pt %xcc, 3b 155 inc 4, %g5 156 sub %o1, 2, %o1 ! used two bytes of last word read 157 and %o2, 3, %o2 158 b 7f 159 inc 4, %o2 160 161.w4cp: andn %o2, 3, %o3 ! o3 is aligned word count 162 sub %o1, %g5, %o1 ! o1 gets the difference 163 1641: lduw [%o1+%g5], %o4 ! read from address 165 deccc 4, %o3 ! decrement count 166 st %o4, [%g5] ! write at destination address 167 bgu,pt %xcc, 1b 168 inc 4, %g5 ! increment to address 169 b 7f 170 and %o2, 3, %o2 ! number of leftover bytes, if any 171 172 ! 173 ! differenced byte copy, works with any alignment 174 ! 175.dbytecp: 176 b 7f 177 sub %o1, %g5, %o1 ! o1 gets the difference 178 1794: stb %o4, [%g5] ! write to address 180 inc %g5 ! inc to address 1817: deccc %o2 ! decrement count 182 bgeu,a,pt %xcc,4b ! loop till done 183 ldub [%o1+%g5], %o4 ! read from address 184 retl 185 nop 186 187 SET_SIZE(memcpy) 188 SET_SIZE(__align_cpy_1) 189