1/* $OpenBSD: memcpy.S,v 1.6 2015/08/31 02:53:56 guenther Exp $ */ 2/* $NetBSD: bcopy.S,v 1.3 1996/10/17 03:08:11 cgd Exp $ */ 3 4/* 5 * Copyright (c) 1995 Carnegie-Mellon University. 6 * All rights reserved. 7 * 8 * Author: Trevor Blackwell. Support for use as memcpy() and memmove() 9 * added by Chris Demetriou. 10 * 11 * Permission to use, copy, modify and distribute this software and 12 * its documentation is hereby granted, provided that both the copyright 13 * notice and this permission notice appear in all copies of the 14 * software, derivative works or modified versions, and any portions 15 * thereof, and that both notices appear in supporting documentation. 16 * 17 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 18 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 19 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 20 * 21 * Carnegie Mellon requests users of this software to return to 22 * 23 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 24 * School of Computer Science 25 * Carnegie Mellon University 26 * Pittsburgh PA 15213-3890 27 * 28 * any improvements or extensions that they make and grant Carnegie the 29 * rights to redistribute these changes. 30 */ 31 32#include "SYS.h" 33 34#define SRCREG a1 35#define DSTREG a0 36#define SIZEREG a2 37 38/* 39 * Copy bytes. 40 * 41 * char *memcpy(void *to, const void *from, size_t len); 42 * 43 * No matter how invoked, the source and destination registers 44 * for calculation. There's no point in copying them to "working" 45 * registers, since the code uses their values "in place," and 46 * copying them would be slower. 47 */ 48 49LEAF(memcpy,3) 50 /* set up return value, while we still can */ 51 mov DSTREG,v0 52 53 /* Check for zero length */ 54 beq SIZEREG,bcopy_done 55 56 /* a3 = end address */ 57 addq SRCREG,SIZEREG,a3 58 59 /* Get the first word */ 60 ldq_u t2,0(SRCREG) 61 62 /* Do they have the same alignment? */ 63 xor SRCREG,DSTREG,t0 64 and t0,7,t0 65 and DSTREG,7,t1 66 bne t0,bcopy_different_alignment 67 68 /* src & dst have same alignment */ 69 beq t1,bcopy_all_aligned 70 71 ldq_u t3,0(DSTREG) 72 addq SIZEREG,t1,SIZEREG 73 mskqh t2,SRCREG,t2 74 mskql t3,SRCREG,t3 75 or t2,t3,t2 76 77 /* Dst is 8-byte aligned */ 78 79bcopy_all_aligned: 80 /* If less than 8 bytes,skip loop */ 81 subq SIZEREG,1,t0 82 and SIZEREG,7,SIZEREG 83 bic t0,7,t0 84 beq t0,bcopy_samealign_lp_end 85 86bcopy_samealign_lp: 87 stq_u t2,0(DSTREG) 88 addq DSTREG,8,DSTREG 89 ldq_u t2,8(SRCREG) 90 subq t0,8,t0 91 addq SRCREG,8,SRCREG 92 bne t0,bcopy_samealign_lp 93 94bcopy_samealign_lp_end: 95 /* If we're done, exit */ 96 bne SIZEREG,bcopy_small_left 97 stq_u t2,0(DSTREG) 98 RET 99 100bcopy_small_left: 101 mskql t2,SIZEREG,t4 102 ldq_u t3,0(DSTREG) 103 mskqh t3,SIZEREG,t3 104 or t4,t3,t4 105 stq_u t4,0(DSTREG) 106 RET 107 108bcopy_different_alignment: 109 /* 110 * this is the fun part 111 */ 112 addq SRCREG,SIZEREG,a3 113 cmpule SIZEREG,8,t0 114 bne t0,bcopy_da_finish 115 116 beq t1,bcopy_da_noentry 117 118 /* Do the initial partial word */ 119 subq zero,DSTREG,t0 120 and t0,7,t0 121 ldq_u t3,7(SRCREG) 122 extql t2,SRCREG,t2 123 extqh t3,SRCREG,t3 124 or t2,t3,t5 125 insql t5,DSTREG,t5 126 ldq_u t6,0(DSTREG) 127 mskql t6,DSTREG,t6 128 or t5,t6,t5 129 stq_u t5,0(DSTREG) 130 addq SRCREG,t0,SRCREG 131 addq DSTREG,t0,DSTREG 132 subq SIZEREG,t0,SIZEREG 133 ldq_u t2,0(SRCREG) 134 135bcopy_da_noentry: 136 subq SIZEREG,1,t0 137 bic t0,7,t0 138 and SIZEREG,7,SIZEREG 139 beq t0,bcopy_da_finish2 140 141bcopy_da_lp: 142 ldq_u t3,7(SRCREG) 143 addq SRCREG,8,SRCREG 144 extql t2,SRCREG,t4 145 extqh t3,SRCREG,t5 146 subq t0,8,t0 147 or t4,t5,t5 148 stq t5,0(DSTREG) 149 addq DSTREG,8,DSTREG 150 beq t0,bcopy_da_finish1 151 ldq_u t2,7(SRCREG) 152 addq SRCREG,8,SRCREG 153 extql t3,SRCREG,t4 154 extqh t2,SRCREG,t5 155 subq t0,8,t0 156 or t4,t5,t5 157 stq t5,0(DSTREG) 158 addq DSTREG,8,DSTREG 159 bne t0,bcopy_da_lp 160 161bcopy_da_finish2: 162 /* Do the last new word */ 163 mov t2,t3 164 165bcopy_da_finish1: 166 /* Do the last partial word */ 167 ldq_u t2,-1(a3) 168 extql t3,SRCREG,t3 169 extqh t2,SRCREG,t2 170 or t2,t3,t2 171 br zero,bcopy_samealign_lp_end 172 173bcopy_da_finish: 174 /* Do the last word in the next source word */ 175 ldq_u t3,-1(a3) 176 extql t2,SRCREG,t2 177 extqh t3,SRCREG,t3 178 or t2,t3,t2 179 insqh t2,DSTREG,t3 180 insql t2,DSTREG,t2 181 lda t4,-1(zero) 182 mskql t4,SIZEREG,t5 183 cmovne t5,t5,t4 184 insqh t4,DSTREG,t5 185 insql t4,DSTREG,t4 186 addq DSTREG,SIZEREG,a4 187 ldq_u t6,0(DSTREG) 188 ldq_u t7,-1(a4) 189 bic t6,t4,t6 190 bic t7,t5,t7 191 and t2,t4,t2 192 and t3,t5,t3 193 or t2,t6,t2 194 or t3,t7,t3 195 stq_u t3,-1(a4) 196 stq_u t2,0(DSTREG) 197bcopy_done: 198 RET 199 200 END_STRONG(memcpy) 201