root/arch/sparc/string.S

/* [previous][next][first][last][top][bottom][index][help] */
   1 /*  string.h:  Efficient string functions in sparc-assembly for
   2                the linux kernel.
   3 
   4     Copyright 1994 (c) David S. Miller (davem@caip.rutgers.edu)
   5 */
   6 
   7 
   8 /* If we are smart we will use only the output and global registers 
   9    as that will allow us to avoid a window save which would be nice.
  10 */
  11 
  12 /* Believe it or not the following strlen is not optimized enough!
  13    In the future I may play games with doing word reads and reducing
  14    the per-word comparisons to *one*, yes I have seen it done.
  15 */
  16         .align 4
  17         .globl _strlen
  18 _strlen:
  19         mov     %o0, %g3        ! leaf-procedure optimization, here
  20         ldsb    [%g3], %g2      ! I only use the register sent to me
  21         cmp     %g2, 0          ! and the globals. Now, this routine
  22         be      1f              ! is callable from boot code.
  23         nop
  24         add     %o0, 1, %o0
  25 0:      ldsb    [%o0], %g2
  26         cmp     %g2, 0
  27         bne,a   0b              ! annulling branch, yuck
  28         add     %o0, 1, %o0
  29 
  30 1:      retl
  31         sub     %o0, %g3, %o0   ! since %g3 holds the original pointer
  32                                 ! and %o0 is at the end byte, we can
  33                                 ! subtract and the result is strlen.
  34 
  35 /* String concatenate function. I am too lazy to honor the third count
  36    argument at this time. Once again, this could be optimized so much
  37    more to use word accesses instead of slooow byte loads.
  38 */
  39         .align 4
  40         .globl _strcat
  41 _strcat:
  42         mov     %o0, %g4
  43         ldsb    [%g4], %g3
  44         cmp     %g3, 0
  45         be,a    2f
  46         ldub    [%o1], %g3
  47         add     %o0, 1, %o0
  48         
  49 0:      ldsb    [%o0], %g3
  50         cmp     %g3, 0
  51         bne,a   0b
  52         add     %o0, 1, %o0
  53 
  54 1:      ldub    [%o1], %g3
  55 
  56 2:      add     %o1, 1, %o1
  57         stb     %g3, [%o0]
  58         cmp     %g3, 0
  59         bne     1b
  60         add     %o0, 1, %o0
  61         retl
  62         mov     %g4, %o0
  63 
  64 /* Aieee, this code is starting to give me a headache. I shouldn't
  65    have tried to do this in one sitting :-(
  66 */
  67 
  68         .align 4
  69         .globl _strcmp
  70 _strcmp:        b       2f
  71                 ldsb    [%o1], %g4
  72 
  73 0:              sll     %o2, 24, %g3
  74                 cmp     %g3, 0
  75                 bne     1f
  76                 add     %o0, 1, %o0
  77                 b       3f
  78                 or      %g0, %g0, %o0
  79 
  80 1:              ldsb    [%o1], %g4
  81 
  82 2:              ldsb    [%o0], %g3
  83                 add     %o1, 1, %o1
  84                 cmp     %g3, %g4
  85                 be      0b
  86                 mov     %g3, %o2
  87                 ldub    [%o2], %g3
  88                 ldub    [%o1-1], %o0            ! oh man, no joke
  89                 sub     %g2, %o0, %o0
  90 
  91 3:              retl
  92                 nop
  93 
  94 /* Ok, strcpy() should be easy enough. Maybe I catch some sleep after 
  95    this one....
  96 */
  97         .align 4
  98         .globl _strcpy
  99 _strcpy:        ldub    [%o1], %g3
 100                 mov     %o0, %g4
 101                 cmp     %g3, 0
 102                 be      1f
 103                 stb     %g3, [%g4]
 104 
 105 0:              add     %o1, 1, %o1
 106                 ldub    [%o1], %g3
 107                 add     %o0, 1, %o0
 108                 cmp     %g3, 0
 109                 bne     0b
 110                 stb     %g3, [%o0]
 111 
 112 1:              retl
 113                 mov     %g4, %o0
 114 
 115         

/* [previous][next][first][last][top][bottom][index][help] */