1/* Copy memory to memory until the specified number of bytes 2 has been copied. Overlap is handled correctly. 3 For SPARC V9. 4 Copyright (C) 2017-2022 Free Software Foundation, Inc. 5 This file is part of the GNU C Library. 6 7 The GNU C Library is free software; you can redistribute it and/or 8 modify it under the terms of the GNU Lesser General Public 9 License as published by the Free Software Foundation; either 10 version 2.1 of the License, or (at your option) any later version. 11 12 The GNU C Library is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 Lesser General Public License for more details. 16 17 You should have received a copy of the GNU Lesser General Public 18 License along with the GNU C Library; if not, see 19 <https://www.gnu.org/licenses/>. */ 20 21#include <sysdep.h> 22 23#ifndef XCC 24# define XCC xcc 25 .register %g2, #scratch 26#endif 27 28ENTRY(memmove) 29 mov %o0, %g2 /* Save pointer to destination */ 30 cmp %o1, %o0 /* if from address is >= to use forward copy */ 31 bgeu,a %XCC, 2f /* else use backward if ... */ 32 cmp %o2, 17 /* delay slot, for small counts copy bytes */ 33 34 sub %o0, %o1, %o4 /* get difference of two addresses */ 35 cmp %o2, %o4 /* compare size and difference of addresses */ 36 bgu %XCC, .Lovbc /* if size is bigger, have to do overlapped copy */ 37 cmp %o2, 17 /* delay slot, for small counts copy bytes */ 38/* 39 * normal, copy forwards 40 */ 412: ble %XCC, .Ldbytecp 42 andcc %o1, 3, %o5 /* is src word aligned */ 43 bz,pn %icc, .Laldst 44 cmp %o5, 2 /* is src half-word aligned */ 45 be,pn %icc, .Ls2alg 46 cmp %o5, 3 /* src is byte aligned */ 47 ldub [%o1], %o3 /* move 1 or 3 bytes to align it */ 48 inc 1, %o1 49 stb %o3, [%o0] /* move a byte to align src */ 50 inc 1, %o0 51 bne,pn %icc, .Ls2alg 52 dec %o2 53 b .Lald /* now go align dest */ 54 andcc %o0, 3, %o5 55 56.Ls2alg: 57 lduh [%o1], %o3 /* know src is 2 byte aligned */ 58 inc 2, %o1 59 srl %o3, 8, %o4 60 stb %o4, [%o0] /* have to do bytes, */ 61 stb %o3, [%o0 + 1] /* don't know dst alingment */ 62 inc 2, %o0 63 dec 2, %o2 64 65.Laldst: 66 andcc %o0, 3, %o5 /* align the destination address */ 67.Lald: bz,pn %icc, .Lw4cp 68 cmp %o5, 2 69 bz,pn %icc, .Lw2cp 70 cmp %o5, 3 71.Lw3cp: 72 lduw [%o1], %o4 73 inc 4, %o1 74 srl %o4, 24, %o5 75 stb %o5, [%o0] 76 bne,pt %icc, .Lw1cp 77 inc %o0 78 dec 1, %o2 79 andn %o2, 3, %o3 /* i3 is aligned word count */ 80 dec 4, %o3 /* avoid reading beyond tail of src */ 81 sub %o1, %o0, %o1 /* i1 gets the difference */ 82 831: sll %o4, 8, %g1 /* save residual bytes */ 84 lduw [%o1+%o0], %o4 85 deccc 4, %o3 86 srl %o4, 24, %o5 /* merge with residual */ 87 or %o5, %g1, %g1 88 st %g1, [%o0] 89 bnz,pt %XCC, 1b 90 inc 4, %o0 91 sub %o1, 3, %o1 /* used one byte of last word read */ 92 and %o2, 3, %o2 93 b 7f 94 inc 4, %o2 95 96.Lw1cp: 97 srl %o4, 8, %o5 98 sth %o5, [%o0] 99 inc 2, %o0 100 dec 3, %o2 101 andn %o2, 3, %o3 102 dec 4, %o3 /* avoid reading beyond tail of src */ 103 sub %o1, %o0, %o1 /* i1 gets the difference */ 104 1052: sll %o4, 24, %g1 /* save residual bytes */ 106 lduw [%o1+%o0], %o4 107 deccc 4, %o3 108 srl %o4, 8, %o5 /* merge with residual */ 109 or %o5, %g1, %g1 110 st %g1, [%o0] 111 bnz,pt %XCC, 2b 112 inc 4, %o0 113 sub %o1, 1, %o1 /* used three bytes of last word read */ 114 and %o2, 3, %o2 115 b 7f 116 inc 4, %o2 117 118.Lw2cp: 119 lduw [%o1], %o4 120 inc 4, %o1 121 srl %o4, 16, %o5 122 sth %o5, [%o0] 123 inc 2, %o0 124 dec 2, %o2 125 andn %o2, 3, %o3 /* i3 is aligned word count */ 126 dec 4, %o3 /* avoid reading beyond tail of src */ 127 sub %o1, %o0, %o1 /* i1 gets the difference */ 128 1293: sll %o4, 16, %g1 /* save residual bytes */ 130 lduw [%o1+%o0], %o4 131 deccc 4, %o3 132 srl %o4, 16, %o5 /* merge with residual */ 133 or %o5, %g1, %g1 134 st %g1, [%o0] 135 bnz,pt %XCC, 3b 136 inc 4, %o0 137 sub %o1, 2, %o1 /* used two bytes of last word read */ 138 and %o2, 3, %o2 139 b 7f 140 inc 4, %o2 141 142.Lw4cp: 143 andn %o2, 3, %o3 /* i3 is aligned word count */ 144 sub %o1, %o0, %o1 /* i1 gets the difference */ 145 1461: lduw [%o1+%o0], %o4 /* read from address */ 147 deccc 4, %o3 /* decrement count */ 148 st %o4, [%o0] /* write at destination address */ 149 bg,pt %XCC, 1b 150 inc 4, %o0 /* increment to address */ 151 b 7f 152 and %o2, 3, %o2 /* number of leftover bytes, if any */ 153 154/* 155 * differenced byte copy, works with any alignment 156 */ 157.Ldbytecp: 158 b 7f 159 sub %o1, %o0, %o1 /* i1 gets the difference */ 160 1614: stb %o4, [%o0] /* write to address */ 162 inc %o0 /* inc to address */ 1637: deccc %o2 /* decrement count */ 164 bge,a %XCC, 4b /* loop till done */ 165 ldub [%o1+%o0], %o4 /* read from address */ 166 retl 167 mov %g2, %o0 /* return pointer to destination */ 168 169/* 170 * an overlapped copy that must be done "backwards" 171 */ 172.Lovbc: 173 add %o1, %o2, %o1 /* get to end of source space */ 174 add %o0, %o2, %o0 /* get to end of destination space */ 175 sub %o1, %o0, %o1 /* i1 gets the difference */ 176 1775: dec %o0 /* decrement to address */ 178 ldub [%o1+%o0], %o3 /* read a byte */ 179 deccc %o2 /* decrement count */ 180 bg,pt %XCC, 5b /* loop until done */ 181 stb %o3, [%o0] /* write byte */ 182 retl 183 mov %g2, %o0 /* return pointer to destination */ 184END(memmove) 185 186libc_hidden_builtin_def (memmove) 187