1/* Copyright (c) 2017 SiFive Inc. All rights reserved. 2 3 This copyrighted material is made available to anyone wishing to use, 4 modify, copy, or redistribute it subject to the terms and conditions 5 of the FreeBSD License. This program is distributed in the hope that 6 it will be useful, but WITHOUT ANY WARRANTY expressed or implied, 7 including the implied warranties of MERCHANTABILITY or FITNESS FOR 8 A PARTICULAR PURPOSE. A copy of this license is available at 9 http://www.opensource.org/licenses. 10*/ 11 12#include <sys/asm.h> 13 14.section .text.strcmp 15.globl strcmp 16.type strcmp, @function 17strcmp: 18#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) 191: 20 lbu a2, 0(a0) 21 lbu a3, 0(a1) 22 add a0, a0, 1 23 add a1, a1, 1 24 bne a2, a3, 2f 25 bnez a2, 1b 26 272: 28 sub a0, a2, a3 29 ret 30 31.size strcmp, .-strcmp 32#else 33 or a4, a0, a1 34 li t2, -1 35 and a4, a4, SZREG-1 36 bnez a4, .Lmisaligned 37 38#if SZREG == 4 39 li a5, 0x7f7f7f7f 40#else 41 ld a5, mask 42#endif 43 44 .macro check_one_word i n 45 REG_L a2, \i*SZREG(a0) 46 REG_L a3, \i*SZREG(a1) 47 48 and t0, a2, a5 49 or t1, a2, a5 50 add t0, t0, a5 51 or t0, t0, t1 52 53 bne t0, t2, .Lnull\i 54 .if \i+1-\n 55 bne a2, a3, .Lmismatch 56 .else 57 add a0, a0, \n*SZREG 58 add a1, a1, \n*SZREG 59 beq a2, a3, .Lloop 60 # fall through to .Lmismatch 61 .endif 62 .endm 63 64 .macro foundnull i n 65 .ifne \i 66 .Lnull\i: 67 add a0, a0, \i*SZREG 68 add a1, a1, \i*SZREG 69 .ifeq \i-1 70 .Lnull0: 71 .endif 72 bne a2, a3, .Lmisaligned 73 li a0, 0 74 ret 75 .endif 76 .endm 77 78.Lloop: 79 # examine full words at a time, favoring strings of a couple dozen chars 80#if __riscv_xlen == 32 81 check_one_word 0 5 82 check_one_word 1 5 83 check_one_word 2 5 84 check_one_word 3 5 85 check_one_word 4 5 86#else 87 check_one_word 0 3 88 check_one_word 1 3 89 check_one_word 2 3 90#endif 91 # backwards branch to .Lloop contained above 92 93.Lmismatch: 94 # words don't match, but a2 has no null byte. 95 96#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 97 98#if __riscv_xlen == 64 99 sll a4, a2, 48 100 sll a5, a3, 48 101 bne a4, a5, .Lmismatch_upper 102 sll a4, a2, 32 103 sll a5, a3, 32 104 bne a4, a5, .Lmismatch_upper 105#endif 106 sll a4, a2, 16 107 sll a5, a3, 16 108 bne a4, a5, .Lmismatch_upper 109 110 srl a4, a2, 8*SZREG-16 111 srl a5, a3, 8*SZREG-16 112 sub a0, a4, a5 113 and a1, a0, 0xff 114 bnez a1, 1f 115 ret 116 117.Lmismatch_upper: 118 srl a4, a4, 8*SZREG-16 119 srl a5, a5, 8*SZREG-16 120 sub a0, a4, a5 121 and a1, a0, 0xff 122 bnez a1, 1f 123 ret 124 1251:and a4, a4, 0xff 126 and a5, a5, 0xff 127 sub a0, a4, a5 128 ret 129 130#else 131 132#if __riscv_xlen == 64 133 srl a4, a2, 48 134 srl a5, a3, 48 135 bne a4, a5, .Lmismatch_lower 136 srl a4, a2, 32 137 srl a5, a3, 32 138 bne a4, a5, .Lmismatch_lower 139#endif 140 srl a4, a2, 16 141 srl a5, a3, 16 142 bne a4, a5, .Lmismatch_lower 143 144 srl a4, a2, 8 145 srl a5, a3, 8 146 bne a4, a5, 1f 147 and a4, a2, 0xff 148 and a5, a3, 0xff 1491:sub a0, a4, a5 150 ret 151 152.Lmismatch_lower: 153 srl a2, a4, 8 154 srl a3, a5, 8 155 bne a2, a3, 1f 156 and a2, a4, 0xff 157 and a3, a5, 0xff 1581:sub a0, a2, a3 159 ret 160 161#endif 162 163.Lmisaligned: 164 # misaligned 165 lbu a2, 0(a0) 166 lbu a3, 0(a1) 167 add a0, a0, 1 168 add a1, a1, 1 169 bne a2, a3, 1f 170 bnez a2, .Lmisaligned 171 1721: 173 sub a0, a2, a3 174 ret 175 176 # cases in which a null byte was detected 177#if __riscv_xlen == 32 178 foundnull 0 5 179 foundnull 1 5 180 foundnull 2 5 181 foundnull 3 5 182 foundnull 4 5 183#else 184 foundnull 0 3 185 foundnull 1 3 186 foundnull 2 3 187#endif 188.size strcmp, .-strcmp 189 190#if SZREG == 8 191.section .srodata.cst8,"aM",@progbits,8 192.align 3 193mask: 194.dword 0x7f7f7f7f7f7f7f7f 195#endif 196#endif 197