···55# it under the terms of the GNU General Public License version 2 as66# published by the Free Software Foundation.7788-lib-y := strchr-700.o strcmp.o strcpy-700.o strlen.o99-lib-y += memcmp.o memcpy-700.o memset.o88+lib-y := strchr-700.o strcpy-700.o strlen.o memcmp.o99+1010+lib-$(CONFIG_ISA_ARCOMPACT) += memcpy-700.o memset.o strcmp.o1111+lib-$(CONFIG_ISA_ARCV2) += memcpy-archs.o memset-archs.o strcmp-archs.o
+236
arch/arc/lib/memcpy-archs.S
···11+/*22+ * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com)33+ *44+ * This program is free software; you can redistribute it and/or modify55+ * it under the terms of the GNU General Public License version 2 as66+ * published by the Free Software Foundation.77+ */88+99+#include <linux/linkage.h>1010+1111+#ifdef __LITTLE_ENDIAN__1212+# define SHIFT_1(RX,RY,IMM) asl RX, RY, IMM ; <<1313+# define SHIFT_2(RX,RY,IMM) lsr RX, RY, IMM ; >>1414+# define MERGE_1(RX,RY,IMM) asl RX, RY, IMM1515+# define MERGE_2(RX,RY,IMM)1616+# define EXTRACT_1(RX,RY,IMM) and RX, RY, 0xFFFF1717+# define EXTRACT_2(RX,RY,IMM) lsr RX, RY, IMM1818+#else1919+# define SHIFT_1(RX,RY,IMM) lsr RX, RY, IMM ; >>2020+# define SHIFT_2(RX,RY,IMM) asl RX, RY, IMM ; <<2121+# define MERGE_1(RX,RY,IMM) asl RX, RY, IMM ; <<2222+# define MERGE_2(RX,RY,IMM) asl RX, RY, IMM ; <<2323+# define EXTRACT_1(RX,RY,IMM) lsr RX, RY, IMM2424+# define EXTRACT_2(RX,RY,IMM) lsr RX, RY, 0x082525+#endif2626+2727+#ifdef CONFIG_ARC_HAS_LL642828+# define PREFETCH_READ(RX) prefetch [RX, 56]2929+# define PREFETCH_WRITE(RX) prefetchw [RX, 64]3030+# define LOADX(DST,RX) ldd.ab DST, [RX, 8]3131+# define STOREX(SRC,RX) std.ab SRC, [RX, 8]3232+# define ZOLSHFT 53333+# define ZOLAND 0x1F3434+#else3535+# define PREFETCH_READ(RX) prefetch [RX, 28]3636+# define PREFETCH_WRITE(RX) prefetchw [RX, 32]3737+# define LOADX(DST,RX) ld.ab DST, [RX, 4]3838+# define STOREX(SRC,RX) st.ab SRC, [RX, 4]3939+# define ZOLSHFT 44040+# define ZOLAND 0xF4141+#endif4242+4343+ENTRY(memcpy)4444+ prefetch [r1] ; Prefetch the read location4545+ prefetchw [r0] ; Prefetch the write location4646+ mov.f 0, r24747+;;; if size is zero4848+ jz.d [blink]4949+ mov r3, r0 ; don;t clobber ret val5050+5151+;;; if size <= 85252+ cmp r2, 85353+ bls.d @smallchunk5454+ mov.f lp_count, r25555+5656+ and.f r4, r0, 0x035757+ rsub lp_count, r4, 45858+ lpnz @aligndestination5959+ ;; LOOP BEGIN6060+ ldb.ab r5, [r1,1]6161+ sub r2, r2, 16262+ stb.ab r5, [r3,1]6363+aligndestination:6464+6565+;;; Check the alignment of the source6666+ and.f r4, r1, 0x036767+ bnz.d @sourceunaligned6868+6969+;;; CASE 0: Both source and destination are 32bit aligned7070+;;; Convert len to Dwords, unfold x47171+ lsr.f lp_count, r2, ZOLSHFT7272+ lpnz @copy32_64bytes7373+ ;; LOOP START7474+ LOADX (r6, r1)7575+ PREFETCH_READ (r1)7676+ PREFETCH_WRITE (r3)7777+ LOADX (r8, r1)7878+ LOADX (r10, r1)7979+ LOADX (r4, r1)8080+ STOREX (r6, r3)8181+ STOREX (r8, r3)8282+ STOREX (r10, r3)8383+ STOREX (r4, r3)8484+copy32_64bytes:8585+8686+ and.f lp_count, r2, ZOLAND ;Last remaining 31 bytes8787+smallchunk:8888+ lpnz @copyremainingbytes8989+ ;; LOOP START9090+ ldb.ab r5, [r1,1]9191+ stb.ab r5, [r3,1]9292+copyremainingbytes:9393+9494+ j [blink]9595+;;; END CASE 09696+9797+sourceunaligned:9898+ cmp r4, 29999+ beq.d @unalignedOffby2100100+ sub r2, r2, 1101101+102102+ bhi.d @unalignedOffby3103103+ ldb.ab r5, [r1, 1]104104+105105+;;; CASE 1: The source is unaligned, off by 1106106+ ;; Hence I need to read 1 byte for a 16bit alignment107107+ ;; and 2bytes to reach 32bit alignment108108+ ldh.ab r6, [r1, 2]109109+ sub r2, r2, 2110110+ ;; Convert to words, unfold x2111111+ lsr.f lp_count, r2, 3112112+ MERGE_1 (r6, r6, 8)113113+ MERGE_2 (r5, r5, 24)114114+ or r5, r5, r6115115+116116+ ;; Both src and dst are aligned117117+ lpnz @copy8bytes_1118118+ ;; LOOP START119119+ ld.ab r6, [r1, 4]120120+ prefetch [r1, 28] ;Prefetch the next read location121121+ ld.ab r8, [r1,4]122122+ prefetchw [r3, 32] ;Prefetch the next write location123123+124124+ SHIFT_1 (r7, r6, 24)125125+ or r7, r7, r5126126+ SHIFT_2 (r5, r6, 8)127127+128128+ SHIFT_1 (r9, r8, 24)129129+ or r9, r9, r5130130+ SHIFT_2 (r5, r8, 8)131131+132132+ st.ab r7, [r3, 4]133133+ st.ab r9, [r3, 4]134134+copy8bytes_1:135135+136136+ ;; Write back the remaining 16bits137137+ EXTRACT_1 (r6, r5, 16)138138+ sth.ab r6, [r3, 2]139139+ ;; Write back the remaining 8bits140140+ EXTRACT_2 (r5, r5, 16)141141+ stb.ab r5, [r3, 1]142142+143143+ and.f lp_count, r2, 0x07 ;Last 8bytes144144+ lpnz @copybytewise_1145145+ ;; LOOP START146146+ ldb.ab r6, [r1,1]147147+ stb.ab r6, [r3,1]148148+copybytewise_1:149149+ j [blink]150150+151151+unalignedOffby2:152152+;;; CASE 2: The source is unaligned, off by 2153153+ ldh.ab r5, [r1, 2]154154+ sub r2, r2, 1155155+156156+ ;; Both src and dst are aligned157157+ ;; Convert to words, unfold x2158158+ lsr.f lp_count, r2, 3159159+#ifdef __BIG_ENDIAN__160160+ asl.nz r5, r5, 16161161+#endif162162+ lpnz @copy8bytes_2163163+ ;; LOOP START164164+ ld.ab r6, [r1, 4]165165+ prefetch [r1, 28] ;Prefetch the next read location166166+ ld.ab r8, [r1,4]167167+ prefetchw [r3, 32] ;Prefetch the next write location168168+169169+ SHIFT_1 (r7, r6, 16)170170+ or r7, r7, r5171171+ SHIFT_2 (r5, r6, 16)172172+173173+ SHIFT_1 (r9, r8, 16)174174+ or r9, r9, r5175175+ SHIFT_2 (r5, r8, 16)176176+177177+ st.ab r7, [r3, 4]178178+ st.ab r9, [r3, 4]179179+copy8bytes_2:180180+181181+#ifdef __BIG_ENDIAN__182182+ lsr.nz r5, r5, 16183183+#endif184184+ sth.ab r5, [r3, 2]185185+186186+ and.f lp_count, r2, 0x07 ;Last 8bytes187187+ lpnz @copybytewise_2188188+ ;; LOOP START189189+ ldb.ab r6, [r1,1]190190+ stb.ab r6, [r3,1]191191+copybytewise_2:192192+ j [blink]193193+194194+unalignedOffby3:195195+;;; CASE 3: The source is unaligned, off by 3196196+;;; Hence, I need to read 1byte for achieve the 32bit alignment197197+198198+ ;; Both src and dst are aligned199199+ ;; Convert to words, unfold x2200200+ lsr.f lp_count, r2, 3201201+#ifdef __BIG_ENDIAN__202202+ asl.ne r5, r5, 24203203+#endif204204+ lpnz @copy8bytes_3205205+ ;; LOOP START206206+ ld.ab r6, [r1, 4]207207+ prefetch [r1, 28] ;Prefetch the next read location208208+ ld.ab r8, [r1,4]209209+ prefetch [r3, 32] ;Prefetch the next write location210210+211211+ SHIFT_1 (r7, r6, 8)212212+ or r7, r7, r5213213+ SHIFT_2 (r5, r6, 24)214214+215215+ SHIFT_1 (r9, r8, 8)216216+ or r9, r9, r5217217+ SHIFT_2 (r5, r8, 24)218218+219219+ st.ab r7, [r3, 4]220220+ st.ab r9, [r3, 4]221221+copy8bytes_3:222222+223223+#ifdef __BIG_ENDIAN__224224+ lsr.nz r5, r5, 24225225+#endif226226+ stb.ab r5, [r3, 1]227227+228228+ and.f lp_count, r2, 0x07 ;Last 8bytes229229+ lpnz @copybytewise_3230230+ ;; LOOP START231231+ ldb.ab r6, [r1,1]232232+ stb.ab r6, [r3,1]233233+copybytewise_3:234234+ j [blink]235235+236236+END(memcpy)
+93
arch/arc/lib/memset-archs.S
···11+/*22+ * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com)33+ *44+ * This program is free software; you can redistribute it and/or modify55+ * it under the terms of the GNU General Public License version 2 as66+ * published by the Free Software Foundation.77+ */88+99+#include <linux/linkage.h>1010+1111+#undef PREALLOC_NOT_AVAIL1212+1313+#ifdef PREALLOC_NOT_AVAIL1414+#define PREWRITE(A,B) prefetchw [(A),(B)]1515+#else1616+#define PREWRITE(A,B) prealloc [(A),(B)]1717+#endif1818+1919+ENTRY(memset)2020+ prefetchw [r0] ; Prefetch the write location2121+ mov.f 0, r22222+;;; if size is zero2323+ jz.d [blink]2424+ mov r3, r0 ; don't clobber ret val2525+2626+;;; if length < 82727+ brls.d.nt r2, 8, .Lsmallchunk2828+ mov.f lp_count,r22929+3030+ and.f r4, r0, 0x033131+ rsub lp_count, r4, 43232+ lpnz @.Laligndestination3333+ ;; LOOP BEGIN3434+ stb.ab r1, [r3,1]3535+ sub r2, r2, 13636+.Laligndestination:3737+3838+;;; Destination is aligned3939+ and r1, r1, 0xFF4040+ asl r4, r1, 84141+ or r4, r4, r14242+ asl r5, r4, 164343+ or r5, r5, r44444+ mov r4, r54545+4646+ sub3 lp_count, r2, 84747+ cmp r2, 644848+ bmsk.hi r2, r2, 54949+ mov.ls lp_count, 05050+ add3.hi r2, r2, 85151+5252+;;; Convert len to Dwords, unfold x85353+ lsr.f lp_count, lp_count, 65454+ lpnz @.Lset64bytes5555+ ;; LOOP START5656+ PREWRITE(r3, 64) ;Prefetch the next write location5757+ std.ab r4, [r3, 8]5858+ std.ab r4, [r3, 8]5959+ std.ab r4, [r3, 8]6060+ std.ab r4, [r3, 8]6161+ std.ab r4, [r3, 8]6262+ std.ab r4, [r3, 8]6363+ std.ab r4, [r3, 8]6464+ std.ab r4, [r3, 8]6565+.Lset64bytes:6666+6767+ lsr.f lp_count, r2, 5 ;Last remaining max 124 bytes6868+ lpnz .Lset32bytes6969+ ;; LOOP START7070+ prefetchw [r3, 32] ;Prefetch the next write location7171+ std.ab r4, [r3, 8]7272+ std.ab r4, [r3, 8]7373+ std.ab r4, [r3, 8]7474+ std.ab r4, [r3, 8]7575+.Lset32bytes:7676+7777+ and.f lp_count, r2, 0x1F ;Last remaining 31 bytes7878+.Lsmallchunk:7979+ lpnz .Lcopy3bytes8080+ ;; LOOP START8181+ stb.ab r1, [r3, 1]8282+.Lcopy3bytes:8383+8484+ j [blink]8585+8686+END(memset)8787+8888+ENTRY(memzero)8989+ ; adjust bzero args to memset args9090+ mov r2, r19191+ b.d memset ;tail call so need to tinker with blink9292+ mov r1, 09393+END(memzero)
+78
arch/arc/lib/strcmp-archs.S
···11+/*22+ * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com)33+ *44+ * This program is free software; you can redistribute it and/or modify55+ * it under the terms of the GNU General Public License version 2 as66+ * published by the Free Software Foundation.77+ */88+99+#include <linux/linkage.h>1010+1111+ENTRY(strcmp)1212+ or r2, r0, r11313+ bmsk_s r2, r2, 11414+ brne r2, 0, @.Lcharloop1515+1616+;;; s1 and s2 are word aligned1717+ ld.ab r2, [r0, 4]1818+1919+ mov_s r12, 0x010101012020+ ror r11, r122121+ .align 42222+.LwordLoop:2323+ ld.ab r3, [r1, 4]2424+ ;; Detect NULL char in str12525+ sub r4, r2, r122626+ ld.ab r5, [r0, 4]2727+ bic r4, r4, r22828+ and r4, r4, r112929+ brne.d.nt r4, 0, .LfoundNULL3030+ ;; Check if the read locations are the same3131+ cmp r2, r33232+ beq.d .LwordLoop3333+ mov.eq r2, r53434+3535+ ;; A match is found, spot it out3636+#ifdef __LITTLE_ENDIAN__3737+ swape r3, r33838+ mov_s r0, 13939+ swape r2, r24040+#else4141+ mov_s r0, 14242+#endif4343+ cmp_s r2, r34444+ j_s.d [blink]4545+ bset.lo r0, r0, 314646+4747+ .align 44848+.LfoundNULL:4949+#ifdef __BIG_ENDIAN__5050+ swape r4, r45151+ swape r2, r25252+ swape r3, r35353+#endif5454+ ;; Find null byte5555+ ffs r0, r45656+ bmsk r2, r2, r05757+ bmsk r3, r3, r05858+ swape r2, r25959+ swape r3, r36060+ ;; make the return value6161+ sub.f r0, r2, r36262+ mov.hi r0, 16363+ j_s.d [blink]6464+ bset.lo r0, r0, 316565+6666+ .align 46767+.Lcharloop:6868+ ldb.ab r2, [r0, 1]6969+ ldb.ab r3, [r1, 1]7070+ nop7171+ breq r2, 0, .Lcmpend7272+ breq r2, r3, .Lcharloop7373+7474+ .align 47575+.Lcmpend:7676+ j_s.d [blink]7777+ sub r0, r2, r37878+END(strcmp)