xref: /kernel/linux/linux-5.10/arch/csky/abiv2/memset.S (revision 8c2ecf20)
18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci#include <linux/linkage.h>
58c2ecf20Sopenharmony_ci#include "sysdep.h"
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci	.weak memset
88c2ecf20Sopenharmony_ciENTRY(__memset)
98c2ecf20Sopenharmony_ciENTRY(memset)
108c2ecf20Sopenharmony_ci	/* Test if len less than 4 bytes.  */
118c2ecf20Sopenharmony_ci	mov	r12, r0
128c2ecf20Sopenharmony_ci	cmplti	r2, 8
138c2ecf20Sopenharmony_ci	bt	.L_set_by_byte
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci	andi	r13, r0, 3
168c2ecf20Sopenharmony_ci	movi	r19, 4
178c2ecf20Sopenharmony_ci	/* Test if dest is not 4 bytes aligned.  */
188c2ecf20Sopenharmony_ci	bnez	r13, .L_dest_not_aligned
198c2ecf20Sopenharmony_ci	/* Hardware can handle unaligned access directly.  */
208c2ecf20Sopenharmony_ci.L_dest_aligned:
218c2ecf20Sopenharmony_ci        zextb   r3, r1
228c2ecf20Sopenharmony_ci        lsli    r1, 8
238c2ecf20Sopenharmony_ci        or      r1, r3
248c2ecf20Sopenharmony_ci        lsli    r3, r1, 16
258c2ecf20Sopenharmony_ci        or      r3, r1
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci	/* If dest is aligned, then copy.  */
288c2ecf20Sopenharmony_ci	zext	r18, r2, 31, 4
298c2ecf20Sopenharmony_ci	/* Test if len less than 16 bytes.  */
308c2ecf20Sopenharmony_ci	bez	r18, .L_len_less_16bytes
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci	LABLE_ALIGN
338c2ecf20Sopenharmony_ci.L_len_larger_16bytes:
348c2ecf20Sopenharmony_ci	stw	r3, (r0, 0)
358c2ecf20Sopenharmony_ci	stw	r3, (r0, 4)
368c2ecf20Sopenharmony_ci	stw	r3, (r0, 8)
378c2ecf20Sopenharmony_ci	stw	r3, (r0, 12)
388c2ecf20Sopenharmony_ci	PRE_BNEZAD (r18)
398c2ecf20Sopenharmony_ci	addi	r0, 16
408c2ecf20Sopenharmony_ci	BNEZAD (r18, .L_len_larger_16bytes)
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci.L_len_less_16bytes:
438c2ecf20Sopenharmony_ci	zext	r18, r2, 3, 2
448c2ecf20Sopenharmony_ci	andi	r2, 3
458c2ecf20Sopenharmony_ci	bez	r18, .L_set_by_byte
468c2ecf20Sopenharmony_ci.L_len_less_16bytes_loop:
478c2ecf20Sopenharmony_ci	stw	r3, (r0, 0)
488c2ecf20Sopenharmony_ci	PRE_BNEZAD (r18)
498c2ecf20Sopenharmony_ci	addi	r0, 4
508c2ecf20Sopenharmony_ci	BNEZAD (r18, .L_len_less_16bytes_loop)
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	/* Test if len less than 4 bytes.  */
538c2ecf20Sopenharmony_ci.L_set_by_byte:
548c2ecf20Sopenharmony_ci	zext	r18, r2, 2, 0
558c2ecf20Sopenharmony_ci	bez	r18, .L_return
568c2ecf20Sopenharmony_ci.L_set_by_byte_loop:
578c2ecf20Sopenharmony_ci	stb	r1, (r0, 0)
588c2ecf20Sopenharmony_ci	PRE_BNEZAD (r18)
598c2ecf20Sopenharmony_ci	addi	r0, 1
608c2ecf20Sopenharmony_ci	BNEZAD (r18, .L_set_by_byte_loop)
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci.L_return:
638c2ecf20Sopenharmony_ci	mov	r0, r12
648c2ecf20Sopenharmony_ci	rts
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	/* If dest is not aligned, just set some bytes makes the dest
678c2ecf20Sopenharmony_ci	   align.  */
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci.L_dest_not_aligned:
708c2ecf20Sopenharmony_ci	sub	r13, r19, r13
718c2ecf20Sopenharmony_ci	sub	r2, r13
728c2ecf20Sopenharmony_ci.L_dest_not_aligned_loop:
738c2ecf20Sopenharmony_ci	/* Makes the dest align.  */
748c2ecf20Sopenharmony_ci	stb	r1, (r0, 0)
758c2ecf20Sopenharmony_ci	PRE_BNEZAD (r13)
768c2ecf20Sopenharmony_ci	addi	r0, 1
778c2ecf20Sopenharmony_ci	BNEZAD (r13, .L_dest_not_aligned_loop)
788c2ecf20Sopenharmony_ci	cmplti	r2, 8
798c2ecf20Sopenharmony_ci	bt	.L_set_by_byte
808c2ecf20Sopenharmony_ci	/* Check whether the src is aligned.  */
818c2ecf20Sopenharmony_ci	jbr	.L_dest_aligned
828c2ecf20Sopenharmony_ciENDPROC(memset)
838c2ecf20Sopenharmony_ciENDPROC(__memset)
84