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 <picolibc.h> 13 14#include "asm.h" 15 16.section .text.strcmp 17.globl strcmp 18.type strcmp, @function 19strcmp: 20#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) 211: 22 lbu a2, 0(a0) 23 lbu a3, 0(a1) 24 add a0, a0, 1 25 add a1, a1, 1 26 bne a2, a3, 2f 27 bnez a2, 1b 28 292: 30 sub a0, a2, a3 31 ret 32 33.size strcmp, .-strcmp 34#else 35 or a4, a0, a1 36 li t2, -1 37 and a4, a4, SZREG-1 38 bnez a4, .Lmisaligned 39 40#ifndef __riscv_zbb 41#if SZREG == 4 42 li a5, 0x7f7f7f7f 43#else 44 ld a5, mask 45#endif 46#endif 47 48 .macro check_one_word i n 49 REG_L a2, \i*SZREG(a0) 50 REG_L a3, \i*SZREG(a1) 51#ifdef __riscv_zbb 52 orc.b t0, a2 53#else 54 and t0, a2, a5 55 or t1, a2, a5 56 add t0, t0, a5 57 or t0, t0, t1 58#endif 59 bne t0, t2, .Lnull\i 60 .if \i+1-\n 61 bne a2, a3, .Lmismatch 62 .else 63 add a0, a0, \n*SZREG 64 add a1, a1, \n*SZREG 65 beq a2, a3, .Lloop 66 # fall through to .Lmismatch 67 .endif 68 .endm 69 70 .macro foundnull i n 71 .ifne \i 72 .Lnull\i: 73 add a0, a0, \i*SZREG 74 add a1, a1, \i*SZREG 75 .ifeq \i-1 76 .Lnull0: 77 .endif 78 bne a2, a3, .Lmisaligned 79 li a0, 0 80 ret 81 .endif 82 .endm 83 84.Lloop: 85 # examine full words at a time, favoring strings of a couple dozen chars 86#if __riscv_xlen == 32 87 check_one_word 0 5 88 check_one_word 1 5 89 check_one_word 2 5 90 check_one_word 3 5 91 check_one_word 4 5 92#else 93 check_one_word 0 3 94 check_one_word 1 3 95 check_one_word 2 3 96#endif 97 # backwards branch to .Lloop contained above 98 99.Lmismatch: 100 # words don't match, but a2 has no null byte. 101 102#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 103 104#if __riscv_xlen == 64 105 sll a4, a2, 48 106 sll a5, a3, 48 107 bne a4, a5, .Lmismatch_upper 108 sll a4, a2, 32 109 sll a5, a3, 32 110 bne a4, a5, .Lmismatch_upper 111#endif 112 sll a4, a2, 16 113 sll a5, a3, 16 114 bne a4, a5, .Lmismatch_upper 115 116 srl a4, a2, 8*SZREG-16 117 srl a5, a3, 8*SZREG-16 118 sub a0, a4, a5 119 and a1, a0, 0xff 120 bnez a1, 1f 121 ret 122 123.Lmismatch_upper: 124 srl a4, a4, 8*SZREG-16 125 srl a5, a5, 8*SZREG-16 126 sub a0, a4, a5 127 and a1, a0, 0xff 128 bnez a1, 1f 129 ret 130 1311:and a4, a4, 0xff 132 and a5, a5, 0xff 133 sub a0, a4, a5 134 ret 135 136#else 137 138#if __riscv_xlen == 64 139 srl a4, a2, 48 140 srl a5, a3, 48 141 bne a4, a5, .Lmismatch_lower 142 srl a4, a2, 32 143 srl a5, a3, 32 144 bne a4, a5, .Lmismatch_lower 145#endif 146 srl a4, a2, 16 147 srl a5, a3, 16 148 bne a4, a5, .Lmismatch_lower 149 150 srl a4, a2, 8 151 srl a5, a3, 8 152 bne a4, a5, 1f 153 and a4, a2, 0xff 154 and a5, a3, 0xff 1551:sub a0, a4, a5 156 ret 157 158.Lmismatch_lower: 159 srl a2, a4, 8 160 srl a3, a5, 8 161 bne a2, a3, 1f 162 and a2, a4, 0xff 163 and a3, a5, 0xff 1641:sub a0, a2, a3 165 ret 166 167#endif 168 169.Lmisaligned: 170 # misaligned 171 lbu a2, 0(a0) 172 lbu a3, 0(a1) 173 add a0, a0, 1 174 add a1, a1, 1 175 bne a2, a3, 1f 176 bnez a2, .Lmisaligned 177 1781: 179 sub a0, a2, a3 180 ret 181 182 # cases in which a null byte was detected 183#if __riscv_xlen == 32 184 foundnull 0 5 185 foundnull 1 5 186 foundnull 2 5 187 foundnull 3 5 188 foundnull 4 5 189#else 190 foundnull 0 3 191 foundnull 1 3 192 foundnull 2 3 193#endif 194.size strcmp, .-strcmp 195 196#if SZREG == 8 && !defined(__riscv_zbb) 197.section .srodata.cst8,"aM",@progbits,8 198.align 3 199mask: 200.dword 0x7f7f7f7f7f7f7f7f 201#endif 202#endif 203