/* Copyright (c) 2017 SiFive Inc. All rights reserved. This copyrighted material is made available to anyone wishing to use, modify, copy, or redistribute it subject to the terms and conditions of the FreeBSD License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. A copy of this license is available at http://www.opensource.org/licenses. */ #include .text .globl strcmp .type strcmp, @function strcmp: #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) 1: lbu a2, 0(a0) lbu a3, 0(a1) add a0, a0, 1 add a1, a1, 1 bne a2, a3, 2f bnez a2, 1b 2: sub a0, a2, a3 ret .size strcmp, .-strcmp #else or a4, a0, a1 li t2, -1 and a4, a4, SZREG-1 bnez a4, .Lmisaligned #if SZREG == 4 li a5, 0x7f7f7f7f #else ld a5, mask #endif .macro check_one_word i n REG_L a2, \i*SZREG(a0) REG_L a3, \i*SZREG(a1) and t0, a2, a5 or t1, a2, a5 add t0, t0, a5 or t0, t0, t1 bne t0, t2, .Lnull\i .if \i+1-\n bne a2, a3, .Lmismatch .else add a0, a0, \n*SZREG add a1, a1, \n*SZREG beq a2, a3, .Lloop # fall through to .Lmismatch .endif .endm .macro foundnull i n .ifne \i .Lnull\i: add a0, a0, \i*SZREG add a1, a1, \i*SZREG .ifeq \i-1 .Lnull0: .endif bne a2, a3, .Lmisaligned li a0, 0 ret .endif .endm .Lloop: # examine full words at a time, favoring strings of a couple dozen chars #if __riscv_xlen == 32 check_one_word 0 5 check_one_word 1 5 check_one_word 2 5 check_one_word 3 5 check_one_word 4 5 #else check_one_word 0 3 check_one_word 1 3 check_one_word 2 3 #endif # backwards branch to .Lloop contained above .Lmismatch: # words don't match, but a2 has no null byte. #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #if __riscv_xlen == 64 sll a4, a2, 48 sll a5, a3, 48 bne a4, a5, .Lmismatch_upper sll a4, a2, 32 sll a5, a3, 32 bne a4, a5, .Lmismatch_upper #endif sll a4, a2, 16 sll a5, a3, 16 bne a4, a5, .Lmismatch_upper srl a4, a2, 8*SZREG-16 srl a5, a3, 8*SZREG-16 sub a0, a4, a5 and a1, a0, 0xff bnez a1, 1f ret .Lmismatch_upper: srl a4, a4, 8*SZREG-16 srl a5, a5, 8*SZREG-16 sub a0, a4, a5 and a1, a0, 0xff bnez a1, 1f ret 1:and a4, a4, 0xff and a5, a5, 0xff sub a0, a4, a5 ret #else #if __riscv_xlen == 64 srl a4, a2, 48 srl a5, a3, 48 bne a4, a5, .Lmismatch_lower srl a4, a2, 32 srl a5, a3, 32 bne a4, a5, .Lmismatch_lower #endif srl a4, a2, 16 srl a5, a3, 16 bne a4, a5, .Lmismatch_lower srl a4, a2, 8 srl a5, a3, 8 bne a4, a5, 1f and a4, a2, 0xff and a5, a3, 0xff 1:sub a0, a4, a5 ret .Lmismatch_lower: srl a2, a4, 8 srl a3, a5, 8 bne a2, a3, 1f and a2, a4, 0xff and a3, a5, 0xff 1:sub a0, a2, a3 ret #endif .Lmisaligned: # misaligned lbu a2, 0(a0) lbu a3, 0(a1) add a0, a0, 1 add a1, a1, 1 bne a2, a3, 1f bnez a2, .Lmisaligned 1: sub a0, a2, a3 ret # cases in which a null byte was detected #if __riscv_xlen == 32 foundnull 0 5 foundnull 1 5 foundnull 2 5 foundnull 3 5 foundnull 4 5 #else foundnull 0 3 foundnull 1 3 foundnull 2 3 #endif .size strcmp, .-strcmp #if SZREG == 8 .section .srodata.cst8,"aM",@progbits,8 .align 3 mask: .dword 0x7f7f7f7f7f7f7f7f #endif #endif