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