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.

63 lines
1.1 KiB
ArmAsm

/* 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)