Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * arch/alpha/lib/strncat.S
0004  * Contributed by Richard Henderson (rth@tamu.edu)
0005  *
0006  * Append no more than COUNT characters from the null-terminated string SRC
0007  * to the null-terminated string DST.  Always null-terminate the new DST.
0008  *
0009  * This differs slightly from the semantics in libc in that we never write
0010  * past count, whereas libc may write to count+1.  This follows the generic
0011  * implementation in lib/string.c and is, IMHO, more sensible.
0012  */
0013 #include <asm/export.h>
0014     .text
0015 
0016     .align 3
0017     .globl strncat
0018     .ent strncat
0019 strncat:
0020     .frame $30, 0, $26
0021     .prologue 0
0022 
0023     mov $16, $0     # set up return value
0024     beq $18, $zerocount
0025 
0026     /* Find the end of the string.  */
0027 
0028     ldq_u   $1, 0($16)  # load first quadword ($16 may be misaligned)
0029     lda     $2, -1($31)
0030     insqh   $2, $16, $2
0031     andnot  $16, 7, $16
0032     or      $2, $1, $1
0033     cmpbge  $31, $1, $2 # bits set iff byte == 0
0034     bne     $2, $found
0035 
0036 $loop:  ldq     $1, 8($16)
0037     addq    $16, 8, $16
0038     cmpbge  $31, $1, $2
0039     beq     $2, $loop
0040 
0041 $found: negq    $2, $3      # clear all but least set bit
0042     and     $2, $3, $2
0043 
0044     and     $2, 0xf0, $3    # binary search for that set bit
0045     and $2, 0xcc, $4
0046     and $2, 0xaa, $5
0047     cmovne  $3, 4, $3
0048     cmovne  $4, 2, $4
0049     cmovne  $5, 1, $5
0050     addq    $3, $4, $3
0051     addq    $16, $5, $16
0052     addq    $16, $3, $16
0053 
0054     /* Now do the append.  */
0055 
0056     bsr $23, __stxncpy
0057 
0058     /* Worry about the null termination.  */
0059 
0060     zapnot  $1, $27, $2 # was last byte a null?
0061     bne $2, 0f
0062     ret
0063 
0064 0:  cmplt   $27, $24, $2    # did we fill the buffer completely?
0065     or  $2, $18, $2
0066     bne $2, 2f
0067 
0068     and $24, 0x80, $2   # no zero next byte
0069     bne $2, 1f
0070 
0071     /* Here there are bytes left in the current word.  Clear one.  */
0072     addq    $24, $24, $24   # end-of-count bit <<= 1
0073 2:  zap $1, $24, $1
0074     stq_u   $1, 0($16)
0075     ret
0076 
0077 1:  /* Here we must read the next DST word and clear the first byte.  */
0078     ldq_u   $1, 8($16)
0079     zap $1, 1, $1
0080     stq_u   $1, 8($16)
0081 
0082 $zerocount:
0083     ret
0084 
0085     .end strncat
0086     EXPORT_SYMBOL(strncat)