mirror of
https://github.com/ipxe/ipxe
synced 2025-12-31 15:25:23 +03:00
[libc] Rewrite string functions
Some of the C library string functions have an unknown provenance. Reimplement all such functions to avoid potential licensing uncertainty. Remove the inline-assembler versions of strlen(), memswap(), and strncmp(); these save a minimal amount of space (around 40 bytes in total) and are not performance-critical. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -104,87 +104,3 @@ void * __memmove ( void *dest, const void *src, size_t len ) {
|
||||
return __memcpy_reverse ( dest, src, len );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap memory areas
|
||||
*
|
||||
* @v dest Destination address
|
||||
* @v src Source address
|
||||
* @v len Length
|
||||
* @ret dest Destination address
|
||||
*/
|
||||
void * memswap ( void *dest, void *src, size_t len ) {
|
||||
size_t discard_c;
|
||||
int discard;
|
||||
|
||||
__asm__ __volatile__ ( "\n1:\n\t"
|
||||
"dec %2\n\t"
|
||||
"js 2f\n\t"
|
||||
"movb (%0,%2), %b3\n\t"
|
||||
"xchgb (%1,%2), %b3\n\t"
|
||||
"movb %b3, (%0,%2)\n\t"
|
||||
"jmp 1b\n\t"
|
||||
"2:\n\t"
|
||||
: "=r" ( src ), "=r" ( dest ),
|
||||
"=&c" ( discard_c ), "=&q" ( discard )
|
||||
: "0" ( src ), "1" ( dest ), "2" ( len )
|
||||
: "memory" );
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate length of string
|
||||
*
|
||||
* @v string String
|
||||
* @ret len Length (excluding NUL)
|
||||
*/
|
||||
size_t strlen ( const char *string ) {
|
||||
const char *discard_D;
|
||||
size_t len_plus_one;
|
||||
|
||||
__asm__ __volatile__ ( "repne scasb\n\t"
|
||||
"not %1\n\t"
|
||||
: "=&D" ( discard_D ), "=&c" ( len_plus_one )
|
||||
: "0" ( string ), "1" ( -1UL ), "a" ( 0 ) );
|
||||
|
||||
return ( len_plus_one - 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare strings (up to a specified length)
|
||||
*
|
||||
* @v str1 First string
|
||||
* @v str2 Second string
|
||||
* @v len Maximum length
|
||||
* @ret diff Difference
|
||||
*/
|
||||
int strncmp ( const char *str1, const char *str2, size_t len ) {
|
||||
const void *discard_S;
|
||||
const void *discard_D;
|
||||
size_t discard_c;
|
||||
int diff;
|
||||
|
||||
__asm__ __volatile__ ( "\n1:\n\t"
|
||||
"dec %2\n\t"
|
||||
"js 2f\n\t"
|
||||
"lodsb\n\t"
|
||||
"scasb\n\t"
|
||||
"jne 3f\n\t"
|
||||
"testb %b3, %b3\n\t"
|
||||
"jnz 1b\n\t"
|
||||
/* Equal */
|
||||
"\n2:\n\t"
|
||||
"xor %3, %3\n\t"
|
||||
"jmp 4f\n\t"
|
||||
/* Not equal; CF indicates difference */
|
||||
"\n3:\n\t"
|
||||
"sbb %3, %3\n\t"
|
||||
"orb $1, %b3\n\t"
|
||||
"\n4:\n\t"
|
||||
: "=&S" ( discard_S ), "=&D" ( discard_D ),
|
||||
"=&c" ( discard_c ), "=&a" ( diff )
|
||||
: "0" ( str1 ), "1" ( str2 ), "2" ( len ) );
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user