You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
/* Copyright (C) 2021,2022 fef <owo@fef.moe>. All rights reserved. */
|
|
|
|
|
|
|
|
#include <asm/common.h>
|
|
|
|
|
|
|
|
/* void *memset(void *dest, int c, usize n) */
|
|
|
|
ENTRY(memset)
|
|
|
|
pushq %rbp
|
|
|
|
movq %rsp, %rbp
|
|
|
|
|
|
|
|
cld
|
|
|
|
|
|
|
|
movq %rdi, %r11 /* save original pointer to dest */
|
|
|
|
|
|
|
|
movl %esi, %eax /* move `c' into correct register for rep;stosq */
|
|
|
|
movq %rdx, %rcx /* move `n' into correct register for rep;stosq */
|
|
|
|
|
|
|
|
cmpq $16, %rcx
|
|
|
|
jb out /* n < 16, not worth the effort */
|
|
|
|
|
|
|
|
testl $1, %edi
|
|
|
|
jz 2f
|
|
|
|
stosb
|
|
|
|
decq %rcx
|
|
|
|
|
|
|
|
/* 2-byte aligned */
|
|
|
|
2: movl %eax, %edx
|
|
|
|
shll $8, %eax
|
|
|
|
orl %edx, %eax /* c |= (c << 8) */
|
|
|
|
|
|
|
|
testl $2, %edi
|
|
|
|
jz 4f
|
|
|
|
stosw
|
|
|
|
subq $2, %rcx
|
|
|
|
|
|
|
|
/* 4-byte aligned */
|
|
|
|
4: movl %eax, %edx
|
|
|
|
shll $16, %eax
|
|
|
|
orl %edx, %eax /* c |= (c << 16) */
|
|
|
|
|
|
|
|
testl $4, %edi
|
|
|
|
jz 8f
|
|
|
|
stosl
|
|
|
|
subq $4, %rcx
|
|
|
|
|
|
|
|
/* 8-byte aligned, now we can fire stosq */
|
|
|
|
8: movl %eax, %edx
|
|
|
|
shlq $32, %rax
|
|
|
|
orq %rdx, %rax /* c |= (c << 32) */
|
|
|
|
movl %ecx, %edx
|
|
|
|
andl $7, %edx /* edx = n % 8 */
|
|
|
|
shrq $3, %rcx /* n /= 8 */
|
|
|
|
rep
|
|
|
|
stosq
|
|
|
|
movl %edx, %ecx
|
|
|
|
|
|
|
|
/* write out remaining bytes (or do the whole memset, if n < 16) */
|
|
|
|
out: rep
|
|
|
|
stosb
|
|
|
|
movq %r11, %rax /* return original pointer to dest */
|
|
|
|
popq %rbp
|
|
|
|
retq
|
|
|
|
END(memset)
|