/*1* arch/xtensa/lib/memset.S2*3* ANSI C standard library function memset4* (Well, almost. .fixup code might return zero.)5*6* This file is subject to the terms and conditions of the GNU General7* Public License. See the file "COPYING" in the main directory of8* this archive for more details.9*10* Copyright (C) 2002 Tensilica Inc.11*/1213#include <linux/linkage.h>14#include <asm/asmmacro.h>15#include <asm/core.h>1617/*18* void *memset(void *dst, int c, size_t length)19*20* The algorithm is as follows:21* Create a word with c in all byte positions22* If the destination is aligned,23* do 16B chucks with a loop, and then finish up with24* 8B, 4B, 2B, and 1B stores conditional on the length.25* If destination is unaligned, align it by conditionally26* setting 1B and 2B and then go to aligned case.27* This code tries to use fall-through branches for the common28* case of an aligned destination (except for the branches to29* the alignment labels).30*/3132.text33ENTRY(__memset)34WEAK(memset)3536abi_entry_default37# a2/ dst, a3/ c, a4/ length38extui a3, a3, 0, 8 # mask to just 8 bits39slli a7, a3, 8 # duplicate character in all bytes of word40or a3, a3, a7 # ...41slli a7, a3, 16 # ...42or a3, a3, a7 # ...43mov a5, a2 # copy dst so that a2 is return value44movi a6, 3 # for alignment tests45bany a2, a6, .Ldstunaligned # if dst is unaligned46.L0: # return here from .Ldstunaligned when dst is aligned47srli a7, a4, 4 # number of loop iterations with 16B48# per iteration49bnez a4, .Laligned50abi_ret_default5152/*53* Destination is word-aligned.54*/55# set 16 bytes per iteration for word-aligned dst56.align 4 # 1 mod 4 alignment for LOOPNEZ57.byte 0 # (0 mod 4 alignment for LBEG)58.Laligned:59#if XCHAL_HAVE_LOOPS60loopnez a7, .Loop1done61#else /* !XCHAL_HAVE_LOOPS */62beqz a7, .Loop1done63slli a6, a7, 464add a6, a6, a5 # a6 = end of last 16B chunk65#endif /* !XCHAL_HAVE_LOOPS */66.Loop1:67EX(10f) s32i a3, a5, 068EX(10f) s32i a3, a5, 469EX(10f) s32i a3, a5, 870EX(10f) s32i a3, a5, 1271addi a5, a5, 1672#if !XCHAL_HAVE_LOOPS73blt a5, a6, .Loop174#endif /* !XCHAL_HAVE_LOOPS */75.Loop1done:76bbci.l a4, 3, .L277# set 8 bytes78EX(10f) s32i a3, a5, 079EX(10f) s32i a3, a5, 480addi a5, a5, 881.L2:82bbci.l a4, 2, .L383# set 4 bytes84EX(10f) s32i a3, a5, 085addi a5, a5, 486.L3:87bbci.l a4, 1, .L488# set 2 bytes89EX(10f) s16i a3, a5, 090addi a5, a5, 291.L4:92bbci.l a4, 0, .L593# set 1 byte94EX(10f) s8i a3, a5, 095.L5:96.Lret1:97abi_ret_default9899/*100* Destination is unaligned101*/102103.Ldstunaligned:104bltui a4, 8, .Lbyteset # do short copies byte by byte105bbci.l a5, 0, .L20 # branch if dst alignment half-aligned106# dst is only byte aligned107# set 1 byte108EX(10f) s8i a3, a5, 0109addi a5, a5, 1110addi a4, a4, -1111# now retest if dst aligned112bbci.l a5, 1, .L0 # if now aligned, return to main algorithm113.L20:114# dst half-aligned115# set 2 bytes116EX(10f) s16i a3, a5, 0117addi a5, a5, 2118addi a4, a4, -2119j .L0 # dst is now aligned, return to main algorithm120121/*122* Byte by byte set123*/124.align 4125.byte 0 # 1 mod 4 alignment for LOOPNEZ126# (0 mod 4 alignment for LBEG)127.Lbyteset:128#if XCHAL_HAVE_LOOPS129loopnez a4, .Lbytesetdone130#else /* !XCHAL_HAVE_LOOPS */131beqz a4, .Lbytesetdone132add a6, a5, a4 # a6 = ending address133#endif /* !XCHAL_HAVE_LOOPS */134.Lbyteloop:135EX(10f) s8i a3, a5, 0136addi a5, a5, 1137#if !XCHAL_HAVE_LOOPS138blt a5, a6, .Lbyteloop139#endif /* !XCHAL_HAVE_LOOPS */140.Lbytesetdone:141abi_ret_default142143ENDPROC(__memset)144EXPORT_SYMBOL(__memset)145EXPORT_SYMBOL(memset)146147.section .fixup, "ax"148.align 4149150/* We return zero if a failure occurred. */15115210:153movi a2, 0154abi_ret_default155156157