coreboot-kgpe-d16/src/arch/x86/memset.c
Patrick Georgi 11f0079c5a src/arch/x86: Convert to SPDX license header
This also drops individual copyright notices, all mentioned authors in
that part of the tree are listed in AUTHORS.

Change-Id: Ib5a92bb46ff2b9d2928aae3763daec71747044c2
Signed-off-by: Patrick Georgi <pgeorgi@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/39284
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: HAOUAS Elyes <ehaouas@noos.fr>
2020-03-06 07:48:24 +00:00

65 lines
1.5 KiB
C

/* SPDX-License-Identifier: GPL-2.0-or-later */
/* This file is part of the coreboot project. */
/* From glibc-2.14, sysdeps/i386/memset.c */
#include <string.h>
#include <stdint.h>
typedef uint32_t op_t;
void *memset(void *dstpp, int c, size_t len)
{
int d0;
unsigned long int dstp = (unsigned long int) dstpp;
/* This explicit register allocation improves code very much indeed. */
register op_t x asm("ax");
x = (unsigned char) c;
/* Clear the direction flag, so filling will move forward. */
asm volatile("cld");
/* This threshold value is optimal. */
if (len >= 12) {
/* Fill X with four copies of the char we want to fill with. */
x |= (x << 8);
x |= (x << 16);
/* Adjust LEN for the bytes handled in the first loop. */
len -= (-dstp) % sizeof(op_t);
/*
* There are at least some bytes to set. No need to test for
* LEN == 0 in this alignment loop.
*/
/* Fill bytes until DSTP is aligned on a longword boundary. */
asm volatile(
"rep\n"
"stosb" /* %0, %2, %3 */ :
"=D" (dstp), "=c" (d0) :
"0" (dstp), "1" ((-dstp) % sizeof(op_t)), "a" (x) :
"memory");
/* Fill longwords. */
asm volatile(
"rep\n"
"stosl" /* %0, %2, %3 */ :
"=D" (dstp), "=c" (d0) :
"0" (dstp), "1" (len / sizeof(op_t)), "a" (x) :
"memory");
len %= sizeof(op_t);
}
/* Write the last few bytes. */
asm volatile(
"rep\n"
"stosb" /* %0, %2, %3 */ :
"=D" (dstp), "=c" (d0) :
"0" (dstp), "1" (len), "a" (x) :
"memory");
return dstpp;
}