1/* The assembly function for memory compare. C-SKY ABIV2 version. 2 Copyright (C) 2018-2022 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library. If not, see 17 <https://www.gnu.org/licenses/>. */ 18 19#include <sysdep.h> 20 21ENTRY (memcmp) 22 /* Test if len less than 4 bytes. */ 23 mov r3, r0 24 movi r0, 0 25 mov r12, r4 26 cmplti r2, 4 27 jbt .L_compare_by_byte 28 29 andi r13, r0, 3 30 movi r19, 4 31 /* Test if s1 is not 4 bytes aligned. */ 32 bnez r13, .L_s1_not_aligned 33 34 LABLE_ALIGN 35.L_s1_aligned: 36 /* If dest is aligned, then copy. */ 37 zext r18, r2, 31, 4 38 /* Test if len less than 16 bytes. */ 39 bez r18, .L_compare_by_word 40 41.L_compare_by_4word: 42 /* If aligned, load word each time. */ 43 ldw r20, (r3, 0) 44 ldw r21, (r1, 0) 45 /* If s1[i] != s2[i], goto .L_byte_check. */ 46 cmpne r20, r21 47 bt .L_byte_check 48 49 ldw r20, (r3, 4) 50 ldw r21, (r1, 4) 51 cmpne r20, r21 52 bt .L_byte_check 53 54 ldw r20, (r3, 8) 55 ldw r21, (r1, 8) 56 cmpne r20, r21 57 bt .L_byte_check 58 59 ldw r20, (r3, 12) 60 ldw r21, (r1, 12) 61 cmpne r20, r21 62 bt .L_byte_check 63 64 PRE_BNEZAD (r18) 65 addi a3, 16 66 addi a1, 16 67 68 BNEZAD (r18, .L_compare_by_4word) 69 70.L_compare_by_word: 71 zext r18, r2, 3, 2 72 bez r18, .L_compare_by_byte 73.L_compare_by_word_loop: 74 ldw r20, (r3, 0) 75 ldw r21, (r1, 0) 76 addi r3, 4 77 PRE_BNEZAD (r18) 78 cmpne r20, r21 79 addi r1, 4 80 bt .L_byte_check 81 BNEZAD (r18, .L_compare_by_word_loop) 82 83.L_compare_by_byte: 84 zext r18, r2, 1, 0 85 bez r18, .L_return 86.L_compare_by_byte_loop: 87 ldb r0, (r3, 0) 88 ldb r4, (r1, 0) 89 addi r3, 1 90 subu r0, r4 91 PRE_BNEZAD (r18) 92 addi r1, 1 93 bnez r0, .L_return 94 BNEZAD (r18, .L_compare_by_byte_loop) 95 96.L_return: 97 mov r4, r12 98 rts 99 100 /* s1[i] != s2[i] in word, so we check byte 3. */ 101.L_byte_check: 102 xtrb3 r0, r20 103 xtrb3 r2, r21 104 subu r0, r2 105 bnez r0, .L_return 106 107 /* check byte 2 */ 108 xtrb2 r0, r20 109 xtrb2 r2, r21 110 subu r0, r2 111 bnez r0, .L_return 112 113 /* check byte 1 */ 114 xtrb1 r0, r20 115 xtrb1 r2, r21 116 subu r0, r2 117 bnez r0, .L_return 118 119 /* check byte 0 */ 120 xtrb0 r0, r20 121 xtrb0 r2, r21 122 subu r0, r2 123 br .L_return 124 125 /* Compare when s1 is not aligned. */ 126.L_s1_not_aligned: 127 sub r13, r19, r13 128 sub r2, r13 129.L_s1_not_aligned_loop: 130 ldb r0, (r3, 0) 131 ldb r4, (r1, 0) 132 addi r3, 1 133 subu r0, r4 134 PRE_BNEZAD (r13) 135 addi r1, 1 136 bnez r0, .L_return 137 BNEZAD (r13, .L_s1_not_aligned_loop) 138 br .L_s1_aligned 139END (memcmp) 140weak_alias (memcmp, bcmp) 141strong_alias (memcmp, __memcmpeq) 142libc_hidden_def (memcmp) 143libc_hidden_def (__memcmpeq) 144.weak memcmp 145