18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2020-2021 Loongson Technology Corporation Limited
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <asm/alternative-asm.h>
78c2ecf20Sopenharmony_ci#include <asm/asm.h>
88c2ecf20Sopenharmony_ci#include <asm/asmmacro.h>
98c2ecf20Sopenharmony_ci#include <asm/cpu.h>
108c2ecf20Sopenharmony_ci#include <asm/export.h>
118c2ecf20Sopenharmony_ci#include <asm/regdef.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci.macro fill_to_64 r0
148c2ecf20Sopenharmony_ci	bstrins.d \r0, \r0, 15, 8
158c2ecf20Sopenharmony_ci	bstrins.d \r0, \r0, 31, 16
168c2ecf20Sopenharmony_ci	bstrins.d \r0, \r0, 63, 32
178c2ecf20Sopenharmony_ci.endm
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ciSYM_FUNC_START_WEAK(memset)
208c2ecf20Sopenharmony_ciSYM_FUNC_START_ALIAS(__memset)
218c2ecf20Sopenharmony_ci	/*
228c2ecf20Sopenharmony_ci	 * Some CPUs support hardware unaligned access
238c2ecf20Sopenharmony_ci	 */
248c2ecf20Sopenharmony_ci	ALTERNATIVE	"b __memset_generic", \
258c2ecf20Sopenharmony_ci			"b __memset_fast", CPU_FEATURE_UAL
268c2ecf20Sopenharmony_ciSYM_FUNC_END(memset)
278c2ecf20Sopenharmony_ciSYM_FUNC_END_ALIAS(__memset)
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ciEXPORT_SYMBOL(memset)
308c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__memset)
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci/*
338c2ecf20Sopenharmony_ci * void *__memset_generic(void *s, int c, size_t n)
348c2ecf20Sopenharmony_ci *
358c2ecf20Sopenharmony_ci * a0: s
368c2ecf20Sopenharmony_ci * a1: c
378c2ecf20Sopenharmony_ci * a2: n
388c2ecf20Sopenharmony_ci */
398c2ecf20Sopenharmony_ciSYM_FUNC_START(__memset_generic)
408c2ecf20Sopenharmony_ci	move	a3, a0
418c2ecf20Sopenharmony_ci	beqz	a2, 2f
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci1:	st.b	a1, a0, 0
448c2ecf20Sopenharmony_ci	addi.d	a0, a0, 1
458c2ecf20Sopenharmony_ci	addi.d	a2, a2, -1
468c2ecf20Sopenharmony_ci	bgt	a2, zero, 1b
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci2:	move	a0, a3
498c2ecf20Sopenharmony_ci	jr	ra
508c2ecf20Sopenharmony_ciSYM_FUNC_END(__memset_generic)
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci/*
538c2ecf20Sopenharmony_ci * void *__memset_fast(void *s, int c, size_t n)
548c2ecf20Sopenharmony_ci *
558c2ecf20Sopenharmony_ci * a0: s
568c2ecf20Sopenharmony_ci * a1: c
578c2ecf20Sopenharmony_ci * a2: n
588c2ecf20Sopenharmony_ci */
598c2ecf20Sopenharmony_ciSYM_FUNC_START(__memset_fast)
608c2ecf20Sopenharmony_ci	/* fill a1 to 64 bits */
618c2ecf20Sopenharmony_ci	fill_to_64 a1
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci	sltui	t0, a2, 9
648c2ecf20Sopenharmony_ci	bnez	t0, .Lsmall
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	add.d	a2, a0, a2
678c2ecf20Sopenharmony_ci	st.d	a1, a0, 0
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	/* align up address */
708c2ecf20Sopenharmony_ci	addi.d	a3, a0, 8
718c2ecf20Sopenharmony_ci	bstrins.d	a3, zero, 2, 0
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	addi.d	a4, a2, -64
748c2ecf20Sopenharmony_ci	bgeu	a3, a4, .Llt64
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci	/* set 64 bytes at a time */
778c2ecf20Sopenharmony_ci.Lloop64:
788c2ecf20Sopenharmony_ci	st.d	a1, a3, 0
798c2ecf20Sopenharmony_ci	st.d	a1, a3, 8
808c2ecf20Sopenharmony_ci	st.d	a1, a3, 16
818c2ecf20Sopenharmony_ci	st.d	a1, a3, 24
828c2ecf20Sopenharmony_ci	st.d	a1, a3, 32
838c2ecf20Sopenharmony_ci	st.d	a1, a3, 40
848c2ecf20Sopenharmony_ci	st.d	a1, a3, 48
858c2ecf20Sopenharmony_ci	st.d	a1, a3, 56
868c2ecf20Sopenharmony_ci	addi.d	a3, a3, 64
878c2ecf20Sopenharmony_ci	bltu	a3, a4, .Lloop64
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci	/* set the remaining bytes */
908c2ecf20Sopenharmony_ci.Llt64:
918c2ecf20Sopenharmony_ci	addi.d	a4, a2, -32
928c2ecf20Sopenharmony_ci	bgeu	a3, a4, .Llt32
938c2ecf20Sopenharmony_ci	st.d	a1, a3, 0
948c2ecf20Sopenharmony_ci	st.d	a1, a3, 8
958c2ecf20Sopenharmony_ci	st.d	a1, a3, 16
968c2ecf20Sopenharmony_ci	st.d	a1, a3, 24
978c2ecf20Sopenharmony_ci	addi.d	a3, a3, 32
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci.Llt32:
1008c2ecf20Sopenharmony_ci	addi.d	a4, a2, -16
1018c2ecf20Sopenharmony_ci	bgeu	a3, a4, .Llt16
1028c2ecf20Sopenharmony_ci	st.d	a1, a3, 0
1038c2ecf20Sopenharmony_ci	st.d	a1, a3, 8
1048c2ecf20Sopenharmony_ci	addi.d	a3, a3, 16
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci.Llt16:
1078c2ecf20Sopenharmony_ci	addi.d	a4, a2, -8
1088c2ecf20Sopenharmony_ci	bgeu	a3, a4, .Llt8
1098c2ecf20Sopenharmony_ci	st.d	a1, a3, 0
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci.Llt8:
1128c2ecf20Sopenharmony_ci	st.d	a1, a2, -8
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	/* return */
1158c2ecf20Sopenharmony_ci	jr	ra
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	.align	4
1188c2ecf20Sopenharmony_ci.Lsmall:
1198c2ecf20Sopenharmony_ci	pcaddi	t0, 4
1208c2ecf20Sopenharmony_ci	slli.d	a2, a2, 4
1218c2ecf20Sopenharmony_ci	add.d	t0, t0, a2
1228c2ecf20Sopenharmony_ci	jr	t0
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci	.align	4
1258c2ecf20Sopenharmony_ci0:	jr	ra
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci	.align	4
1288c2ecf20Sopenharmony_ci1:	st.b	a1, a0, 0
1298c2ecf20Sopenharmony_ci	jr	ra
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci	.align	4
1328c2ecf20Sopenharmony_ci2:	st.h	a1, a0, 0
1338c2ecf20Sopenharmony_ci	jr	ra
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ci	.align	4
1368c2ecf20Sopenharmony_ci3:	st.h	a1, a0, 0
1378c2ecf20Sopenharmony_ci	st.b	a1, a0, 2
1388c2ecf20Sopenharmony_ci	jr	ra
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	.align	4
1418c2ecf20Sopenharmony_ci4:	st.w	a1, a0, 0
1428c2ecf20Sopenharmony_ci	jr	ra
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci	.align	4
1458c2ecf20Sopenharmony_ci5:	st.w	a1, a0, 0
1468c2ecf20Sopenharmony_ci	st.b	a1, a0, 4
1478c2ecf20Sopenharmony_ci	jr	ra
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci	.align	4
1508c2ecf20Sopenharmony_ci6:	st.w	a1, a0, 0
1518c2ecf20Sopenharmony_ci	st.h	a1, a0, 4
1528c2ecf20Sopenharmony_ci	jr	ra
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci	.align	4
1558c2ecf20Sopenharmony_ci7:	st.w	a1, a0, 0
1568c2ecf20Sopenharmony_ci	st.w	a1, a0, 3
1578c2ecf20Sopenharmony_ci	jr	ra
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci	.align	4
1608c2ecf20Sopenharmony_ci8:	st.d	a1, a0, 0
1618c2ecf20Sopenharmony_ci	jr	ra
1628c2ecf20Sopenharmony_ciSYM_FUNC_END(__memset_fast)
163