1 ! Copyright (C) 2008-2012 Imagination Technologies Ltd.
12 MOV A1.2, D0Ar2 ! source pointer
13 MOV A0.2, D1Ar1 ! destination pointer
14 MOV A0.3, D1Ar1 ! for return value
15 ! If there are less than 16 bytes to copy use the byte copy loop
19 ! Simply copy a byte at a time
28 ! Finally set return value and return
33 ANDS D1Ar5, D1Ar1, #7 ! test destination alignment
36 ! The destination address is not 8 byte aligned. We will copy bytes from
37 ! the source to the destination until the remaining data has an 8 byte
38 ! destination address alignment (i.e we should never copy more than 7
42 ADD D1Ar5, D1Ar5, #1 ! dest is aligned when D1Ar5 reaches #8
43 SUB D1Ar3, D1Ar3, #1 ! decrement count of remaining bytes
48 ! We have at least (16 - 7) = 9 bytes to copy - calculate the number of 8 byte
49 ! blocks, then jump to the unaligned copy loop or fall through to the aligned
50 ! copy loop as appropriate.
53 LSR D1Ar5, D1Ar3, #3 ! D1Ar5 = number of 8 byte blocks
54 ANDS D0Ar4, D0Ar4, #7 ! test source alignment
55 BNZ $Lunaligned_copy ! if unaligned, use unaligned copy loop
57 ! Both source and destination are 8 byte aligned - the easy case.
59 LSRS D1Ar5, D1Ar3, #5 ! D1Ar5 = number of 32 byte blocks
64 GETL D0Re0, D1Re0, [A1.2++]
65 GETL D0Ar6, D1Ar5, [A1.2++]
66 SETL [A0.2++], D0Re0, D1Re0
67 SETL [A0.2++], D0Ar6, D1Ar5
68 GETL D0Re0, D1Re0, [A1.2++]
69 GETL D0Ar6, D1Ar5, [A1.2++]
70 SETL [A0.2++], D0Re0, D1Re0
71 SETL [A0.2++], D0Ar6, D1Ar5
74 ! If there are any remaining bytes use the byte copy loop, otherwise we are done
75 ANDS D1Ar3, D1Ar3, #0x1f
79 ! The destination is 8 byte aligned but the source is not, and there are 8
80 ! or more bytes to be copied.
82 ! Adjust the source pointer (A1.2) to the 8 byte boundary before its
86 ANDMB D0Ar4, D0Ar4, #0xfff8
88 ! Save the number of bytes of mis-alignment in D0Ar4 for use later
89 SUBS D0Ar6, D0Ar6, D0Ar4
91 ! if there is no mis-alignment after all, use the aligned copy loop
95 GETL D0Re0, D1Re0, [A1.2]
99 ! There are 3 mis-alignment cases to be considered. Less than 4 bytes, exactly
100 ! 4 bytes, and more than 4 bytes.
102 BLT $Lunaligned_1_2_3 ! use 1-3 byte mis-alignment loop
103 BZ $Lunaligned_4 ! use 4 byte mis-alignment loop
105 ! The mis-alignment is more than 4 bytes
108 ! Calculate the bit offsets required for the shift operations necesssary
110 ! D0Ar6 = bit offset, D1Ar5 = (32 - bit offset)
111 MULW D0Ar6, D0Ar6, #8
113 SUB D1Ar5, D1Ar5, D0Ar6
114 ! Move data 4 bytes before we enter the main loop
118 GETL D0Ar2, D1Ar1, [++A1.2]
119 ! form 64-bit data in D0Re0, D1Re0
120 LSR D0Re0, D0Re0, D0Ar6
122 LSL D1Re0, D1Re0, D1Ar5
123 ADD D0Re0, D0Re0, D1Re0
125 LSR D0Ar2, D0Ar2, D0Ar6
126 LSL D1Re0, D1Ar1, D1Ar5
127 ADD D1Re0, D1Re0, D0Ar2
129 SETL [A0.2++], D0Re0, D1Re0
136 ! Calculate the bit offsets required for the shift operations necesssary
138 ! D0Ar6 = bit offset, D1Ar5 = (32 - bit offset)
139 MULW D0Ar6, D0Ar6, #8
141 SUB D1Ar5, D1Ar5, D0Ar6
144 ! form 64-bit data in D0Re0,D1Re0
145 LSR D0Re0, D0Re0, D0Ar6
146 LSL D1Ar1, D1Re0, D1Ar5
147 ADD D0Re0, D0Re0, D1Ar1
149 LSR D0FrT, D0Ar2, D0Ar6
150 GETL D0Ar2, D1Ar1, [++A1.2]
153 LSL D1Re0, D1Re0, D1Ar5
154 ADD D1Re0, D1Re0, D0FrT
156 SETL [A0.2++], D0Re0, D1Re0
163 ! The 4 byte mis-alignment case - this does not require any shifting, just a
164 ! shuffling of registers.
168 GETL D0Ar2, D1Ar1, [++A1.2]
170 SETL [A0.2++], D0Re0, D1Re0
175 ! If there are no remaining bytes to copy, we are done.
176 ANDS D1Ar3, D1Ar3, #7
178 ! Re-adjust the source pointer (A1.2) back to the actual (unaligned) byte
179 ! address of the remaining bytes, and fall through to the byte copy loop.
181 ADD D1Ar5, D0Ar4, D0Ar6
185 .size _memcpy,.-_memcpy