root/arch/xtensa/lib/memset.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /*
   2  *  arch/xtensa/lib/memset.S
   3  *
   4  *  ANSI C standard library function memset
   5  *  (Well, almost.  .fixup code might return zero.)
   6  *
   7  *  This file is subject to the terms and conditions of the GNU General
   8  *  Public License.  See the file "COPYING" in the main directory of
   9  *  this archive for more details.
  10  *
  11  *  Copyright (C) 2002 Tensilica Inc.
  12  */
  13 
  14 #include <linux/linkage.h>
  15 #include <asm/asmmacro.h>
  16 #include <asm/core.h>
  17 
  18 /*
  19  * void *memset(void *dst, int c, size_t length)
  20  *
  21  * The algorithm is as follows:
  22  *   Create a word with c in all byte positions
  23  *   If the destination is aligned,
  24  *     do 16B chucks with a loop, and then finish up with
  25  *     8B, 4B, 2B, and 1B stores conditional on the length.
  26  *   If destination is unaligned, align it by conditionally
  27  *     setting 1B and 2B and then go to aligned case.
  28  *   This code tries to use fall-through branches for the common
  29  *     case of an aligned destination (except for the branches to
  30  *     the alignment labels).
  31  */
  32 
  33 .text
  34 ENTRY(__memset)
  35 WEAK(memset)
  36 
  37         abi_entry_default
  38         # a2/ dst, a3/ c, a4/ length
  39         extui   a3, a3, 0, 8    # mask to just 8 bits
  40         slli    a7, a3, 8       # duplicate character in all bytes of word
  41         or      a3, a3, a7      # ...
  42         slli    a7, a3, 16      # ...
  43         or      a3, a3, a7      # ...
  44         mov     a5, a2          # copy dst so that a2 is return value
  45         movi    a6, 3           # for alignment tests
  46         bany    a2, a6, .Ldstunaligned # if dst is unaligned
  47 .L0:    # return here from .Ldstunaligned when dst is aligned
  48         srli    a7, a4, 4       # number of loop iterations with 16B
  49                                 # per iteration
  50         bnez    a4, .Laligned
  51         abi_ret_default
  52 
  53 /*
  54  * Destination is word-aligned.
  55  */
  56         # set 16 bytes per iteration for word-aligned dst
  57         .align  4               # 1 mod 4 alignment for LOOPNEZ
  58         .byte   0               # (0 mod 4 alignment for LBEG)
  59 .Laligned:
  60 #if XCHAL_HAVE_LOOPS
  61         loopnez a7, .Loop1done
  62 #else /* !XCHAL_HAVE_LOOPS */
  63         beqz    a7, .Loop1done
  64         slli    a6, a7, 4
  65         add     a6, a6, a5      # a6 = end of last 16B chunk
  66 #endif /* !XCHAL_HAVE_LOOPS */
  67 .Loop1:
  68 EX(10f) s32i    a3, a5,  0
  69 EX(10f) s32i    a3, a5,  4
  70 EX(10f) s32i    a3, a5,  8
  71 EX(10f) s32i    a3, a5, 12
  72         addi    a5, a5, 16
  73 #if !XCHAL_HAVE_LOOPS
  74         blt     a5, a6, .Loop1
  75 #endif /* !XCHAL_HAVE_LOOPS */
  76 .Loop1done:
  77         bbci.l  a4, 3, .L2
  78         # set 8 bytes
  79 EX(10f) s32i    a3, a5,  0
  80 EX(10f) s32i    a3, a5,  4
  81         addi    a5, a5,  8
  82 .L2:
  83         bbci.l  a4, 2, .L3
  84         # set 4 bytes
  85 EX(10f) s32i    a3, a5,  0
  86         addi    a5, a5,  4
  87 .L3:
  88         bbci.l  a4, 1, .L4
  89         # set 2 bytes
  90 EX(10f) s16i    a3, a5,  0
  91         addi    a5, a5,  2
  92 .L4:
  93         bbci.l  a4, 0, .L5
  94         # set 1 byte
  95 EX(10f) s8i     a3, a5,  0
  96 .L5:
  97 .Lret1:
  98         abi_ret_default
  99 
 100 /*
 101  * Destination is unaligned
 102  */
 103 
 104 .Ldstunaligned:
 105         bltui   a4, 8, .Lbyteset        # do short copies byte by byte
 106         bbci.l  a5, 0, .L20             # branch if dst alignment half-aligned
 107         # dst is only byte aligned
 108         # set 1 byte
 109 EX(10f) s8i     a3, a5,  0
 110         addi    a5, a5,  1
 111         addi    a4, a4, -1
 112         # now retest if dst aligned
 113         bbci.l  a5, 1, .L0      # if now aligned, return to main algorithm
 114 .L20:
 115         # dst half-aligned
 116         # set 2 bytes
 117 EX(10f) s16i    a3, a5,  0
 118         addi    a5, a5,  2
 119         addi    a4, a4, -2
 120         j       .L0             # dst is now aligned, return to main algorithm
 121 
 122 /*
 123  * Byte by byte set
 124  */
 125         .align  4
 126         .byte   0               # 1 mod 4 alignment for LOOPNEZ
 127                                 # (0 mod 4 alignment for LBEG)
 128 .Lbyteset:
 129 #if XCHAL_HAVE_LOOPS
 130         loopnez a4, .Lbytesetdone
 131 #else /* !XCHAL_HAVE_LOOPS */
 132         beqz    a4, .Lbytesetdone
 133         add     a6, a5, a4      # a6 = ending address
 134 #endif /* !XCHAL_HAVE_LOOPS */
 135 .Lbyteloop:
 136 EX(10f) s8i     a3, a5, 0
 137         addi    a5, a5, 1
 138 #if !XCHAL_HAVE_LOOPS
 139         blt     a5, a6, .Lbyteloop
 140 #endif /* !XCHAL_HAVE_LOOPS */
 141 .Lbytesetdone:
 142         abi_ret_default
 143 
 144 ENDPROC(__memset)
 145 
 146         .section .fixup, "ax"
 147         .align  4
 148 
 149 /* We return zero if a failure occurred. */
 150 
 151 10:
 152         movi    a2, 0
 153         abi_ret_default

/* [<][>][^][v][top][bottom][index][help] */