From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2155) id F168638582A1; Tue, 20 Dec 2022 21:54:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F168638582A1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1671573286; bh=uWrxdyPcdPpdQ7ZhhIHIDVgc+dEm8EiaE5dWFxfp9Bs=; h=From:To:Subject:Date:From; b=MRdNVjdq4RIOooNNYY3/AimoT3WxS6PimaYFPyUuyy66uY0AaZBwk6Tz/Xw7z3u8b hU01cLK9ADCeS81Hn+SlDRVogXJ8w86NJUhF6G2mpCvs42obW4PEe/VXUe0WcXLmcb KiISga5qiDWPUFxJuHPLz0Eq7B4dLd7EWj521tqU= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Corinna Vinschen To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin] Cygwin: x86_64: import new memset.S from NetBSD X-Act-Checkin: newlib-cygwin X-Git-Author: Corinna Vinschen X-Git-Refname: refs/heads/master X-Git-Oldrev: 8e83ca675f522d132ca35d847aa35f310951702e X-Git-Newrev: 3830325502a64c303f9296b7f1e670022da8fa53 Message-Id: <20221220215446.F168638582A1@sourceware.org> Date: Tue, 20 Dec 2022 21:54:46 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3D3830325502a= 64c303f9296b7f1e670022da8fa53 commit 3830325502a64c303f9296b7f1e670022da8fa53 Author: Corinna Vinschen AuthorDate: Tue Dec 20 10:03:17 2022 +0100 Commit: Corinna Vinschen CommitDate: Tue Dec 20 10:13:59 2022 +0100 Cygwin: x86_64: import new memset.S from NetBSD =20 Signed-off-by: Corinna Vinschen Diff: --- winsup/cygwin/x86_64/memset.S | 138 +++++++++++++++++++++++++-------------= ---- 1 file changed, 81 insertions(+), 57 deletions(-) diff --git a/winsup/cygwin/x86_64/memset.S b/winsup/cygwin/x86_64/memset.S index ac73b6ace893..f91d134efd29 100644 --- a/winsup/cygwin/x86_64/memset.S +++ b/winsup/cygwin/x86_64/memset.S @@ -1,69 +1,93 @@ -/* These functions are almost verbatim FreeBSD code (even if the header of - one file mentiones NetBSD), just wrapped in the minimum required code to - make them work under the MS AMD64 ABI. - See FreeBSD src/lib/libc/amd64/string/memset.S */ +/* $NetBSD: memset.S,v 1.5 2014/05/22 16:47:31 pooka Exp $ */ =20 -/* - * Written by J.T. Conklin . - * Public domain. - * Adapted for NetBSD/x86_64 by - * Frank van der Linden +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by David Laight. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTO= RS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIM= ITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICU= LAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTO= RS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF = THE + * POSSIBILITY OF SUCH DAMAGE. */ =20 - .globl memset - .seh_proc memset -memset: - movq %rsi,8(%rsp) - movq %rdi,16(%rsp) - .seh_endprologue - movq %rcx,%rdi - movq %rdx,%rsi - movq %r8,%rdx - - movq %rsi,%rax - andq $0xff,%rax - movq %rdx,%rcx - movq %rdi,%r11 - - cld /* set fill direction forward */ +#include =20 - /* if the string is too short, it's really not worth the - * overhead of aligning to word boundries, etc. So we jump to - * a plain unaligned set. */ - cmpq $0x0f,%rcx - jle L1 +#if defined(LIBC_SCCS) + RCSID("$NetBSD: memset.S,v 1.5 2014/05/22 16:47:31 pooka Exp $") +#endif =20 - movb %al,%ah /* copy char to all bytes in word */ - movl %eax,%edx - sall $16,%eax - orl %edx,%eax +#ifndef _KERNEL +/* bzero, %rdi is buffer, %rsi length */ =20 - movl %eax,%edx - salq $32,%rax - orq %rdx,%rax +ENTRY2(bzero) + mov %rsi,%rdx /* length */ + xor %eax,%eax /* value to write */ + jmp 1f +END(bzero) +#endif =20 - movq %rdi,%rdx /* compute misalignment */ - negq %rdx - andq $7,%rdx - movq %rcx,%r8 - subq %rdx,%r8 +/* memset, %rdi is buffer, %rsi char to fill, %rdx length */ =20 - movq %rdx,%rcx /* set until word aligned */ - rep - stosb +ENTRY3(memset) + movzbq %sil,%rax /* byte value to fill */ + mov %rdx,%rsi /* copy of length */ + mov $0x0101010101010101,%r9 + imul %r9,%rax /* fill value in all bytes */ =20 - movq %r8,%rcx - shrq $3,%rcx /* set by words */ - rep - stosq +1: + mov %rdi,%r9 /* Need to return buffer address */ + or %edi,%edx /* address | length */ + mov %rsi,%rcx + cmp $7,%rsi + jbe 10f /* jump if short fill */ + test $7,%dl /* check for misaligned fill */ + jnz 20f /* jump if misaligned */ =20 - movq %r8,%rcx /* set remainder by bytes */ - andq $7,%rcx -L1: rep - stosb - movq %r11,%rax +/* Target aligned and length multiple of 8 */ +2: + shr $3,%rcx + rep stosq + mov %r9,%rax + ret =20 - movq 8(%rsp),%rsi - movq 16(%rsp),%rdi +/* + * Short transfer, any faffing here will generate mispredicted branches. + * So we keep it simple. + */ +10: rep stosb + mov %r9,%rax ret - .seh_endproc + +/* + * Buffer or length misaligned. + * Write pattern to first and last word of buffer, then fill middle. + * (This writes to some bytes more than once - possibly three times!.) + */ +20: + mov %rax,(%rdi) + movzbq %dil,%rdx /* low address for alignment */ + mov %rax,-8(%rcx,%rdi) + and $7,%dl /* offset in word */ + sub %rdx,%rcx /* adjust length ... */ + add %rdx,%rdi /* ... and target */ + jmp 2b +END(memset)