From patchwork Wed May 7 14:46:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Salem X-Patchwork-Id: 111671 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8816E3858C2F for ; Wed, 7 May 2025 14:47:49 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8816E3858C2F Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=Dwaqli5X X-Original-To: newlib@sourceware.org Delivered-To: newlib@sourceware.org Received: from mail-qt1-x82e.google.com (mail-qt1-x82e.google.com [IPv6:2607:f8b0:4864:20::82e]) by sourceware.org (Postfix) with ESMTPS id F3E9C3858D37 for ; Wed, 7 May 2025 14:46:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org F3E9C3858D37 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org F3E9C3858D37 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::82e ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1746629207; cv=none; b=eTRTiMkp7EiEjPHKR09fY08dn1oT//ZyF+k1t4BEu6AxulubcS4R/quhmAqs3D9OoHMI/vfUk2qq8vxKO6AjOhL1uy8UdMQaUSRurQUcIp87DB9oZWWgdeSORpQfi2yGlFqh9ZdRAG/OUvtbmGFzloa3+OuZyLaBrhuYxszULVs= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1746629207; c=relaxed/simple; bh=Q3ROrXC8xjNy9ZBNBZELM0aBxVYjRbjseNL09RyggZg=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=QZYo6dCA5SgEWhYUBe/bnJDAPFbdGZ0kxgoJbm8l5dg9FvEuyftwyElS0gooc+2Gkv0JzL/wA6vN/9mwlhgRj6KJjHr+Zesr2we/TKnnEMb/XoowhG1+1nP6mNcTlUDDhrwn7LAbp0QbN6ZfCF6XK4yPms89Gz1S9/omRy/6t6U= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F3E9C3858D37 Received: by mail-qt1-x82e.google.com with SMTP id d75a77b69052e-4772f48f516so11584811cf.1 for ; Wed, 07 May 2025 07:46:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746629206; x=1747234006; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=ZL5CFWqt5oR6+gJhrRoat51j9Np/TFIMsUcjl3Mi7xY=; b=Dwaqli5XQN/f07vM6yFEqMbzBEimQRiPt8DlJjiiB4zsgPx3Ow3VaVDLQeZ9t+iJiI Cr34y9/MTaMDCZSw2AEIduwNlMWsl+D5waBdGHKhRncebgiTJ1wUTdi8rqkRJOy8Uq0P q/hT8QDkkFtg7ByDRmE5XeaNAWi+VJ6IxzvNk+/avZZcsFVlPfakH/CmUOmTYaajdM/M mn/cKjDvx6PSyK2iycsy1SjCPRmsYSy9D0O94UB6yA0JrrwBiKntnVmxfvUamMZFXrdx clZK//YXtHmonOFJQqyzDghzYmUGAzu6b6HW3mpelU19lk29Obvakyrqc17ibdsFA8+J /oyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746629206; x=1747234006; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZL5CFWqt5oR6+gJhrRoat51j9Np/TFIMsUcjl3Mi7xY=; b=klHtuNf3yAyMNftlcSQUPtb7wgmnBfEBOu99bdP37Vin6bK0quQdbMKDZD3Q/UypVd G/6rTlc7Fm13QiEtIXRgmD8mqFzhaIC2zPM5Hc7u1m7sJl3yGAhgwt5M1d6wZR8OqOT7 YXMvuqyooi5+dsgma4uWrFEHxwngiZTsYpetLtntW92Qqdmpq5/Np5qJ0XeEA9LwvJAD 7q1DSprrLMw3aXHUVXO/Xv6V7nisW+ZiEx8UWUHEdtwzWsKZBQpMVHFVTP/R7A7Ys4rG wO1n65Y/lRi6KC7qzYoSAjBIrcxjUaVvVYnviSbeHSaDss5i4IY4TUEkfvPVxZBI7hir dO2w== X-Gm-Message-State: AOJu0YzLMlUFdfSuJWpd+luLOvteXZHMUDrKWPuOFylSXb6F9ugvn+qx Up6qZKyoKZtHXvR3M1uO5j/O5OQ/jc55dZ92rEeJhTR5DtB1jgbSXT07jfsp X-Gm-Gg: ASbGncu5KPLDAn9T4f2iKY5ldchTIsK/l6CItmSNsNpCgrAKKsRJ3OWVMOBR8UTuSPo PeB2X2wAH85PDIB0bppmh4BP87dBiiVYTtUNk/mNycUM77j2OyDVgK5tRo4/60+aaDdOw7uyF9k 3jXRxSSl5/oPMJZLbC2tTuqUGPihIeIGow+JwMBp/sUt7YqwI7DfuAxbm4fMJl9EkQZQWcUQI07 iAQ/jUA0TXxF1BdTcwuBYwNdcezzWR8KTAcymJCLRlLTckjMgMJ9SVnz9PZy5z/Rog0ypsYXFHL Q933ikR3bGb54izm0MLxOs1nEdIOi3tCxpsyxmgCmUzWD/NO5t1mGgDiH+kkvGJ5ISyKERLZKo2 b8cZkRVKi X-Google-Smtp-Source: AGHT+IFdBQ5IAirOVBJYmUZ7swGB3mreVr8b9n5dztVgBjOKsPhqycyhx34VsoNm9qaaFIplxs6KiA== X-Received: by 2002:a05:620a:3195:b0:7c9:5ee5:719 with SMTP id af79cd13be357-7caf6d03e65mr701642685a.15.1746629206035; Wed, 07 May 2025 07:46:46 -0700 (PDT) Received: from fedora.. (c-73-176-204-61.hsd1.il.comcast.net. [73.176.204.61]) by smtp.gmail.com with ESMTPSA id af79cd13be357-7caf75d8fe2sm157522385a.97.2025.05.07.07.46.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 May 2025 07:46:45 -0700 (PDT) From: Eric Salem To: newlib@sourceware.org, Kito Cheng Subject: [PATCH v2 1/3] newlib: riscv: Add memchr() and memrchr() implementations Date: Wed, 7 May 2025 09:46:41 -0500 Message-ID: <4d1db27470f8833edb05693f286c63cfd001c01f.1746628687.git.ericsalem@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Status: No, score=-10.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: newlib@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Newlib mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: newlib-bounces~patchwork=sourceware.org@sourceware.org Copy stock implementations of memchr() and memrchr() to the RISC-V port. Reviewed-by: Christian Herber Signed-off-by: Eric Salem --- newlib/libc/machine/riscv/Makefile.inc | 2 +- newlib/libc/machine/riscv/memchr.c | 99 ++++++++++++++++++++++++++ newlib/libc/machine/riscv/memrchr.c | 99 ++++++++++++++++++++++++++ 3 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 newlib/libc/machine/riscv/memchr.c create mode 100644 newlib/libc/machine/riscv/memrchr.c diff --git a/newlib/libc/machine/riscv/Makefile.inc b/newlib/libc/machine/riscv/Makefile.inc index 4d6c0469abb3..85bed91772cf 100644 --- a/newlib/libc/machine/riscv/Makefile.inc +++ b/newlib/libc/machine/riscv/Makefile.inc @@ -1,3 +1,3 @@ libc_a_SOURCES += \ %D%/memmove.S %D%/memmove-stub.c %D%/memset.S %D%/memcpy-asm.S %D%/memcpy.c %D%/strlen.c \ - %D%/strcpy.c %D%/stpcpy.c %D%/strcmp.S %D%/setjmp.S %D%/ieeefp.c %D%/ffs.c + %D%/strcpy.c %D%/stpcpy.c %D%/strcmp.S %D%/memchr.c %D%/memrchr.c %D%/setjmp.S %D%/ieeefp.c %D%/ffs.c diff --git a/newlib/libc/machine/riscv/memchr.c b/newlib/libc/machine/riscv/memchr.c new file mode 100644 index 000000000000..5c08c12813fe --- /dev/null +++ b/newlib/libc/machine/riscv/memchr.c @@ -0,0 +1,99 @@ +/* +FUNCTION + <>---find character in memory + +INDEX + memchr + +SYNOPSIS + #include + void *memchr(const void *<[src]>, int <[c]>, size_t <[length]>); + +DESCRIPTION + This function searches memory starting at <<*<[src]>>> for the + character <[c]>. The search only ends with the first + occurrence of <[c]>, or after <[length]> characters; in + particular, <> does not terminate the search. + +RETURNS + If the character <[c]> is found within <[length]> characters + of <<*<[src]>>>, a pointer to the character is returned. If + <[c]> is not found, then <> is returned. + +PORTABILITY +<> is ANSI C. + +<> requires no supporting OS subroutines. + +QUICKREF + memchr ansi pure +*/ + +#include <_ansi.h> +#include +#include +#include "../../string/local.h" + +void * +memchr (const void *src_void, + int c, + size_t length) +{ + const unsigned char *src = (const unsigned char *) src_void; + unsigned char d = c; + +#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) + unsigned long *asrc; + unsigned long mask; + unsigned int i; + + while (UNALIGNED_X(src)) + { + if (!length--) + return NULL; + if (*src == d) + return (void *) src; + src++; + } + + if (!TOO_SMALL_LITTLE_BLOCK(length)) + { + /* If we get this far, we know that length is large and src is + word-aligned. */ + /* The fast code reads the source one word at a time and only + performs the bytewise search on word-sized segments if they + contain the search character, which is detected by XORing + the word-sized segment with a word-sized block of the search + character and then detecting for the presence of NUL in the + result. */ + asrc = (unsigned long *) src; + mask = d << 8 | d; + mask = mask << 16 | mask; + for (i = 32; i < sizeof(mask) * 8; i <<= 1) + mask = (mask << i) | mask; + + while (!TOO_SMALL_LITTLE_BLOCK(length)) + { + if (DETECT_CHAR(*asrc, mask)) + break; + length -= LITTLE_BLOCK_SIZE; + asrc++; + } + + /* If there are fewer than LITTLE_BLOCK_SIZE characters left, + then we resort to the bytewise loop. */ + + src = (unsigned char *) asrc; + } + +#endif /* not PREFER_SIZE_OVER_SPEED */ + + while (length--) + { + if (*src == d) + return (void *) src; + src++; + } + + return NULL; +} diff --git a/newlib/libc/machine/riscv/memrchr.c b/newlib/libc/machine/riscv/memrchr.c new file mode 100644 index 000000000000..8d15ccb780ec --- /dev/null +++ b/newlib/libc/machine/riscv/memrchr.c @@ -0,0 +1,99 @@ +/* +FUNCTION + <>---reverse search for character in memory + +INDEX + memrchr + +SYNOPSIS + #include + void *memrchr(const void *<[src]>, int <[c]>, size_t <[length]>); + +DESCRIPTION + This function searches memory starting at <[length]> bytes + beyond <<*<[src]>>> backwards for the character <[c]>. + The search only ends with the first occurrence of <[c]>; in + particular, <> does not terminate the search. + +RETURNS + If the character <[c]> is found within <[length]> characters + of <<*<[src]>>>, a pointer to the character is returned. If + <[c]> is not found, then <> is returned. + +PORTABILITY +<> is a GNU extension. + +<> requires no supporting OS subroutines. + +QUICKREF + memrchr +*/ + +#include <_ansi.h> +#include +#include +#include "../../string/local.h" + +void * +memrchr (const void *src_void, + int c, + size_t length) +{ + const unsigned char *src = (const unsigned char *) src_void + length - 1; + unsigned char d = c; + +#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) + unsigned long *asrc; + unsigned long mask; + unsigned int i; + + while (UNALIGNED_X(src)) + { + if (!length--) + return NULL; + if (*src == d) + return (void *) src; + src--; + } + + if (!TOO_SMALL_LITTLE_BLOCK(length)) + { + /* If we get this far, we know that length is large and src is + word-aligned. */ + /* The fast code reads the source one word at a time and only + performs the bytewise search on word-sized segments if they + contain the search character, which is detected by XORing + the word-sized segment with a word-sized block of the search + character and then detecting for the presence of NUL in the + result. */ + asrc = (unsigned long *) (src - LITTLE_BLOCK_SIZE + 1); + mask = d << 8 | d; + mask = mask << 16 | mask; + for (i = 32; i < sizeof(mask) * 8; i <<= 1) + mask = (mask << i) | mask; + + while (!TOO_SMALL_LITTLE_BLOCK(length)) + { + if (DETECT_CHAR(*asrc, mask)) + break; + length -= LITTLE_BLOCK_SIZE; + asrc--; + } + + /* If there are fewer than LITTLE_BLOCK_SIZE characters left, + then we resort to the bytewise loop. */ + + src = (unsigned char *) asrc + LITTLE_BLOCK_SIZE - 1; + } + +#endif /* not PREFER_SIZE_OVER_SPEED */ + + while (length--) + { + if (*src == d) + return (void *) src; + src--; + } + + return NULL; +}