| 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 | |
| 15 | |
| 16 | |
| 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 | |
| 39 | extui a3, a3, 0, 8 |
| 40 | slli a7, a3, 8 |
| 41 | or a3, a3, a7 |
| 42 | slli a7, a3, 16 |
| 43 | or a3, a3, a7 |
| 44 | mov a5, a2 |
| 45 | movi a6, 3 |
| 46 | bany a2, a6, .Ldstunaligned |
| 47 | .L0: |
| 48 | srli a7, a4, 4 |
| 49 | |
| 50 | bnez a4, .Laligned
|
| 51 | abi_ret_default
|
| 52 |
|
| 53 | /*
|
| 54 | * Destination is word-aligned.
|
| 55 | */
|
| 56 | |
| 57 | .align 4 |
| 58 | .byte 0 |
| 59 | .Laligned:
|
| 60 | |
| 61 | loopnez a7, .Loop1done
|
| 62 | |
| 63 | beqz a7, .Loop1done
|
| 64 | slli a6, a7, 4
|
| 65 | add a6, a6, a5 |
| 66 | |
| 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 | |
| 74 | blt a5, a6, .Loop1
|
| 75 | |
| 76 | .Loop1done:
|
| 77 | bbci.l a4, 3, .L2
|
| 78 | |
| 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 | |
| 85 | EX(10f) s32i a3, a5, 0
|
| 86 | addi a5, a5, 4
|
| 87 | .L3:
|
| 88 | bbci.l a4, 1, .L4
|
| 89 | |
| 90 | EX(10f) s16i a3, a5, 0
|
| 91 | addi a5, a5, 2
|
| 92 | .L4:
|
| 93 | bbci.l a4, 0, .L5
|
| 94 | |
| 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 |
| 106 | bbci.l a5, 0, .L20 |
| 107 | |
| 108 | |
| 109 | EX(10f) s8i a3, a5, 0
|
| 110 | addi a5, a5, 1
|
| 111 | addi a4, a4, -1
|
| 112 | |
| 113 | bbci.l a5, 1, .L0 |
| 114 | .L20:
|
| 115 | |
| 116 | |
| 117 | EX(10f) s16i a3, a5, 0
|
| 118 | addi a5, a5, 2
|
| 119 | addi a4, a4, -2
|
| 120 | j .L0 |
| 121 |
|
| 122 | /*
|
| 123 | * Byte by byte set
|
| 124 | */
|
| 125 | .align 4
|
| 126 | .byte 0 |
| 127 | |
| 128 | .Lbyteset:
|
| 129 | |
| 130 | loopnez a4, .Lbytesetdone
|
| 131 | |
| 132 | beqz a4, .Lbytesetdone
|
| 133 | add a6, a5, a4 |
| 134 | |
| 135 | .Lbyteloop:
|
| 136 | EX(10f) s8i a3, a5, 0
|
| 137 | addi a5, a5, 1
|
| 138 | |
| 139 | blt a5, a6, .Lbyteloop
|
| 140 | |
| 141 | .Lbytesetdone:
|
| 142 | abi_ret_default
|
| 143 |
|
| 144 | ENDPROC(__memset)
|
| 145 | EXPORT_SYMBOL(__memset)
|
| 146 | EXPORT_SYMBOL(memset)
|
| 147 |
|
| 148 | .section .fixup, "ax"
|
| 149 | .align 4
|
| 150 |
|
| 151 | /* We return zero if a failure occurred. */
|
| 152 |
|
| 153 | 10:
|
| 154 | movi a2, 0
|
| 155 | abi_ret_default
|