176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifndef ETHERBOOT_BITS_STRING_H 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define ETHERBOOT_BITS_STRING_H 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Taken from Linux /usr/include/asm/string.h 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * All except memcpy, memmove, memset and memcmp removed. 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Non-standard memswap() function added because it saves quite a bit 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * of code (mbrown@fensystems.co.uk). 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * This string-include defines all string functions as inline 1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * functions. Use gcc. It also assumes ds=es=data space, this should be 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * normal. Most of the string-functions are rather heavily hand-optimized, 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * see especially strtok,strstr,str[c]spn. They should work, but are not 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * very easy to understand. Everything is done entirely within the register 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * set, making the functions fast and clean. String instructions have been 1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * used through-out, making for "slightly" unclear code :-) 1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * NO Copyright (C) 1991, 1992 Linus Torvalds, 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * consider these trivial functions to be PD. 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2476d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFILE_LICENCE ( PUBLIC_DOMAIN ); 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __HAVE_ARCH_MEMCPY 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void * __memcpy ( void *dest, const void *src, size_t len ); 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if 0 3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __attribute__ (( always_inline )) void * 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman__memcpy ( void *dest, const void *src, size_t len ) { 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int d0, d1, d2; 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __asm__ __volatile__ ( "rep ; movsb" 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "=&c" ( d0 ), "=&S" ( d1 ), "=&D" ( d2 ) 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "0" ( len ), "1" ( src ), "2" ( dest ) 3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "memory" ); 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return dest; 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __attribute__ (( always_inline )) void * 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman__constant_memcpy ( void *dest, const void *src, size_t len ) { 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman union { 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint32_t u32[2]; 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint16_t u16[4]; 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint8_t u8[8]; 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } __attribute__ (( __may_alias__ )) *dest_u = dest; 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const union { 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint32_t u32[2]; 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint16_t u16[4]; 5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint8_t u8[8]; 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } __attribute__ (( __may_alias__ )) *src_u = src; 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const void *esi; 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *edi; 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman switch ( len ) { 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 0 : /* 0 bytes */ 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return dest; 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Single-register moves; these are always better than a 6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * string operation. We can clobber an arbitrary two 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * registers (data, source, dest can re-use source register) 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * instead of being restricted to esi and edi. There's also a 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * much greater potential for optimising with nearby code. 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 1 : /* 4 bytes */ 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dest_u->u8[0] = src_u->u8[0]; 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return dest; 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 2 : /* 6 bytes */ 7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dest_u->u16[0] = src_u->u16[0]; 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return dest; 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 4 : /* 4 bytes */ 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dest_u->u32[0] = src_u->u32[0]; 7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return dest; 7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Double-register moves; these are probably still a win. 7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 3 : /* 12 bytes */ 8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dest_u->u16[0] = src_u->u16[0]; 8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dest_u->u8[2] = src_u->u8[2]; 8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return dest; 8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 5 : /* 10 bytes */ 8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dest_u->u32[0] = src_u->u32[0]; 8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dest_u->u8[4] = src_u->u8[4]; 8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return dest; 8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 6 : /* 12 bytes */ 9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dest_u->u32[0] = src_u->u32[0]; 9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dest_u->u16[2] = src_u->u16[2]; 9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return dest; 9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 8 : /* 10 bytes */ 9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dest_u->u32[0] = src_u->u32[0]; 9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dest_u->u32[1] = src_u->u32[1]; 9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return dest; 9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Even if we have to load up esi and edi ready for a string 10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * operation, we can sometimes save space by using multiple 10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * single-byte "movs" operations instead of loading up ecx and 10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * using "rep movsb". 10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * "load ecx, rep movsb" is 7 bytes, plus an average of 1 byte 10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * to allow for saving/restoring ecx 50% of the time. 10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * "movsl" and "movsb" are 1 byte each, "movsw" is two bytes. 10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * (In 16-bit mode, "movsl" is 2 bytes and "movsw" is 1 byte, 10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * but "movsl" moves twice as much data, so it balances out). 11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * The cutoff point therefore occurs around 26 bytes; the byte 11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * requirements for each method are: 11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * len 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * #bytes (ecx) 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * #bytes (no ecx) 4 5 6 7 5 6 7 8 6 7 8 9 7 8 9 10 11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman esi = src; 12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman edi = dest; 12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( len >= 26 ) 12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return __memcpy ( dest, src, len ); 12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( len >= 6*4 ) 12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __asm__ __volatile__ ( "movsl" : "=&D" ( edi ), "=&S" ( esi ) 12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "0" ( edi ), "1" ( esi ) : "memory" ); 12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( len >= 5*4 ) 12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __asm__ __volatile__ ( "movsl" : "=&D" ( edi ), "=&S" ( esi ) 13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "0" ( edi ), "1" ( esi ) : "memory" ); 13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( len >= 4*4 ) 13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __asm__ __volatile__ ( "movsl" : "=&D" ( edi ), "=&S" ( esi ) 13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "0" ( edi ), "1" ( esi ) : "memory" ); 13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( len >= 3*4 ) 13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __asm__ __volatile__ ( "movsl" : "=&D" ( edi ), "=&S" ( esi ) 13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "0" ( edi ), "1" ( esi ) : "memory" ); 13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( len >= 2*4 ) 13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __asm__ __volatile__ ( "movsl" : "=&D" ( edi ), "=&S" ( esi ) 13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "0" ( edi ), "1" ( esi ) : "memory" ); 14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( len >= 1*4 ) 14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __asm__ __volatile__ ( "movsl" : "=&D" ( edi ), "=&S" ( esi ) 14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "0" ( edi ), "1" ( esi ) : "memory" ); 14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ( len % 4 ) >= 2 ) 14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __asm__ __volatile__ ( "movsw" : "=&D" ( edi ), "=&S" ( esi ) 14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "0" ( edi ), "1" ( esi ) : "memory" ); 14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ( len % 2 ) >= 1 ) 14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __asm__ __volatile__ ( "movsb" : "=&D" ( edi ), "=&S" ( esi ) 14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "0" ( edi ), "1" ( esi ) : "memory" ); 14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return dest; 15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define memcpy( dest, src, len ) \ 15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ( __builtin_constant_p ( (len) ) ? \ 15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __constant_memcpy ( (dest), (src), (len) ) : \ 15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __memcpy ( (dest), (src), (len) ) ) 15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __HAVE_ARCH_MEMMOVE 15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void * memmove(void * dest,const void * src, size_t n) 16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint d0, d1, d2; 16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanif (dest<src) 16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman__asm__ __volatile__( 16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "cld\n\t" 16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "rep\n\t" 16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "movsb" 16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "=&c" (d0), "=&S" (d1), "=&D" (d2) 16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman :"0" (n),"1" (src),"2" (dest) 16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "memory"); 17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanelse 17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman__asm__ __volatile__( 17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "std\n\t" 17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "rep\n\t" 17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "movsb\n\t" 17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "cld" 17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "=&c" (d0), "=&S" (d1), "=&D" (d2) 17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman :"0" (n), 17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "1" (n-1+(const char *)src), 17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "2" (n-1+(char *)dest) 18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman :"memory"); 18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanreturn dest; 18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __HAVE_ARCH_MEMSET 18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void * memset(void *s, int c,size_t count) 18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint d0, d1; 18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman__asm__ __volatile__( 18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "cld\n\t" 19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "rep\n\t" 19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "stosb" 19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "=&c" (d0), "=&D" (d1) 19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman :"a" (c),"1" (s),"0" (count) 19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman :"memory"); 19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanreturn s; 19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __HAVE_ARCH_MEMSWAP 19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void * memswap(void *dest, void *src, size_t n) 20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint d0, d1, d2, d3; 20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman__asm__ __volatile__( 20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "\n1:\t" 20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "movb (%%edi),%%al\n\t" 20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "xchgb (%%esi),%%al\n\t" 20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "incl %%esi\n\t" 20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "stosb\n\t" 20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "loop 1b" 20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "=&c" (d0), "=&S" (d1), "=&D" (d2), "=&a" (d3) 21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "0" (n), "1" (src), "2" (dest) 21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "memory" ); 21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanreturn dest; 21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __HAVE_ARCH_STRNCMP 21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline int strncmp(const char * cs,const char * ct,size_t count) 21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanregister int __res; 21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint d0, d1, d2; 22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman__asm__ __volatile__( 22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "1:\tdecl %3\n\t" 22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "js 2f\n\t" 22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "lodsb\n\t" 22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "scasb\n\t" 22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "jne 3f\n\t" 22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "testb %%al,%%al\n\t" 22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "jne 1b\n" 22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "2:\txorl %%eax,%%eax\n\t" 22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "jmp 4f\n" 23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "3:\tsbbl %%eax,%%eax\n\t" 23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "orb $1,%%al\n" 23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "4:" 23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2) 23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman :"1" (cs),"2" (ct),"3" (count)); 23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanreturn __res; 23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __HAVE_ARCH_STRLEN 23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline size_t strlen(const char * s) 24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint d0; 24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanregister int __res; 24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman__asm__ __volatile__( 24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "repne\n\t" 24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "scasb\n\t" 24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "notl %0\n\t" 24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "decl %0" 24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman :"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff)); 24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanreturn __res; 25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* ETHERBOOT_BITS_STRING_H */ 253