1 /* memcpy.S: optimised assembly memcpy
3 * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
16 ###############################################################################
18 # void *memcpy(void *to, const char *from, size_t count)
20 # - NOTE: must not use any stack. exception detection performs function return
21 # to caller's fixup routine, aborting the remainder of the copy
23 ###############################################################################
24 .globl memcpy,__memcpy_end
25 .type memcpy,@function
28 orcc gr10,gr0,gr0,icc3
32 # optimise based on best common alignment for to, from & count
33 andicc.p gr4,#0x0f,gr0,icc0
35 andicc.p gr4,#0x07,gr0,icc1
37 andicc.p gr4,#0x03,gr0,icc0
39 andicc.p gr4,#0x01,gr0,icc1
44 # do byte by byte copy
47 0: ldubu.p @(gr9,gr11),gr4
48 subicc gr10,#1,gr10,icc0
49 stbu.p gr4,@(gr3,gr11)
53 # do halfword by halfword copy
58 0: lduhu.p @(gr9,gr11),gr4
59 subicc gr10,#2,gr10,icc0
60 sthu.p gr4,@(gr3,gr11)
64 # do word by word copy
69 0: ldu.p @(gr9,gr11),gr4
70 subicc gr10,#4,gr10,icc0
75 # do double-word by double-word copy
79 0: lddu.p @(gr9,gr11),gr4
80 subicc gr10,#8,gr10,icc0
81 stdu.p gr4,@(gr3,gr11)
85 # do quad-word by quad-word copy
89 0: lddu @(gr9,gr11),gr4
90 lddu.p @(gr9,gr11),gr6
91 subicc gr10,#16,gr10,icc0
93 stdu.p gr6,@(gr3,gr11)
98 .size memcpy, __memcpy_end-memcpy
100 ###############################################################################
102 # copy to/from userspace
103 # - return the number of bytes that could not be copied (0 on complete success)
105 # long __memcpy_user(void *dst, const void *src, size_t count)
107 ###############################################################################
108 .globl __memcpy_user, __memcpy_user_error_lr, __memcpy_user_error_handler
109 .type __memcpy_user,@function
113 add gr8,gr10,gr6 ; calculate expected end address
116 # abuse memcpy to do the dirty work
118 __memcpy_user_error_lr:
124 # deal any exception generated by memcpy
125 # GR8 - memcpy's current dest address
126 # GR11 - memset's step value (index register for store insns)
127 __memcpy_user_error_handler:
128 lddi.p @(sp,#0),gr4 ; load GR4 with dst+count, GR5 with ret addr
135 .size __memcpy_user, .-__memcpy_user