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/asm-extable.h> 108c2ecf20Sopenharmony_ci#include <asm/cpu.h> 118c2ecf20Sopenharmony_ci#include <asm/export.h> 128c2ecf20Sopenharmony_ci#include <asm/regdef.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ciSYM_FUNC_START(__clear_user) 158c2ecf20Sopenharmony_ci /* 168c2ecf20Sopenharmony_ci * Some CPUs support hardware unaligned access 178c2ecf20Sopenharmony_ci */ 188c2ecf20Sopenharmony_ci ALTERNATIVE "b __clear_user_generic", \ 198c2ecf20Sopenharmony_ci "b __clear_user_fast", CPU_FEATURE_UAL 208c2ecf20Sopenharmony_ciSYM_FUNC_END(__clear_user) 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__clear_user) 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci/* 258c2ecf20Sopenharmony_ci * unsigned long __clear_user_generic(void *addr, size_t size) 268c2ecf20Sopenharmony_ci * 278c2ecf20Sopenharmony_ci * a0: addr 288c2ecf20Sopenharmony_ci * a1: size 298c2ecf20Sopenharmony_ci */ 308c2ecf20Sopenharmony_ciSYM_FUNC_START(__clear_user_generic) 318c2ecf20Sopenharmony_ci beqz a1, 2f 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci1: st.b zero, a0, 0 348c2ecf20Sopenharmony_ci addi.d a0, a0, 1 358c2ecf20Sopenharmony_ci addi.d a1, a1, -1 368c2ecf20Sopenharmony_ci bgt a1, zero, 1b 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci2: move a0, a1 398c2ecf20Sopenharmony_ci jr ra 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci _asm_extable 1b, 2b 428c2ecf20Sopenharmony_ciSYM_FUNC_END(__clear_user_generic) 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci/* 458c2ecf20Sopenharmony_ci * unsigned long __clear_user_fast(void *addr, unsigned long size) 468c2ecf20Sopenharmony_ci * 478c2ecf20Sopenharmony_ci * a0: addr 488c2ecf20Sopenharmony_ci * a1: size 498c2ecf20Sopenharmony_ci */ 508c2ecf20Sopenharmony_ciSYM_FUNC_START(__clear_user_fast) 518c2ecf20Sopenharmony_ci sltui t0, a1, 9 528c2ecf20Sopenharmony_ci bnez t0, .Lsmall 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci add.d a2, a0, a1 558c2ecf20Sopenharmony_ci0: st.d zero, a0, 0 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci /* align up address */ 588c2ecf20Sopenharmony_ci addi.d a0, a0, 8 598c2ecf20Sopenharmony_ci bstrins.d a0, zero, 2, 0 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci addi.d a3, a2, -64 628c2ecf20Sopenharmony_ci bgeu a0, a3, .Llt64 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci /* set 64 bytes at a time */ 658c2ecf20Sopenharmony_ci.Lloop64: 668c2ecf20Sopenharmony_ci1: st.d zero, a0, 0 678c2ecf20Sopenharmony_ci2: st.d zero, a0, 8 688c2ecf20Sopenharmony_ci3: st.d zero, a0, 16 698c2ecf20Sopenharmony_ci4: st.d zero, a0, 24 708c2ecf20Sopenharmony_ci5: st.d zero, a0, 32 718c2ecf20Sopenharmony_ci6: st.d zero, a0, 40 728c2ecf20Sopenharmony_ci7: st.d zero, a0, 48 738c2ecf20Sopenharmony_ci8: st.d zero, a0, 56 748c2ecf20Sopenharmony_ci addi.d a0, a0, 64 758c2ecf20Sopenharmony_ci bltu a0, a3, .Lloop64 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci /* set the remaining bytes */ 788c2ecf20Sopenharmony_ci.Llt64: 798c2ecf20Sopenharmony_ci addi.d a3, a2, -32 808c2ecf20Sopenharmony_ci bgeu a0, a3, .Llt32 818c2ecf20Sopenharmony_ci9: st.d zero, a0, 0 828c2ecf20Sopenharmony_ci10: st.d zero, a0, 8 838c2ecf20Sopenharmony_ci11: st.d zero, a0, 16 848c2ecf20Sopenharmony_ci12: st.d zero, a0, 24 858c2ecf20Sopenharmony_ci addi.d a0, a0, 32 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci.Llt32: 888c2ecf20Sopenharmony_ci addi.d a3, a2, -16 898c2ecf20Sopenharmony_ci bgeu a0, a3, .Llt16 908c2ecf20Sopenharmony_ci13: st.d zero, a0, 0 918c2ecf20Sopenharmony_ci14: st.d zero, a0, 8 928c2ecf20Sopenharmony_ci addi.d a0, a0, 16 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci.Llt16: 958c2ecf20Sopenharmony_ci addi.d a3, a2, -8 968c2ecf20Sopenharmony_ci bgeu a0, a3, .Llt8 978c2ecf20Sopenharmony_ci15: st.d zero, a0, 0 988c2ecf20Sopenharmony_ci addi.d a0, a0, 8 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci.Llt8: 1018c2ecf20Sopenharmony_ci16: st.d zero, a2, -8 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci /* return */ 1048c2ecf20Sopenharmony_ci move a0, zero 1058c2ecf20Sopenharmony_ci jr ra 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci .align 4 1088c2ecf20Sopenharmony_ci.Lsmall: 1098c2ecf20Sopenharmony_ci pcaddi t0, 4 1108c2ecf20Sopenharmony_ci slli.d a2, a1, 4 1118c2ecf20Sopenharmony_ci add.d t0, t0, a2 1128c2ecf20Sopenharmony_ci jr t0 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci .align 4 1158c2ecf20Sopenharmony_ci move a0, zero 1168c2ecf20Sopenharmony_ci jr ra 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci .align 4 1198c2ecf20Sopenharmony_ci17: st.b zero, a0, 0 1208c2ecf20Sopenharmony_ci move a0, zero 1218c2ecf20Sopenharmony_ci jr ra 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci .align 4 1248c2ecf20Sopenharmony_ci18: st.h zero, a0, 0 1258c2ecf20Sopenharmony_ci move a0, zero 1268c2ecf20Sopenharmony_ci jr ra 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci .align 4 1298c2ecf20Sopenharmony_ci19: st.h zero, a0, 0 1308c2ecf20Sopenharmony_ci20: st.b zero, a0, 2 1318c2ecf20Sopenharmony_ci move a0, zero 1328c2ecf20Sopenharmony_ci jr ra 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci .align 4 1358c2ecf20Sopenharmony_ci21: st.w zero, a0, 0 1368c2ecf20Sopenharmony_ci move a0, zero 1378c2ecf20Sopenharmony_ci jr ra 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci .align 4 1408c2ecf20Sopenharmony_ci22: st.w zero, a0, 0 1418c2ecf20Sopenharmony_ci23: st.b zero, a0, 4 1428c2ecf20Sopenharmony_ci move a0, zero 1438c2ecf20Sopenharmony_ci jr ra 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci .align 4 1468c2ecf20Sopenharmony_ci24: st.w zero, a0, 0 1478c2ecf20Sopenharmony_ci25: st.h zero, a0, 4 1488c2ecf20Sopenharmony_ci move a0, zero 1498c2ecf20Sopenharmony_ci jr ra 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci .align 4 1528c2ecf20Sopenharmony_ci26: st.w zero, a0, 0 1538c2ecf20Sopenharmony_ci27: st.w zero, a0, 3 1548c2ecf20Sopenharmony_ci move a0, zero 1558c2ecf20Sopenharmony_ci jr ra 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci .align 4 1588c2ecf20Sopenharmony_ci28: st.d zero, a0, 0 1598c2ecf20Sopenharmony_ci move a0, zero 1608c2ecf20Sopenharmony_ci jr ra 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci /* fixup and ex_table */ 1638c2ecf20Sopenharmony_ci.Llarge_fixup: 1648c2ecf20Sopenharmony_ci sub.d a1, a2, a0 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci.Lsmall_fixup: 1678c2ecf20Sopenharmony_ci29: st.b zero, a0, 0 1688c2ecf20Sopenharmony_ci addi.d a0, a0, 1 1698c2ecf20Sopenharmony_ci addi.d a1, a1, -1 1708c2ecf20Sopenharmony_ci bgt a1, zero, 29b 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci.Lexit: 1738c2ecf20Sopenharmony_ci move a0, a1 1748c2ecf20Sopenharmony_ci jr ra 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci _asm_extable 0b, .Lsmall_fixup 1778c2ecf20Sopenharmony_ci _asm_extable 1b, .Llarge_fixup 1788c2ecf20Sopenharmony_ci _asm_extable 2b, .Llarge_fixup 1798c2ecf20Sopenharmony_ci _asm_extable 3b, .Llarge_fixup 1808c2ecf20Sopenharmony_ci _asm_extable 4b, .Llarge_fixup 1818c2ecf20Sopenharmony_ci _asm_extable 5b, .Llarge_fixup 1828c2ecf20Sopenharmony_ci _asm_extable 6b, .Llarge_fixup 1838c2ecf20Sopenharmony_ci _asm_extable 7b, .Llarge_fixup 1848c2ecf20Sopenharmony_ci _asm_extable 8b, .Llarge_fixup 1858c2ecf20Sopenharmony_ci _asm_extable 9b, .Llarge_fixup 1868c2ecf20Sopenharmony_ci _asm_extable 10b, .Llarge_fixup 1878c2ecf20Sopenharmony_ci _asm_extable 11b, .Llarge_fixup 1888c2ecf20Sopenharmony_ci _asm_extable 12b, .Llarge_fixup 1898c2ecf20Sopenharmony_ci _asm_extable 13b, .Llarge_fixup 1908c2ecf20Sopenharmony_ci _asm_extable 14b, .Llarge_fixup 1918c2ecf20Sopenharmony_ci _asm_extable 15b, .Llarge_fixup 1928c2ecf20Sopenharmony_ci _asm_extable 16b, .Llarge_fixup 1938c2ecf20Sopenharmony_ci _asm_extable 17b, .Lexit 1948c2ecf20Sopenharmony_ci _asm_extable 18b, .Lsmall_fixup 1958c2ecf20Sopenharmony_ci _asm_extable 19b, .Lsmall_fixup 1968c2ecf20Sopenharmony_ci _asm_extable 20b, .Lsmall_fixup 1978c2ecf20Sopenharmony_ci _asm_extable 21b, .Lsmall_fixup 1988c2ecf20Sopenharmony_ci _asm_extable 22b, .Lsmall_fixup 1998c2ecf20Sopenharmony_ci _asm_extable 23b, .Lsmall_fixup 2008c2ecf20Sopenharmony_ci _asm_extable 24b, .Lsmall_fixup 2018c2ecf20Sopenharmony_ci _asm_extable 25b, .Lsmall_fixup 2028c2ecf20Sopenharmony_ci _asm_extable 26b, .Lsmall_fixup 2038c2ecf20Sopenharmony_ci _asm_extable 27b, .Lsmall_fixup 2048c2ecf20Sopenharmony_ci _asm_extable 28b, .Lsmall_fixup 2058c2ecf20Sopenharmony_ci _asm_extable 29b, .Lexit 2068c2ecf20Sopenharmony_ciSYM_FUNC_END(__clear_user_fast) 207