1*4882a593Smuzhiyun/* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. 3*4882a593Smuzhiyun 4*4882a593Smuzhiyun#include <linux/linkage.h> 5*4882a593Smuzhiyun#include "sysdep.h" 6*4882a593Smuzhiyun 7*4882a593SmuzhiyunENTRY(memcmp) 8*4882a593Smuzhiyun /* Test if len less than 4 bytes. */ 9*4882a593Smuzhiyun mov r3, r0 10*4882a593Smuzhiyun movi r0, 0 11*4882a593Smuzhiyun mov r12, r4 12*4882a593Smuzhiyun cmplti r2, 4 13*4882a593Smuzhiyun bt .L_compare_by_byte 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun andi r13, r0, 3 16*4882a593Smuzhiyun movi r19, 4 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun /* Test if s1 is not 4 bytes aligned. */ 19*4882a593Smuzhiyun bnez r13, .L_s1_not_aligned 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun LABLE_ALIGN 22*4882a593Smuzhiyun.L_s1_aligned: 23*4882a593Smuzhiyun /* If dest is aligned, then copy. */ 24*4882a593Smuzhiyun zext r18, r2, 31, 4 25*4882a593Smuzhiyun /* Test if len less than 16 bytes. */ 26*4882a593Smuzhiyun bez r18, .L_compare_by_word 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun.L_compare_by_4word: 29*4882a593Smuzhiyun /* If aligned, load word each time. */ 30*4882a593Smuzhiyun ldw r20, (r3, 0) 31*4882a593Smuzhiyun ldw r21, (r1, 0) 32*4882a593Smuzhiyun /* If s1[i] != s2[i], goto .L_byte_check. */ 33*4882a593Smuzhiyun cmpne r20, r21 34*4882a593Smuzhiyun bt .L_byte_check 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun ldw r20, (r3, 4) 37*4882a593Smuzhiyun ldw r21, (r1, 4) 38*4882a593Smuzhiyun cmpne r20, r21 39*4882a593Smuzhiyun bt .L_byte_check 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun ldw r20, (r3, 8) 42*4882a593Smuzhiyun ldw r21, (r1, 8) 43*4882a593Smuzhiyun cmpne r20, r21 44*4882a593Smuzhiyun bt .L_byte_check 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun ldw r20, (r3, 12) 47*4882a593Smuzhiyun ldw r21, (r1, 12) 48*4882a593Smuzhiyun cmpne r20, r21 49*4882a593Smuzhiyun bt .L_byte_check 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun PRE_BNEZAD (r18) 52*4882a593Smuzhiyun addi a3, 16 53*4882a593Smuzhiyun addi a1, 16 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun BNEZAD (r18, .L_compare_by_4word) 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun.L_compare_by_word: 58*4882a593Smuzhiyun zext r18, r2, 3, 2 59*4882a593Smuzhiyun bez r18, .L_compare_by_byte 60*4882a593Smuzhiyun.L_compare_by_word_loop: 61*4882a593Smuzhiyun ldw r20, (r3, 0) 62*4882a593Smuzhiyun ldw r21, (r1, 0) 63*4882a593Smuzhiyun addi r3, 4 64*4882a593Smuzhiyun PRE_BNEZAD (r18) 65*4882a593Smuzhiyun cmpne r20, r21 66*4882a593Smuzhiyun addi r1, 4 67*4882a593Smuzhiyun bt .L_byte_check 68*4882a593Smuzhiyun BNEZAD (r18, .L_compare_by_word_loop) 69*4882a593Smuzhiyun 70*4882a593Smuzhiyun.L_compare_by_byte: 71*4882a593Smuzhiyun zext r18, r2, 1, 0 72*4882a593Smuzhiyun bez r18, .L_return 73*4882a593Smuzhiyun.L_compare_by_byte_loop: 74*4882a593Smuzhiyun ldb r0, (r3, 0) 75*4882a593Smuzhiyun ldb r4, (r1, 0) 76*4882a593Smuzhiyun addi r3, 1 77*4882a593Smuzhiyun subu r0, r4 78*4882a593Smuzhiyun PRE_BNEZAD (r18) 79*4882a593Smuzhiyun addi r1, 1 80*4882a593Smuzhiyun bnez r0, .L_return 81*4882a593Smuzhiyun BNEZAD (r18, .L_compare_by_byte_loop) 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun.L_return: 84*4882a593Smuzhiyun mov r4, r12 85*4882a593Smuzhiyun rts 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun# ifdef __CSKYBE__ 88*4882a593Smuzhiyun/* d[i] != s[i] in word, so we check byte 0. */ 89*4882a593Smuzhiyun.L_byte_check: 90*4882a593Smuzhiyun xtrb0 r0, r20 91*4882a593Smuzhiyun xtrb0 r2, r21 92*4882a593Smuzhiyun subu r0, r2 93*4882a593Smuzhiyun bnez r0, .L_return 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun /* check byte 1 */ 96*4882a593Smuzhiyun xtrb1 r0, r20 97*4882a593Smuzhiyun xtrb1 r2, r21 98*4882a593Smuzhiyun subu r0, r2 99*4882a593Smuzhiyun bnez r0, .L_return 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun /* check byte 2 */ 102*4882a593Smuzhiyun xtrb2 r0, r20 103*4882a593Smuzhiyun xtrb2 r2, r21 104*4882a593Smuzhiyun subu r0, r2 105*4882a593Smuzhiyun bnez r0, .L_return 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun /* check byte 3 */ 108*4882a593Smuzhiyun xtrb3 r0, r20 109*4882a593Smuzhiyun xtrb3 r2, r21 110*4882a593Smuzhiyun subu r0, r2 111*4882a593Smuzhiyun# else 112*4882a593Smuzhiyun/* s1[i] != s2[i] in word, so we check byte 3. */ 113*4882a593Smuzhiyun.L_byte_check: 114*4882a593Smuzhiyun xtrb3 r0, r20 115*4882a593Smuzhiyun xtrb3 r2, r21 116*4882a593Smuzhiyun subu r0, r2 117*4882a593Smuzhiyun bnez r0, .L_return 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun /* check byte 2 */ 120*4882a593Smuzhiyun xtrb2 r0, r20 121*4882a593Smuzhiyun xtrb2 r2, r21 122*4882a593Smuzhiyun subu r0, r2 123*4882a593Smuzhiyun bnez r0, .L_return 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun /* check byte 1 */ 126*4882a593Smuzhiyun xtrb1 r0, r20 127*4882a593Smuzhiyun xtrb1 r2, r21 128*4882a593Smuzhiyun subu r0, r2 129*4882a593Smuzhiyun bnez r0, .L_return 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun /* check byte 0 */ 132*4882a593Smuzhiyun xtrb0 r0, r20 133*4882a593Smuzhiyun xtrb0 r2, r21 134*4882a593Smuzhiyun subu r0, r2 135*4882a593Smuzhiyun br .L_return 136*4882a593Smuzhiyun# endif /* !__CSKYBE__ */ 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun/* Compare when s1 is not aligned. */ 139*4882a593Smuzhiyun.L_s1_not_aligned: 140*4882a593Smuzhiyun sub r13, r19, r13 141*4882a593Smuzhiyun sub r2, r13 142*4882a593Smuzhiyun.L_s1_not_aligned_loop: 143*4882a593Smuzhiyun ldb r0, (r3, 0) 144*4882a593Smuzhiyun ldb r4, (r1, 0) 145*4882a593Smuzhiyun addi r3, 1 146*4882a593Smuzhiyun subu r0, r4 147*4882a593Smuzhiyun PRE_BNEZAD (r13) 148*4882a593Smuzhiyun addi r1, 1 149*4882a593Smuzhiyun bnez r0, .L_return 150*4882a593Smuzhiyun BNEZAD (r13, .L_s1_not_aligned_loop) 151*4882a593Smuzhiyun br .L_s1_aligned 152*4882a593SmuzhiyunENDPROC(memcmp) 153