Adrian Bunk | b00dc83 | 2008-05-19 16:52:27 -0700 | [diff] [blame] | 1 | /* |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2 | * strncpy_from_user.S: Sparc64 strncpy from userspace. |
| 3 | * |
| 4 | * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz) |
| 5 | */ |
| 6 | |
| 7 | #include <asm/asi.h> |
| 8 | #include <asm/errno.h> |
| 9 | |
| 10 | .data |
| 11 | .align 8 |
| 12 | 0: .xword 0x0101010101010101 |
| 13 | |
| 14 | .text |
| 15 | .align 32 |
| 16 | |
| 17 | /* Must return: |
| 18 | * |
| 19 | * -EFAULT for an exception |
| 20 | * count if we hit the buffer limit |
| 21 | * bytes copied if we hit a null byte |
| 22 | * (without the null byte) |
| 23 | * |
| 24 | * This implementation assumes: |
| 25 | * %o1 is 8 aligned => !(%o2 & 7) |
| 26 | * %o0 is 8 aligned (if not, it will be slooooow, but will work) |
| 27 | * |
| 28 | * This is optimized for the common case: |
| 29 | * in my stats, 90% of src are 8 aligned (even on sparc32) |
| 30 | * and average length is 18 or so. |
| 31 | */ |
| 32 | |
| 33 | .globl __strncpy_from_user |
| 34 | .type __strncpy_from_user,#function |
| 35 | __strncpy_from_user: |
| 36 | /* %o0=dest, %o1=src, %o2=count */ |
| 37 | andcc %o1, 7, %g0 ! IEU1 Group |
| 38 | bne,pn %icc, 30f ! CTI |
| 39 | add %o0, %o2, %g3 ! IEU0 |
| 40 | 60: ldxa [%o1] %asi, %g1 ! Load Group |
| 41 | brlez,pn %o2, 10f ! CTI |
| 42 | mov %o0, %o3 ! IEU0 |
| 43 | 50: sethi %hi(0b), %o4 ! IEU0 Group |
| 44 | ldx [%o4 + %lo(0b)], %o4 ! Load |
| 45 | sllx %o4, 7, %o5 ! IEU1 Group |
| 46 | 1: sub %g1, %o4, %g2 ! IEU0 Group |
| 47 | stx %g1, [%o0] ! Store |
| 48 | add %o0, 8, %o0 ! IEU1 |
| 49 | andcc %g2, %o5, %g0 ! IEU1 Group |
| 50 | bne,pn %xcc, 5f ! CTI |
| 51 | add %o1, 8, %o1 ! IEU0 |
| 52 | cmp %o0, %g3 ! IEU1 Group |
| 53 | bl,a,pt %xcc, 1b ! CTI |
| 54 | 61: ldxa [%o1] %asi, %g1 ! Load |
| 55 | 10: retl ! CTI Group |
| 56 | mov %o2, %o0 ! IEU0 |
| 57 | 5: srlx %g2, 32, %g7 ! IEU0 Group |
| 58 | sethi %hi(0xff00), %o4 ! IEU1 |
| 59 | andcc %g7, %o5, %g0 ! IEU1 Group |
| 60 | be,pn %icc, 2f ! CTI |
| 61 | or %o4, %lo(0xff00), %o4 ! IEU0 |
| 62 | srlx %g1, 48, %g7 ! IEU0 Group |
| 63 | andcc %g7, %o4, %g0 ! IEU1 Group |
| 64 | be,pn %icc, 50f ! CTI |
| 65 | andcc %g7, 0xff, %g0 ! IEU1 Group |
| 66 | be,pn %icc, 51f ! CTI |
| 67 | srlx %g1, 32, %g7 ! IEU0 |
| 68 | andcc %g7, %o4, %g0 ! IEU1 Group |
| 69 | be,pn %icc, 52f ! CTI |
| 70 | andcc %g7, 0xff, %g0 ! IEU1 Group |
| 71 | be,pn %icc, 53f ! CTI |
| 72 | 2: andcc %g2, %o5, %g0 ! IEU1 Group |
| 73 | be,pn %icc, 2f ! CTI |
| 74 | srl %g1, 16, %g7 ! IEU0 |
| 75 | andcc %g7, %o4, %g0 ! IEU1 Group |
| 76 | be,pn %icc, 54f ! CTI |
| 77 | andcc %g7, 0xff, %g0 ! IEU1 Group |
| 78 | be,pn %icc, 55f ! CTI |
| 79 | andcc %g1, %o4, %g0 ! IEU1 Group |
| 80 | be,pn %icc, 56f ! CTI |
| 81 | andcc %g1, 0xff, %g0 ! IEU1 Group |
| 82 | be,a,pn %icc, 57f ! CTI |
| 83 | sub %o0, %o3, %o0 ! IEU0 |
| 84 | 2: cmp %o0, %g3 ! IEU1 Group |
| 85 | bl,a,pt %xcc, 50b ! CTI |
| 86 | 62: ldxa [%o1] %asi, %g1 ! Load |
| 87 | retl ! CTI Group |
| 88 | mov %o2, %o0 ! IEU0 |
| 89 | 50: sub %o0, %o3, %o0 |
| 90 | retl |
| 91 | sub %o0, 8, %o0 |
| 92 | 51: sub %o0, %o3, %o0 |
| 93 | retl |
| 94 | sub %o0, 7, %o0 |
| 95 | 52: sub %o0, %o3, %o0 |
| 96 | retl |
| 97 | sub %o0, 6, %o0 |
| 98 | 53: sub %o0, %o3, %o0 |
| 99 | retl |
| 100 | sub %o0, 5, %o0 |
| 101 | 54: sub %o0, %o3, %o0 |
| 102 | retl |
| 103 | sub %o0, 4, %o0 |
| 104 | 55: sub %o0, %o3, %o0 |
| 105 | retl |
| 106 | sub %o0, 3, %o0 |
| 107 | 56: sub %o0, %o3, %o0 |
| 108 | retl |
| 109 | sub %o0, 2, %o0 |
| 110 | 57: retl |
| 111 | sub %o0, 1, %o0 |
| 112 | 30: brlez,pn %o2, 3f |
| 113 | sub %g0, %o2, %o3 |
| 114 | add %o0, %o2, %o0 |
| 115 | 63: lduba [%o1] %asi, %o4 |
| 116 | 1: add %o1, 1, %o1 |
| 117 | brz,pn %o4, 2f |
| 118 | stb %o4, [%o0 + %o3] |
| 119 | addcc %o3, 1, %o3 |
| 120 | bne,pt %xcc, 1b |
| 121 | 64: lduba [%o1] %asi, %o4 |
| 122 | 3: retl |
| 123 | mov %o2, %o0 |
| 124 | 2: retl |
| 125 | add %o2, %o3, %o0 |
| 126 | .size __strncpy_from_user, .-__strncpy_from_user |
| 127 | |
David S. Miller | 4d000d5 | 2006-03-04 23:23:56 -0800 | [diff] [blame] | 128 | .section __ex_table,"a" |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 129 | .align 4 |
David S. Miller | 5fd2975 | 2005-09-28 20:41:45 -0700 | [diff] [blame] | 130 | .word 60b, __retl_efault |
| 131 | .word 61b, __retl_efault |
| 132 | .word 62b, __retl_efault |
| 133 | .word 63b, __retl_efault |
| 134 | .word 64b, __retl_efault |
| 135 | .previous |