2 * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com)
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
9 #include <linux/linkage.h>
11 #ifdef __LITTLE_ENDIAN__
12 # define SHIFT_1(RX,RY,IMM) asl RX, RY, IMM ; <<
13 # define SHIFT_2(RX,RY,IMM) lsr RX, RY, IMM ; >>
14 # define MERGE_1(RX,RY,IMM) asl RX, RY, IMM
15 # define MERGE_2(RX,RY,IMM)
16 # define EXTRACT_1(RX,RY,IMM) and RX, RY, 0xFFFF
17 # define EXTRACT_2(RX,RY,IMM) lsr RX, RY, IMM
19 # define SHIFT_1(RX,RY,IMM) lsr RX, RY, IMM ; >>
20 # define SHIFT_2(RX,RY,IMM) asl RX, RY, IMM ; <<
21 # define MERGE_1(RX,RY,IMM) asl RX, RY, IMM ; <<
22 # define MERGE_2(RX,RY,IMM) asl RX, RY, IMM ; <<
23 # define EXTRACT_1(RX,RY,IMM) lsr RX, RY, IMM
24 # define EXTRACT_2(RX,RY,IMM) lsr RX, RY, 0x08
27 #ifdef CONFIG_ARC_HAS_LL64
28 # define LOADX(DST,RX) ldd.ab DST, [RX, 8]
29 # define STOREX(SRC,RX) std.ab SRC, [RX, 8]
33 # define LOADX(DST,RX) ld.ab DST, [RX, 4]
34 # define STOREX(SRC,RX) st.ab SRC, [RX, 4]
43 mov r3, r0 ; don;t clobber ret val
52 lpnz @.Laligndestination
59 ;;; Check the alignment of the source
61 bnz.d @.Lsourceunaligned
63 ;;; CASE 0: Both source and destination are 32bit aligned
64 ;;; Convert len to Dwords, unfold x4
65 lsr.f lp_count, r2, ZOLSHFT
66 lpnz @.Lcopy32_64bytes
78 and.f lp_count, r2, ZOLAND ;Last remaining 31 bytes
80 lpnz @.Lcopyremainingbytes
91 beq.d @.LunalignedOffby2
94 bhi.d @.LunalignedOffby3
97 ;;; CASE 1: The source is unaligned, off by 1
98 ;; Hence I need to read 1 byte for a 16bit alignment
99 ;; and 2bytes to reach 32bit alignment
102 ;; Convert to words, unfold x2
103 lsr.f lp_count, r2, 3
108 ;; Both src and dst are aligned
126 ;; Write back the remaining 16bits
127 EXTRACT_1 (r6, r5, 16)
129 ;; Write back the remaining 8bits
130 EXTRACT_2 (r5, r5, 16)
133 and.f lp_count, r2, 0x07 ;Last 8bytes
134 lpnz @.Lcopybytewise_1
142 ;;; CASE 2: The source is unaligned, off by 2
146 ;; Both src and dst are aligned
147 ;; Convert to words, unfold x2
148 lsr.f lp_count, r2, 3
149 #ifdef __BIG_ENDIAN__
169 #ifdef __BIG_ENDIAN__
174 and.f lp_count, r2, 0x07 ;Last 8bytes
175 lpnz @.Lcopybytewise_2
183 ;;; CASE 3: The source is unaligned, off by 3
184 ;;; Hence, I need to read 1byte for achieve the 32bit alignment
186 ;; Both src and dst are aligned
187 ;; Convert to words, unfold x2
188 lsr.f lp_count, r2, 3
189 #ifdef __BIG_ENDIAN__
209 #ifdef __BIG_ENDIAN__
214 and.f lp_count, r2, 0x07 ;Last 8bytes
215 lpnz @.Lcopybytewise_3