]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/sparc/lib/strncpy_from_user_64.S
sparc,sparc64: unify lib/
[linux-2.6-omap-h63xx.git] / arch / sparc / lib / strncpy_from_user_64.S
diff --git a/arch/sparc/lib/strncpy_from_user_64.S b/arch/sparc/lib/strncpy_from_user_64.S
new file mode 100644 (file)
index 0000000..511c8f1
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * strncpy_from_user.S: Sparc64 strncpy from userspace.
+ *
+ *  Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz)
+ */
+
+#include <asm/asi.h>
+#include <asm/errno.h>
+
+       .data
+       .align  8
+0:     .xword  0x0101010101010101
+
+       .text
+       .align  32
+
+       /* Must return:
+        *
+        * -EFAULT              for an exception
+        * count                if we hit the buffer limit
+        * bytes copied         if we hit a null byte
+        * (without the null byte)
+        *
+        * This implementation assumes:
+        * %o1 is 8 aligned => !(%o2 & 7)
+        * %o0 is 8 aligned (if not, it will be slooooow, but will work)
+        *
+        * This is optimized for the common case:
+        * in my stats, 90% of src are 8 aligned (even on sparc32)
+        * and average length is 18 or so.
+        */
+
+       .globl  __strncpy_from_user
+       .type   __strncpy_from_user,#function
+__strncpy_from_user:
+       /* %o0=dest, %o1=src, %o2=count */
+       andcc   %o1, 7, %g0             ! IEU1  Group
+       bne,pn  %icc, 30f               ! CTI
+        add    %o0, %o2, %g3           ! IEU0
+60:    ldxa    [%o1] %asi, %g1         ! Load  Group
+       brlez,pn %o2, 10f               ! CTI
+        mov    %o0, %o3                ! IEU0
+50:    sethi   %hi(0b), %o4            ! IEU0  Group
+       ldx     [%o4 + %lo(0b)], %o4    ! Load
+       sllx    %o4, 7, %o5             ! IEU1  Group
+1:     sub     %g1, %o4, %g2           ! IEU0  Group
+       stx     %g1, [%o0]              ! Store
+       add     %o0, 8, %o0             ! IEU1
+       andcc   %g2, %o5, %g0           ! IEU1  Group
+       bne,pn  %xcc, 5f                ! CTI
+        add    %o1, 8, %o1             ! IEU0
+       cmp     %o0, %g3                ! IEU1  Group
+       bl,a,pt %xcc, 1b                ! CTI
+61:     ldxa   [%o1] %asi, %g1         ! Load
+10:    retl                            ! CTI   Group
+        mov    %o2, %o0                ! IEU0
+5:     srlx    %g2, 32, %g7            ! IEU0  Group
+       sethi   %hi(0xff00), %o4        ! IEU1
+       andcc   %g7, %o5, %g0           ! IEU1  Group
+       be,pn   %icc, 2f                ! CTI
+        or     %o4, %lo(0xff00), %o4   ! IEU0
+       srlx    %g1, 48, %g7            ! IEU0  Group
+       andcc   %g7, %o4, %g0           ! IEU1  Group
+       be,pn   %icc, 50f               ! CTI
+        andcc  %g7, 0xff, %g0          ! IEU1  Group
+       be,pn   %icc, 51f               ! CTI
+        srlx   %g1, 32, %g7            ! IEU0
+       andcc   %g7, %o4, %g0           ! IEU1  Group
+       be,pn   %icc, 52f               ! CTI
+        andcc  %g7, 0xff, %g0          ! IEU1  Group
+       be,pn   %icc, 53f               ! CTI
+2:      andcc  %g2, %o5, %g0           ! IEU1  Group
+       be,pn   %icc, 2f                ! CTI
+        srl    %g1, 16, %g7            ! IEU0
+       andcc   %g7, %o4, %g0           ! IEU1  Group
+       be,pn   %icc, 54f               ! CTI
+        andcc  %g7, 0xff, %g0          ! IEU1  Group
+       be,pn   %icc, 55f               ! CTI
+        andcc  %g1, %o4, %g0           ! IEU1  Group
+       be,pn   %icc, 56f               ! CTI
+        andcc  %g1, 0xff, %g0          ! IEU1  Group
+       be,a,pn %icc, 57f               ! CTI
+        sub    %o0, %o3, %o0           ! IEU0
+2:     cmp     %o0, %g3                ! IEU1  Group
+       bl,a,pt %xcc, 50b               ! CTI
+62:     ldxa   [%o1] %asi, %g1         ! Load
+       retl                            ! CTI   Group
+        mov    %o2, %o0                ! IEU0
+50:    sub     %o0, %o3, %o0
+       retl
+        sub    %o0, 8, %o0
+51:    sub     %o0, %o3, %o0
+       retl
+        sub    %o0, 7, %o0
+52:    sub     %o0, %o3, %o0
+       retl
+        sub    %o0, 6, %o0
+53:    sub     %o0, %o3, %o0
+       retl
+        sub    %o0, 5, %o0
+54:    sub     %o0, %o3, %o0
+       retl
+        sub    %o0, 4, %o0
+55:    sub     %o0, %o3, %o0
+       retl
+        sub    %o0, 3, %o0
+56:    sub     %o0, %o3, %o0
+       retl
+        sub    %o0, 2, %o0
+57:    retl
+        sub    %o0, 1, %o0
+30:    brlez,pn %o2, 3f
+        sub    %g0, %o2, %o3
+       add     %o0, %o2, %o0
+63:    lduba   [%o1] %asi, %o4
+1:     add     %o1, 1, %o1
+       brz,pn  %o4, 2f
+        stb    %o4, [%o0 + %o3]
+       addcc   %o3, 1, %o3
+       bne,pt  %xcc, 1b
+64:     lduba  [%o1] %asi, %o4
+3:     retl
+        mov    %o2, %o0
+2:     retl
+        add    %o2, %o3, %o0
+       .size   __strncpy_from_user, .-__strncpy_from_user
+
+       .section __ex_table,"a"
+       .align  4
+       .word   60b, __retl_efault
+       .word   61b, __retl_efault
+       .word   62b, __retl_efault
+       .word   63b, __retl_efault
+       .word   64b, __retl_efault
+       .previous