1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
/* $Id: strncpy_from_user.S,v 1.6 1999/05/25 16:53:05 jj Exp $
* 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 4
/* 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
__strncpy_from_user:
/* %o0=dest, %o1=src, %o2=count */
sethi %hi(0b), %o5 ! IEU0 Group
andcc %o1, 7, %g0 ! IEU1
bne,pn %icc, 30f ! CTI
ldx [%o5 + %lo(0b)], %o4 ! Load Group
add %o0, %o2, %g3 ! IEU0
60: ldxa [%o1] %asi, %g1 ! Load Group
brlez,pn %o2, 10f ! CTI
sllx %o4, 7, %o5 ! IEU0 Group
mov %o0, %o3 ! IEU1
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), %g5 ! IEU1
andcc %g7, %o5, %g0 ! IEU1 Group
be,pn %icc, 2f ! CTI
or %g5, %lo(0xff00), %g5 ! IEU0
srlx %g1, 48, %g7 ! IEU0 Group
andcc %g7, %g5, %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, %g5, %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, %g5, %g0 ! IEU1 Group
be,pn %icc, 54f ! CTI
andcc %g7, 0xff, %g0 ! IEU1 Group
be,pn %icc, 55f ! CTI
andcc %g1, %g5, %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, 1b ! 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
.section .fixup,#alloc,#execinstr
.align 4
4: retl
mov -EFAULT, %o0
.section __ex_table,#alloc
.align 4
.word 60b, 4b
.word 61b, 4b
.word 62b, 4b
.word 63b, 4b
.word 64b, 4b
|