char *strrchr( const char *s, int c ) #endif /*********************************************/ { RISC_DATA_LOCALREF; UINT *result = NULL; CHAR_TYPE *result2 = NULL; UINT *dw = ROUND(s); // round down to dword UINT mask, dword, cdword, tmpdword; size_t len = 0; int offset = OFFSET(s); #ifdef __WIDECHAR__ UINT cShl16; #else UINT cShl8, cShl16, cShl24; #endif #ifdef __WIDECHAR__ if( offset % 2 ) return( __simple_wcsrchr( s, c ) ); #endif /*** If searching for '\0', use different technique ***/ if( c == NULLCHAR ) return( (CHAR_TYPE*)s + __F_NAME(strlen,wcslen)( s ) ); /*** Initialize locals ***/ c &= CHR1MASK; #ifdef __WIDECHAR__ cShl16 = c << 16; cdword = cShl16 | c; #else cShl8 = c << 8; cShl16 = c << 16; cShl24 = c << 24; cdword = cShl24 | cShl16 | cShl8 | c; #endif dword = *dw; /*** Scan any bytes up to a 4-byte alignment ***/ if( OFFSET_GOT_NIL(dword,offset) ) { /* there is a null char in the first word */ tmpdword = SKIP_CHRS(dword,offset/CHARSIZE) ^ cdword; if( GOT_NIL(tmpdword) ) { /* c is in the first word */ #ifdef __WIDECHAR__ if( offset == 0 ) { /* no odd alignments */ tmpdword = CHR1(dword); if( tmpdword == c ) { result2 = (CHAR_TYPE*)s; } else if( tmpdword == 0 ) { return( NULL ); } len++; } #else switch( offset ) { case 0: tmpdword = CHR1(dword); if( tmpdword == c ) { result2 = (CHAR_TYPE*)s; } else if( tmpdword == 0 ) { return( NULL ); } len++; /* fall through */ case 1: tmpdword = CHR2(dword); if( tmpdword == cShl8 ) { result2 = (CHAR_TYPE*)s+len; } else if( tmpdword == 0 ) { return( result2 ); } len++; /* fall through */ case 2: tmpdword = CHR3(dword); if( tmpdword == cShl16 ) { return (CHAR_TYPE*)s+len; } else { return( result2 ); } } #endif } return( result2 ); } else { tmpdword = SKIP_CHRS(dword,offset/CHARSIZE) ^ cdword; if( GOT_NIL(tmpdword) ) { // c is in the first word result = dw; mask = SKIP_CHRS_MASKS(offset/CHARSIZE); } } /*** Scan in aligned 4-byte groups ***/ for( ;; ) { dword = *(++dw); if( GOT_NIL(dword) ) break; tmpdword = dword ^ cdword; if( GOT_NIL(tmpdword)) { result = dw; mask = SKIP_CHRS_MASKS(0); } dword = *(++dw); if( GOT_NIL(dword) ) break; tmpdword = dword ^ cdword; if( GOT_NIL(tmpdword)) { result = dw; mask = SKIP_CHRS_MASKS(0); } } /*** Scan the last byte(s) in the string ***/ /* we have a null char somewhere in the last dword */ #ifdef __WIDECHAR__ if( CHR1(dword) ) { // first char in the dword is not null if( CHR1(dword) == c ) { return( (CHAR_TYPE*)dw ); } } #else if( CHR1(dword) ) { // first char in the dword is not null if( CHR2(dword) ) { // second char in the dword is not null if( CHR3(dword) ) { // third char in the dword is not null if ( ( CHR3(dword) ) == cShl16 ) { return( ((char *)dw) + 2 ); } else if ( ( CHR2(dword) ) == cShl8 ) { return( ((char *)dw) + 1 ); } else if ( ( CHR1(dword) ) == c ) { return( (char *)dw ); } } else { if ( ( CHR2(dword) ) == cShl8 ) { return ((char *)dw)+1; } else if ( ( CHR1(dword) ) == c ) { return( (char *)dw ); } } } else { if ( ( CHR1(dword) ) == c ) { return( (char *)dw ); } } } #endif if( result != NULL ) { // we found a dword with c dword = *result; dword &= mask; #ifdef __WIDECHAR__ if( CHR2(dword) == cShl16 ) { return( ((CHAR_TYPE*)result) + 1 ); } #else if( CHR4(dword) == cShl24 ) { return( ((CHAR_TYPE*)result) + 3 ); } else if( CHR3(dword) == cShl16 ) { return( ((CHAR_TYPE*)result) + 2 ); } else if( CHR2(dword) == cShl8 ) { return( ((CHAR_TYPE*)result) + 1 ); } #endif } return( (CHAR_TYPE*)result ); }
size_t __F_NAME(strlen,wcslen)( const CHAR_TYPE *s ) /**************************************************/ { RISC_DATA_LOCALREF; int offset = OFFSET(s); UINT *dw = ROUND(s); /* round down to dword */ UINT dword; size_t len = 0; #ifdef __WIDECHAR__ if( offset % 2 ) return( __simple_wcslen( s ) ); #endif /*** Scan until s is aligned ***/ dword = *dw++; if( OFFSET_GOT_NIL(dword,offset) ) { #if USE_INT64 switch( offset ) { case 0: if( !CHR1(dword) ) break; len++; /* fall through */ case 1: if( !CHR2(dword) ) break; len++; /* fall through */ case 2: if( !CHR3(dword) ) break; len++; /* fall through */ case 3: if( !CHR4(dword) ) break; len++; /* fall through */ case 4: if( !CHR5(dword) ) break; len++; /* fall through */ case 5: if( !CHR6(dword) ) break; len++; /* fall through */ case 6: if( !CHR7(dword) ) break; len++; /* fall through */ default: break; } #else #ifdef __WIDECHAR__ switch( offset ) { case 0: if( !CHR1(dword) ) break; len++; /* fall through */ default: /* offset==2 (no odd offsets) */ break; } #else switch( offset ) { case 0: if( !CHR1(dword) ) break; len++; /* fall through */ case 1: if( !CHR2(dword) ) break; len++; /* fall through */ case 2: if( !CHR3(dword) ) break; len++; /* fall through */ default: break; } #endif #endif return( len ); } else { len += ( BYTES_PER_WORD - offset ) / CHARSIZE; } /*** Scan one word at a time until a null char is found ***/ for( ;; ) { dword = *dw++; if( GOT_NIL(dword) ) break; dword = *dw++; if( GOT_NIL(dword) ) break; } /*** Locate the null char within the offending word ***/ len = (CHAR_TYPE*)dw - s; #if USE_INT64 if( !CHR1(dword) ) { len -= 8; } else if( !CHR2(dword) ) { len -= 7; } else if( !CHR3(dword) ) { len -= 6; } else if( !CHR4(dword) ) { len -= 5; } else if( !CHR5(dword) ) { len -= 4; } else if( !CHR6(dword) ) { len -= 3; } else if( !CHR7(dword) ) { len -= 2; } else { len -= 1; } #else #ifdef __WIDECHAR__ if( !CHR1(dword) ) { len -= 2; } else { len -= 1; } #else if( !CHR1(dword) ) { len -= 4; } else if( !CHR2(dword) ) { len -= 3; } else if( !CHR3(dword) ) { len -= 2; } else { len -= 1; } #endif #endif return( len ); }