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_ciENTRY(memcmp) 88c2ecf20Sopenharmony_ci /* Test if len less than 4 bytes. */ 98c2ecf20Sopenharmony_ci mov r3, r0 108c2ecf20Sopenharmony_ci movi r0, 0 118c2ecf20Sopenharmony_ci mov r12, r4 128c2ecf20Sopenharmony_ci cmplti r2, 4 138c2ecf20Sopenharmony_ci bt .L_compare_by_byte 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci andi r13, r0, 3 168c2ecf20Sopenharmony_ci movi r19, 4 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci /* Test if s1 is not 4 bytes aligned. */ 198c2ecf20Sopenharmony_ci bnez r13, .L_s1_not_aligned 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci LABLE_ALIGN 228c2ecf20Sopenharmony_ci.L_s1_aligned: 238c2ecf20Sopenharmony_ci /* If dest is aligned, then copy. */ 248c2ecf20Sopenharmony_ci zext r18, r2, 31, 4 258c2ecf20Sopenharmony_ci /* Test if len less than 16 bytes. */ 268c2ecf20Sopenharmony_ci bez r18, .L_compare_by_word 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci.L_compare_by_4word: 298c2ecf20Sopenharmony_ci /* If aligned, load word each time. */ 308c2ecf20Sopenharmony_ci ldw r20, (r3, 0) 318c2ecf20Sopenharmony_ci ldw r21, (r1, 0) 328c2ecf20Sopenharmony_ci /* If s1[i] != s2[i], goto .L_byte_check. */ 338c2ecf20Sopenharmony_ci cmpne r20, r21 348c2ecf20Sopenharmony_ci bt .L_byte_check 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci ldw r20, (r3, 4) 378c2ecf20Sopenharmony_ci ldw r21, (r1, 4) 388c2ecf20Sopenharmony_ci cmpne r20, r21 398c2ecf20Sopenharmony_ci bt .L_byte_check 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci ldw r20, (r3, 8) 428c2ecf20Sopenharmony_ci ldw r21, (r1, 8) 438c2ecf20Sopenharmony_ci cmpne r20, r21 448c2ecf20Sopenharmony_ci bt .L_byte_check 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci ldw r20, (r3, 12) 478c2ecf20Sopenharmony_ci ldw r21, (r1, 12) 488c2ecf20Sopenharmony_ci cmpne r20, r21 498c2ecf20Sopenharmony_ci bt .L_byte_check 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci PRE_BNEZAD (r18) 528c2ecf20Sopenharmony_ci addi a3, 16 538c2ecf20Sopenharmony_ci addi a1, 16 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci BNEZAD (r18, .L_compare_by_4word) 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci.L_compare_by_word: 588c2ecf20Sopenharmony_ci zext r18, r2, 3, 2 598c2ecf20Sopenharmony_ci bez r18, .L_compare_by_byte 608c2ecf20Sopenharmony_ci.L_compare_by_word_loop: 618c2ecf20Sopenharmony_ci ldw r20, (r3, 0) 628c2ecf20Sopenharmony_ci ldw r21, (r1, 0) 638c2ecf20Sopenharmony_ci addi r3, 4 648c2ecf20Sopenharmony_ci PRE_BNEZAD (r18) 658c2ecf20Sopenharmony_ci cmpne r20, r21 668c2ecf20Sopenharmony_ci addi r1, 4 678c2ecf20Sopenharmony_ci bt .L_byte_check 688c2ecf20Sopenharmony_ci BNEZAD (r18, .L_compare_by_word_loop) 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci.L_compare_by_byte: 718c2ecf20Sopenharmony_ci zext r18, r2, 1, 0 728c2ecf20Sopenharmony_ci bez r18, .L_return 738c2ecf20Sopenharmony_ci.L_compare_by_byte_loop: 748c2ecf20Sopenharmony_ci ldb r0, (r3, 0) 758c2ecf20Sopenharmony_ci ldb r4, (r1, 0) 768c2ecf20Sopenharmony_ci addi r3, 1 778c2ecf20Sopenharmony_ci subu r0, r4 788c2ecf20Sopenharmony_ci PRE_BNEZAD (r18) 798c2ecf20Sopenharmony_ci addi r1, 1 808c2ecf20Sopenharmony_ci bnez r0, .L_return 818c2ecf20Sopenharmony_ci BNEZAD (r18, .L_compare_by_byte_loop) 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci.L_return: 848c2ecf20Sopenharmony_ci mov r4, r12 858c2ecf20Sopenharmony_ci rts 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci# ifdef __CSKYBE__ 888c2ecf20Sopenharmony_ci/* d[i] != s[i] in word, so we check byte 0. */ 898c2ecf20Sopenharmony_ci.L_byte_check: 908c2ecf20Sopenharmony_ci xtrb0 r0, r20 918c2ecf20Sopenharmony_ci xtrb0 r2, r21 928c2ecf20Sopenharmony_ci subu r0, r2 938c2ecf20Sopenharmony_ci bnez r0, .L_return 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci /* check byte 1 */ 968c2ecf20Sopenharmony_ci xtrb1 r0, r20 978c2ecf20Sopenharmony_ci xtrb1 r2, r21 988c2ecf20Sopenharmony_ci subu r0, r2 998c2ecf20Sopenharmony_ci bnez r0, .L_return 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci /* check byte 2 */ 1028c2ecf20Sopenharmony_ci xtrb2 r0, r20 1038c2ecf20Sopenharmony_ci xtrb2 r2, r21 1048c2ecf20Sopenharmony_ci subu r0, r2 1058c2ecf20Sopenharmony_ci bnez r0, .L_return 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci /* check byte 3 */ 1088c2ecf20Sopenharmony_ci xtrb3 r0, r20 1098c2ecf20Sopenharmony_ci xtrb3 r2, r21 1108c2ecf20Sopenharmony_ci subu r0, r2 1118c2ecf20Sopenharmony_ci# else 1128c2ecf20Sopenharmony_ci/* s1[i] != s2[i] in word, so we check byte 3. */ 1138c2ecf20Sopenharmony_ci.L_byte_check: 1148c2ecf20Sopenharmony_ci xtrb3 r0, r20 1158c2ecf20Sopenharmony_ci xtrb3 r2, r21 1168c2ecf20Sopenharmony_ci subu r0, r2 1178c2ecf20Sopenharmony_ci bnez r0, .L_return 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci /* check byte 2 */ 1208c2ecf20Sopenharmony_ci xtrb2 r0, r20 1218c2ecf20Sopenharmony_ci xtrb2 r2, r21 1228c2ecf20Sopenharmony_ci subu r0, r2 1238c2ecf20Sopenharmony_ci bnez r0, .L_return 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci /* check byte 1 */ 1268c2ecf20Sopenharmony_ci xtrb1 r0, r20 1278c2ecf20Sopenharmony_ci xtrb1 r2, r21 1288c2ecf20Sopenharmony_ci subu r0, r2 1298c2ecf20Sopenharmony_ci bnez r0, .L_return 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci /* check byte 0 */ 1328c2ecf20Sopenharmony_ci xtrb0 r0, r20 1338c2ecf20Sopenharmony_ci xtrb0 r2, r21 1348c2ecf20Sopenharmony_ci subu r0, r2 1358c2ecf20Sopenharmony_ci br .L_return 1368c2ecf20Sopenharmony_ci# endif /* !__CSKYBE__ */ 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci/* Compare when s1 is not aligned. */ 1398c2ecf20Sopenharmony_ci.L_s1_not_aligned: 1408c2ecf20Sopenharmony_ci sub r13, r19, r13 1418c2ecf20Sopenharmony_ci sub r2, r13 1428c2ecf20Sopenharmony_ci.L_s1_not_aligned_loop: 1438c2ecf20Sopenharmony_ci ldb r0, (r3, 0) 1448c2ecf20Sopenharmony_ci ldb r4, (r1, 0) 1458c2ecf20Sopenharmony_ci addi r3, 1 1468c2ecf20Sopenharmony_ci subu r0, r4 1478c2ecf20Sopenharmony_ci PRE_BNEZAD (r13) 1488c2ecf20Sopenharmony_ci addi r1, 1 1498c2ecf20Sopenharmony_ci bnez r0, .L_return 1508c2ecf20Sopenharmony_ci BNEZAD (r13, .L_s1_not_aligned_loop) 1518c2ecf20Sopenharmony_ci br .L_s1_aligned 1528c2ecf20Sopenharmony_ciENDPROC(memcmp) 153