Back to home page

LXR

 
 

    


0001 /*
0002  * This file is subject to the terms and conditions of the GNU General Public
0003  * License.  See the file "COPYING" in the main directory of this archive
0004  * for more details.
0005  *
0006  * Copyright (c) 1996, 1998, 1999, 2004 by Ralf Baechle
0007  * Copyright (c) 1999 Silicon Graphics, Inc.
0008  */
0009 #include <asm/asm.h>
0010 #include <asm/asm-offsets.h>
0011 #include <asm/regdef.h>
0012 
0013 #define EX(insn,reg,addr,handler)           \
0014 9:  insn    reg, addr;              \
0015     .section __ex_table,"a";            \
0016     PTR 9b, handler;                \
0017     .previous
0018 
0019 /*
0020  * Return the size of a string including the ending NUL character up to a
0021  * maximum of a1 or 0 in case of error.
0022  *
0023  * Note: for performance reasons we deliberately accept that a user may
0024  *   make strlen_user and strnlen_user access the first few KSEG0
0025  *   bytes.  There's nothing secret there.  On 64-bit accessing beyond
0026  *   the maximum is a tad hairier ...
0027  */
0028     .macro __BUILD_STRNLEN_ASM func
0029 LEAF(__strnlen_\func\()_asm)
0030     LONG_L      v0, TI_ADDR_LIMIT($28)  # pointer ok?
0031     and     v0, a0
0032     bnez        v0, .Lfault\@
0033 
0034 FEXPORT(__strnlen_\func\()_nocheck_asm)
0035     move        v0, a0
0036     PTR_ADDU    a1, a0          # stop pointer
0037 1:
0038 #ifdef CONFIG_CPU_DADDI_WORKAROUNDS
0039     .set        noat
0040     li      AT, 1
0041 #endif
0042     beq     v0, a1, 1f      # limit reached?
0043 .ifeqs "\func", "kernel"
0044     EX(lb, t0, (v0), .Lfault\@)
0045 .else
0046     EX(lbe, t0, (v0), .Lfault\@)
0047 .endif
0048     .set        noreorder
0049     bnez        t0, 1b
0050 1:
0051 #ifndef CONFIG_CPU_DADDI_WORKAROUNDS
0052      PTR_ADDIU  v0, 1
0053 #else
0054      PTR_ADDU   v0, AT
0055     .set        at
0056 #endif
0057     .set        reorder
0058     PTR_SUBU    v0, a0
0059     jr      ra
0060     END(__strnlen_\func\()_asm)
0061 
0062 .Lfault\@:
0063     move        v0, zero
0064     jr      ra
0065     .endm
0066 
0067 #ifndef CONFIG_EVA
0068     /* Set aliases */
0069     .global __strnlen_user_asm
0070     .global __strnlen_user_nocheck_asm
0071     .set __strnlen_user_asm, __strnlen_kernel_asm
0072     .set __strnlen_user_nocheck_asm, __strnlen_kernel_nocheck_asm
0073 #endif
0074 
0075 __BUILD_STRNLEN_ASM kernel
0076 
0077 #ifdef CONFIG_EVA
0078 
0079     .set push
0080     .set eva
0081 __BUILD_STRNLEN_ASM user
0082     .set pop
0083 #endif