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