/* memset/bzero -- set memory area to CH/0 Optimized version for x86-64. Copyright (C) 2002-2016 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see . */ #include .text #if IS_IN (libc) ENTRY(__bzero) movq %rdi, %rax /* Set return value. */ movq %rsi, %rdx /* Set n. */ pxor %xmm0, %xmm0 jmp L(entry_from_bzero) END(__bzero) weak_alias (__bzero, bzero) /* Like memset but takes additional parameter with return value. */ ENTRY(__memset_tail) movq %rcx, %rax /* Set return value. */ movd %esi, %xmm0 punpcklbw %xmm0, %xmm0 punpcklwd %xmm0, %xmm0 pshufd $0, %xmm0, %xmm0 jmp L(entry_from_bzero) END(__memset_tail) #endif #if defined PIC && IS_IN (libc) ENTRY_CHK (__memset_chk) cmpq %rdx, %rcx jb HIDDEN_JUMPTARGET (__chk_fail) END_CHK (__memset_chk) #endif ENTRY (memset) movd %esi, %xmm0 movq %rdi, %rax punpcklbw %xmm0, %xmm0 punpcklwd %xmm0, %xmm0 pshufd $0, %xmm0, %xmm0 L(entry_from_bzero): cmpq $64, %rdx ja L(loop_start) cmpq $16, %rdx jbe L(less_16_bytes) cmpq $32, %rdx movdqu %xmm0, (%rdi) movdqu %xmm0, -16(%rdi,%rdx) ja L(between_32_64_bytes) L(return): rep ret .p2align 4 L(between_32_64_bytes): movdqu %xmm0, 16(%rdi) movdqu %xmm0, -32(%rdi,%rdx) ret .p2align 4 L(loop_start): leaq 64(%rdi), %rcx movdqu %xmm0, (%rdi) andq $-64, %rcx movdqu %xmm0, -16(%rdi,%rdx) movdqu %xmm0, 16(%rdi) movdqu %xmm0, -32(%rdi,%rdx) movdqu %xmm0, 32(%rdi) movdqu %xmm0, -48(%rdi,%rdx) movdqu %xmm0, 48(%rdi) movdqu %xmm0, -64(%rdi,%rdx) addq %rdi, %rdx andq $-64, %rdx cmpq %rdx, %rcx je L(return) .p2align 4 L(loop): movdqa %xmm0, (%rcx) movdqa %xmm0, 16(%rcx) movdqa %xmm0, 32(%rcx) movdqa %xmm0, 48(%rcx) addq $64, %rcx cmpq %rcx, %rdx jne L(loop) rep ret L(less_16_bytes): movq %xmm0, %rcx testb $24, %dl jne L(between8_16bytes) testb $4, %dl jne L(between4_7bytes) testb $1, %dl je L(odd_byte) movb %cl, (%rdi) L(odd_byte): testb $2, %dl je L(return) movw %cx, -2(%rax,%rdx) ret L(between4_7bytes): movl %ecx, (%rdi) movl %ecx, -4(%rdi,%rdx) ret L(between8_16bytes): movq %rcx, (%rdi) movq %rcx, -8(%rdi,%rdx) ret END (memset) libc_hidden_builtin_def (memset) #if defined PIC && IS_IN (libc) && !defined USE_MULTIARCH strong_alias (__memset_chk, __memset_zero_constant_len_parameter) .section .gnu.warning.__memset_zero_constant_len_parameter .string "memset used with constant zero length parameter; this could be due to transposed parameters" #endif