Annotation of sys/lib/libkern/arch/m88k/copy_subr.S, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: copy_subr.S,v 1.1 2006/11/17 22:32:38 miod Exp $ */
! 2: /*
! 3: * Mach Operating System
! 4: * Copyright (c) 1993-1992 Carnegie Mellon University
! 5: * Copyright (c) 1991 OMRON Corporation
! 6: * Copyright (c) 1996 Nivas Madhur
! 7: * Copyright (c) 1998 Steve Murphree, Jr.
! 8: * All Rights Reserved.
! 9: *
! 10: * Permission to use, copy, modify and distribute this software and its
! 11: * documentation is hereby granted, provided that both the copyright
! 12: * notice and this permission notice appear in all copies of the
! 13: * software, derivative works or modified versions, and any portions
! 14: * thereof, and that both notices appear in supporting documentation.
! 15: *
! 16: * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
! 17: * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
! 18: * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
! 19: *
! 20: * Carnegie Mellon requests users of this software to return to
! 21: *
! 22: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
! 23: * School of Computer Science
! 24: * Carnegie Mellon University
! 25: * Pittsburgh PA 15213-3890
! 26: *
! 27: * any improvements or extensions that they make and grant Carnegie the
! 28: * rights to redistribute these changes.
! 29: */
! 30:
! 31: #include <machine/asm.h>
! 32:
! 33: /*
! 34: * copy count bytes of data from source to destination
! 35: * Don Harper (don@omron.co.jp), Omron Corporation.
! 36: */
! 37:
! 38: #if defined(MEMCPY) || defined(MEMMOVE)
! 39: #define SRC r3
! 40: #define DST r2
! 41: #define SAVE r5
! 42: #else
! 43: #define SRC r2
! 44: #define DST r3
! 45: #endif
! 46: #define LEN r4
! 47:
! 48: #ifdef MEMCPY
! 49: ENTRY(memcpy)
! 50: #endif
! 51: #ifdef MEMMOVE
! 52: ENTRY(memmove)
! 53: #endif
! 54: #ifdef BCOPY
! 55: ENTRY(bcopy)
! 56: #endif
! 57: #ifdef OVBCOPY
! 58: ENTRY(ovbcopy)
! 59: #endif
! 60:
! 61: #if defined(MEMCPY) || defined(MEMMOVE)
! 62: or SAVE, DST, r0
! 63: #endif
! 64:
! 65: bcnd eq0,LEN,_ASM_LABEL(bcopy_out) /* nothing to do if == 0 */
! 66:
! 67: /*
! 68: * check position of source and destination data
! 69: */
! 70: cmp r9,SRC,DST /* compare source address to destination */
! 71: bb1 eq,r9,_ASM_LABEL(bcopy_out) /* nothing to do if equal */
! 72: #if defined(MEMMOVE) || defined(OVBCOPY)
! 73: bb1 lo,r9,_ASM_LABEL(bcopy_reverse) /* reverse copy if src < dest */
! 74: #endif
! 75:
! 76: /*
! 77: * source address is greater than destination address, or we do
! 78: * not have to care about overlapping areas: copy forward
! 79: */
! 80: cmp r9,LEN,16 /* see if we have at least 16 bytes */
! 81: bb1 lt,r9,_ASM_LABEL(f_byte_copy) /* copy bytes for small data length */
! 82: /*
! 83: * determine copy strategy based on alignment of source and destination
! 84: */
! 85: mask r6,SRC,3 /* get 2 low order bits of source address */
! 86: mask r7,DST,3 /* get 2 low order bits of destintation addr */
! 87: mak r6,r6,0<4> /* convert source bits to table offset */
! 88: mak r7,r7,0<2> /* convert destination bits to table offset */
! 89: or.u r12,r0,hi16(_ASM_LABEL(f_strat))
! 90: or r12,r12,lo16(_ASM_LABEL(f_strat))
! 91: addu r6,r6,r7 /* compute final table offset for strategy */
! 92: ld r12,r12,r6 /* load the strategy routine */
! 93: jmp r12 /* branch to strategy routine */
! 94:
! 95: /*
! 96: * Copy three bytes from src to destination then copy words
! 97: */
! 98: ASLOCAL(f_3byte_word_copy)
! 99: ld.bu r6,SRC,0 /* load byte from source */
! 100: ld.bu r7,SRC,1 /* load byte from source */
! 101: ld.bu r8,SRC,2 /* load byte from source */
! 102: st.b r6,DST,0 /* store byte to destination */
! 103: st.b r7,DST,1 /* store byte to destination */
! 104: st.b r8,DST,2 /* store byte to destination */
! 105: addu SRC,SRC,3 /* increment source pointer */
! 106: addu DST,DST,3 /* increment destination pointer */
! 107: br.n _ASM_LABEL(f_word_copy) /* copy full words */
! 108: subu LEN,LEN,3 /* decrement length */
! 109:
! 110: /*
! 111: * Copy 1 halfword from src to destination then copy words
! 112: */
! 113: ASLOCAL(f_1half_word_copy)
! 114: ld.hu r6,SRC,0 /* load half-word from source */
! 115: st.h r6,DST,0 /* store half-word to destination */
! 116: addu SRC,SRC,2 /* increment source pointer */
! 117: addu DST,DST,2 /* increment destination pointer */
! 118: br.n _ASM_LABEL(f_word_copy) /* copy full words */
! 119: subu LEN,LEN,2 /* decrement remaining length */
! 120:
! 121: /*
! 122: * Copy 1 byte from src to destination then copy words
! 123: */
! 124: ASLOCAL(f_1byte_word_copy)
! 125: ld.bu r6,SRC,0 /* load 1 byte from source */
! 126: st.b r6,DST,0 /* store 1 byte to destination */
! 127: addu SRC,SRC,1 /* increment source pointer */
! 128: addu DST,DST,1 /* increment destination pointer */
! 129: subu LEN,LEN,1 /* decrement remaining length */
! 130: /* FALLTHROUGH */
! 131: /*
! 132: * Copy as many full words as possible, 4 words per loop
! 133: */
! 134: ASLOCAL(f_word_copy)
! 135: cmp r10,LEN,16 /* see if we have 16 bytes remaining */
! 136: bb1 lo,r10,_ASM_LABEL(f_byte_copy) /* not enough left, copy bytes */
! 137: ld r6,SRC,0 /* load first word */
! 138: ld r7,SRC,4 /* load second word */
! 139: ld r8,SRC,8 /* load third word */
! 140: ld r9,SRC,12 /* load fourth word */
! 141: st r6,DST,0 /* store first word */
! 142: st r7,DST,4 /* store second word */
! 143: st r8,DST,8 /* store third word */
! 144: st r9,DST,12 /* store fourth word */
! 145: addu SRC,SRC,16 /* increment source pointer */
! 146: addu DST,DST,16 /* increment destination pointer */
! 147: br.n _ASM_LABEL(f_word_copy) /* branch to copy another block */
! 148: subu LEN,LEN,16 /* decrement remaining length */
! 149:
! 150: ASLOCAL(f_1byte_half_copy)
! 151: ld.bu r6,SRC,0 /* load 1 byte from source */
! 152: st.b r6,DST,0 /* store 1 byte to destination */
! 153: addu SRC,SRC,1 /* increment source pointer */
! 154: addu DST,DST,1 /* increment destination pointer */
! 155: subu LEN,LEN,1 /* decrement remaining length */
! 156: /* FALLTHROUGH */
! 157:
! 158: ASLOCAL(f_half_copy)
! 159: cmp r10,LEN,16 /* see if we have 16 bytes remaining */
! 160: bb1 lo,r10,_ASM_LABEL(f_byte_copy) /* not enough left, copy bytes */
! 161: ld.hu r6,SRC,0 /* load first half-word */
! 162: ld.hu r7,SRC,2 /* load second half-word */
! 163: ld.hu r8,SRC,4 /* load third half-word */
! 164: ld.hu r9,SRC,6 /* load fourth half-word */
! 165: ld.hu r10,SRC,8 /* load fifth half-word */
! 166: ld.hu r11,SRC,10 /* load sixth half-word */
! 167: ld.hu r12,SRC,12 /* load seventh half-word */
! 168: ld.hu r13,SRC,14 /* load eighth half-word */
! 169: st.h r6,DST,0 /* store first half-word */
! 170: st.h r7,DST,2 /* store second half-word */
! 171: st.h r8,DST,4 /* store third half-word */
! 172: st.h r9,DST,6 /* store fourth half-word */
! 173: st.h r10,DST,8 /* store fifth half-word */
! 174: st.h r11,DST,10 /* store sixth half-word */
! 175: st.h r12,DST,12 /* store seventh half-word */
! 176: st.h r13,DST,14 /* store eighth half-word */
! 177: addu SRC,SRC,16 /* increment source pointer */
! 178: addu DST,DST,16 /* increment destination pointer */
! 179: br.n _ASM_LABEL(f_half_copy) /* branch to copy another block */
! 180: subu LEN,LEN,16 /* decrement remaining length */
! 181:
! 182: ASLOCAL(f_byte_copy)
! 183: bcnd eq0,LEN,_ASM_LABEL(bcopy_out) /* branch if nothing left to copy */
! 184: ld.bu r6,SRC,0 /* load byte from source */
! 185: st.b r6,DST,0 /* store byte in destination */
! 186: addu SRC,SRC,1 /* increment source pointer */
! 187: addu DST,DST,1 /* increment destination pointer */
! 188: br.n _ASM_LABEL(f_byte_copy) /* branch for next byte */
! 189: subu LEN,LEN,1 /* decrement remaining length */
! 190:
! 191: #if defined(MEMMOVE) || defined(OVBCOPY)
! 192: /*
! 193: * source address is less than destination address, copy in reverse
! 194: */
! 195: ASLOCAL(bcopy_reverse)
! 196: /*
! 197: * start copy pointers at end of data
! 198: */
! 199: addu SRC,SRC,LEN /* start source at end of data */
! 200: addu DST,DST,LEN /* start destination at end of data */
! 201: /*
! 202: * check for short data
! 203: */
! 204: cmp r9,LEN,16 /* see if we have at least 16 bytes */
! 205: bb1 lt,r9,_ASM_LABEL(r_byte_copy) /* copy bytes for small data length */
! 206: /*
! 207: * determine copy strategy based on alignment of source and destination
! 208: */
! 209: mask r6,SRC,3 /* get 2 low order bits of source address */
! 210: mask r7,DST,3 /* get 2 low order bits of destintation addr */
! 211: mak r6,r6,0<4> /* convert source bits to table offset */
! 212: mak r7,r7,0<2> /* convert destination bits to table offset */
! 213: or.u r12,r0,hi16(_ASM_LABEL(r_strat))
! 214: or r12,r12,lo16(_ASM_LABEL(r_strat))
! 215: addu r6,r6,r7 /* compute final table offset for strategy */
! 216: ld r12,r12,r6 /* load the strategy routine */
! 217: jmp r12 /* branch to strategy routine */
! 218:
! 219: /*
! 220: * Copy three bytes from src to destination then copy words
! 221: */
! 222: ASLOCAL(r_3byte_word_copy)
! 223: subu SRC,SRC,3 /* decrement source pointer */
! 224: subu DST,DST,3 /* decrement destination pointer */
! 225: ld.bu r6,SRC,0 /* load byte from source */
! 226: ld.bu r7,SRC,1 /* load byte from source */
! 227: ld.bu r8,SRC,2 /* load byte from source */
! 228: st.b r6,DST,0 /* store byte to destination */
! 229: st.b r7,DST,1 /* store byte to destination */
! 230: st.b r8,DST,2 /* store byte to destination */
! 231: br.n _ASM_LABEL(r_word_copy) /* copy full words */
! 232: subu LEN,LEN,3 /* decrement length */
! 233:
! 234: /*
! 235: * Copy 1 halfword from src to destination then copy words
! 236: */
! 237: ASLOCAL(r_1half_word_copy)
! 238: subu SRC,SRC,2 /* decrement source pointer */
! 239: subu DST,DST,2 /* decrement destination pointer */
! 240: ld.hu r6,SRC,0 /* load half-word from source */
! 241: st.h r6,DST,0 /* store half-word to destination */
! 242: br.n _ASM_LABEL(r_word_copy) /* copy full words */
! 243: subu LEN,LEN,2 /* decrement remaining length */
! 244:
! 245: /*
! 246: * Copy 1 byte from src to destination then copy words
! 247: */
! 248: ASLOCAL(r_1byte_word_copy)
! 249: subu SRC,SRC,1 /* decrement source pointer */
! 250: subu DST,DST,1 /* decrement destination pointer */
! 251: ld.bu r6,SRC,0 /* load 1 byte from source */
! 252: st.b r6,DST,0 /* store 1 byte to destination */
! 253: subu LEN,LEN,1 /* decrement remaining length */
! 254: /* FALLTHROUGH */
! 255: /*
! 256: * Copy as many full words as possible, 4 words per loop
! 257: */
! 258: ASLOCAL(r_word_copy)
! 259: cmp r10,LEN,16 /* see if we have 16 bytes remaining */
! 260: bb1 lo,r10,_ASM_LABEL(r_byte_copy) /* not enough left, copy bytes */
! 261: subu SRC,SRC,16 /* decrement source pointer */
! 262: subu DST,DST,16 /* decrement destination pointer */
! 263: ld r6,SRC,0 /* load first word */
! 264: ld r7,SRC,4 /* load second word */
! 265: ld r8,SRC,8 /* load third word */
! 266: ld r9,SRC,12 /* load fourth word */
! 267: st r6,DST,0 /* store first word */
! 268: st r7,DST,4 /* store second word */
! 269: st r8,DST,8 /* store third word */
! 270: st r9,DST,12 /* store fourth word */
! 271: br.n _ASM_LABEL(r_word_copy) /* branch to copy another block */
! 272: subu LEN,LEN,16 /* decrement remaining length */
! 273:
! 274: ASLOCAL(r_1byte_half_copy)
! 275: subu SRC,SRC,1 /* decrement source pointer */
! 276: subu DST,DST,1 /* decrement destination pointer */
! 277: ld.bu r6,SRC,0 /* load 1 byte from source */
! 278: st.b r6,DST,0 /* store 1 byte to destination */
! 279: subu LEN,LEN,1 /* decrement remaining length */
! 280: /* FALLTHROUGH */
! 281:
! 282: ASLOCAL(r_half_copy)
! 283: cmp r10,LEN,16 /* see if we have 16 bytes remaining */
! 284: bb1 lo,r10,_ASM_LABEL(r_byte_copy) /* not enough left, copy bytes */
! 285: subu SRC,SRC,16 /* decrement source pointer */
! 286: subu DST,DST,16 /* decrement destination pointer */
! 287: ld.hu r6,SRC,0 /* load first half-word */
! 288: ld.hu r7,SRC,2 /* load second half-word */
! 289: ld.hu r8,SRC,4 /* load third half-word */
! 290: ld.hu r9,SRC,6 /* load fourth half-word */
! 291: ld.hu r10,SRC,8 /* load fifth half-word */
! 292: ld.hu r11,SRC,10 /* load sixth half-word */
! 293: ld.hu r12,SRC,12 /* load seventh half-word */
! 294: ld.hu r13,SRC,14 /* load eighth half-word */
! 295: st.h r6,DST,0 /* store first half-word */
! 296: st.h r7,DST,2 /* store second half-word */
! 297: st.h r8,DST,4 /* store third half-word */
! 298: st.h r9,DST,6 /* store fourth half-word */
! 299: st.h r10,DST,8 /* store fifth half-word */
! 300: st.h r11,DST,10 /* store sixth half-word */
! 301: st.h r12,DST,12 /* store seventh half-word */
! 302: st.h r13,DST,14 /* store eighth half-word */
! 303: br.n _ASM_LABEL(r_half_copy) /* branch to copy another block */
! 304: subu LEN,LEN,16 /* decrement remaining length */
! 305:
! 306: ASLOCAL(r_byte_copy)
! 307: bcnd eq0,LEN,_ASM_LABEL(bcopy_out) /* branch if nothing left to copy */
! 308: subu SRC,SRC,1 /* decrement source pointer */
! 309: subu DST,DST,1 /* decrement destination pointer */
! 310: ld.bu r6,SRC,0 /* load byte from source */
! 311: st.b r6,DST,0 /* store byte in destination */
! 312: br.n _ASM_LABEL(r_byte_copy) /* branch for next byte */
! 313: subu LEN,LEN,1 /* decrement remaining length */
! 314: #endif /* MEMMOVE || OVBCOPY */
! 315:
! 316: ASLOCAL(bcopy_out)
! 317: #if defined(MEMCPY) || defined(MEMMOVE)
! 318: jmp.n r1 /* all done, return to caller */
! 319: or r2, SAVE, r0
! 320: #else
! 321: jmp r1 /* all done, return to caller */
! 322: #endif
! 323:
! 324: data
! 325: align 4
! 326: ASLOCAL(f_strat)
! 327: word _ASM_LABEL(f_word_copy)
! 328: word _ASM_LABEL(f_byte_copy)
! 329: word _ASM_LABEL(f_half_copy)
! 330: word _ASM_LABEL(f_byte_copy)
! 331: word _ASM_LABEL(f_byte_copy)
! 332: word _ASM_LABEL(f_3byte_word_copy)
! 333: word _ASM_LABEL(f_byte_copy)
! 334: word _ASM_LABEL(f_1byte_half_copy)
! 335: word _ASM_LABEL(f_half_copy)
! 336: word _ASM_LABEL(f_byte_copy)
! 337: word _ASM_LABEL(f_1half_word_copy)
! 338: word _ASM_LABEL(f_byte_copy)
! 339: word _ASM_LABEL(f_byte_copy)
! 340: word _ASM_LABEL(f_1byte_half_copy)
! 341: word _ASM_LABEL(f_byte_copy)
! 342: word _ASM_LABEL(f_1byte_word_copy)
! 343:
! 344: #if defined(MEMMOVE) || defined(OVBCOPY)
! 345: ASLOCAL(r_strat)
! 346: word _ASM_LABEL(r_word_copy)
! 347: word _ASM_LABEL(r_byte_copy)
! 348: word _ASM_LABEL(r_half_copy)
! 349: word _ASM_LABEL(r_byte_copy)
! 350: word _ASM_LABEL(r_byte_copy)
! 351: word _ASM_LABEL(r_1byte_word_copy)
! 352: word _ASM_LABEL(r_byte_copy)
! 353: word _ASM_LABEL(r_1byte_half_copy)
! 354: word _ASM_LABEL(r_half_copy)
! 355: word _ASM_LABEL(r_byte_copy)
! 356: word _ASM_LABEL(r_1half_word_copy)
! 357: word _ASM_LABEL(r_byte_copy)
! 358: word _ASM_LABEL(r_byte_copy)
! 359: word _ASM_LABEL(r_1byte_half_copy)
! 360: word _ASM_LABEL(r_byte_copy)
! 361: word _ASM_LABEL(r_3byte_word_copy)
! 362: #endif
CVSweb