1405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham/* 2405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * Copyright (c) 2010 MIPS Technologies, Inc. 3405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * 4405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * All rights reserved. 5405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * 6405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * Redistribution and use in source and binary forms, with or without 7405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * modification, are permitted provided that the following conditions 8405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * are met: 9405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * 10405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * * Redistributions of source code must retain the above copyright 11405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * notice, this list of conditions and the following disclaimer. 12405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * * Redistributions in binary form must reproduce the above copyright 13405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * notice, this list of conditions and the following disclaimer 14405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * in the documentation and/or other materials provided with 15405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * the distribution. 16405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * * Neither the name of MIPS Technologies Inc. nor the names of its 17405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * contributors may be used to endorse or promote products derived 18405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * from this software without specific prior written permission. 19405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * 20405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham */ 32405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 33405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#include "mips-string-ops.h" 34405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 35405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define do_strlen_word(__av) {\ 36405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham if (detect_zero(x,x,_01s,_80s)) break;\ 37405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham x = __av;\ 38405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham cnt += sizeof (unsigned);\ 39405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham } 40405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 41405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define do_strlen_byte(__x) {\ 42405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham if ((bx.b.B##__x) == 0) break;\ 43405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham ++cnt;\ 44405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham } 45405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 46405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#if SMOKE_TEST_MIPS_STRLEN 47405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define strlen my_strlen 48405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#endif 49405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 50405b8029a6888f386adf3512113a33546141d1c8Raghu Gandhamint 51405b8029a6888f386adf3512113a33546141d1c8Raghu Gandhamstrlen (const void *_a) 52405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham{ 53405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham int cnt = 0; 54405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham unsigned x; 55405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 56405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham /* align the string to word boundary so we can do word at a time. */ 57405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham if ((cvt_ptr_to (unsigned, _a) & (sizeof (unsigned) - 1)) != 0) 58405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham { 59405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham if ((cvt_ptr_to (unsigned, _a) & 1) != 0) 60405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham { 61405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham if (get_byte (_a, 0) == 0) 62405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham return cnt; 63405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham /* set bit 1 so 2-bytes are checked and incremented. */ 64405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham inc_ptr_as (char *, _a, 1); 65405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham ++cnt; 66405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham } 67405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham if ((cvt_ptr_to (unsigned, _a) & 2) != 0) 68405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham { 69405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham if (get_byte (_a, 0) == 0) 70405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham return cnt + 0; 71405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham if (get_byte (_a, 1) == 0) 72405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham return cnt + 1; 73405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham inc_ptr_as (char *, _a, 2); 74405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham cnt += 2; 75405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham } 76405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham } 77405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 78405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#if __mips64 79405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#error strlen: mips64 check for 4-byte alignment not implemented. 80405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#endif 81405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 82405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham if (1) 83405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham { 84405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham def_and_set_01 (_01s); 85405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham def_and_set_80 (_80s); 86405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 87405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham /* as advantagous as it is to performance, this code cannot pre-load 88405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham the following word, nor can it prefetch the next line at the start 89405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham of the loop since the string can be at the end of a page with the 90405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham following page unmapped. There are tests in the suite to catch 91405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham any attempt to go beyond the current word. */ 92405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham x = get_word (_a, 0); 93405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham while (1) 94405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham { 95405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham /* doing 8 words should cover most strings. */ 96405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham do_strlen_word (get_word (_a, 1)); 97405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham do_strlen_word (get_word (_a, 2)); 98405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham do_strlen_word (get_word (_a, 3)); 99405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham do_strlen_word (get_word (_a, 4)); 100405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham do_strlen_word (get_word (_a, 5)); 101405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham do_strlen_word (get_word (_a, 6)); 102405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham do_strlen_word (get_word (_a, 7)); 103405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham do_strlen_word (get_word (_a, 8)); 104405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham inc_ptr_as (unsigned *, _a, 8); 105405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham } 106405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham } 107405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham while (1) 108405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham { 109405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham /* pull apart the last word processed and find the zero. */ 110405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham bitfields_t bx; 111405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham bx.v = x; 112405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#if __mips64 113405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham do_strlen_byte (0); 114405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham do_strlen_byte (1); 115405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham do_strlen_byte (2); 116405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham do_strlen_byte (3); 117405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham do_strlen_byte (4); 118405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham do_strlen_byte (5); 119405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham do_strlen_byte (6); 120405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#else 121405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham do_strlen_byte (0); 122405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham do_strlen_byte (1); 123405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham do_strlen_byte (2); 124405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#endif 125405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham /* last byte is zero */ 126405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham break; 127405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham } 128405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham return cnt; 129405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham} 130405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 131405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#undef do_strlen_byte 132405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#undef do_strlen_word 133405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 134405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#if SMOKE_TEST_MIPS_STRLEN 135405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#include <stdio.h> 136405b8029a6888f386adf3512113a33546141d1c8Raghu Gandhamchar str1[] = "DHRYSTONE PROGRAM, 1'ST STRING"; 137405b8029a6888f386adf3512113a33546141d1c8Raghu Gandhamchar str2[] = "DHRYSTONE PROGRAM, 2'ST STRING"; 138405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 139405b8029a6888f386adf3512113a33546141d1c8Raghu Gandhamchar str3[] = "another string"; 140405b8029a6888f386adf3512113a33546141d1c8Raghu Gandhamchar str4[] = "another"; 141405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 142405b8029a6888f386adf3512113a33546141d1c8Raghu Gandhamchar str5[] = "somes tring"; 143405b8029a6888f386adf3512113a33546141d1c8Raghu Gandhamchar str6[] = "somes_tring"; 144405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 145405b8029a6888f386adf3512113a33546141d1c8Raghu Gandhamchar str7[16], str8[16]; 146405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 147405b8029a6888f386adf3512113a33546141d1c8Raghu Gandhamstatic char * 148405b8029a6888f386adf3512113a33546141d1c8Raghu Gandhamchk (unsigned mine, unsigned libs, int *errors) 149405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham{ 150405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham static char answer[1024]; 151405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham char *result = mine == libs ? "PASS" : "FAIL"; 152405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham sprintf (answer, "new_strlen=%d: lib_strlen=%d: %s!", mine, libs, result); 153405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham if (mine != libs) 154405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham (*errors)++; 155405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham return answer; 156405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham} 157405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 158405b8029a6888f386adf3512113a33546141d1c8Raghu Gandhamint 159405b8029a6888f386adf3512113a33546141d1c8Raghu Gandhammain (int argc, char **argv) 160405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham{ 161405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham int errors = 0; 162405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham /* set -1 in one position */ 163405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham str6[5] = 0xff; 164405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham /* set zero in same position with junk in following 3 */ 165405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham str7[0] = str8[0] = 0; 166405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham str7[1] = 0xff; 167405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham str7[2] = 'a'; 168405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham str7[3] = 2; 169405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham str8[1] = 's'; 170405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham str8[2] = -2; 171405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham str8[3] = 0; 172405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 173405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham fprintf (stderr, "========== mips_strlen%s test...\n", 174405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham argv[0] ? argv[0] : "unknown strlen"); 175405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define P(__x,__y) {\ 176405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham int a = my_strlen(__x + __y);\ 177405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham int b = (strlen)(__x + __y) /* library version */;\ 178405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham fprintf(stderr,"%s+%d: %s\n",#__x,__y,chk(a,b,&errors));\ 179405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham } 180405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 181405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str1, 0); 182405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str1, 1); 183405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str1, 2); 184405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str1, 3); 185405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 186405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str2, 0); 187405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str2, 1); 188405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str2, 2); 189405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str2, 3); 190405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 191405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str3, 0); 192405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str3, 1); 193405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str3, 2); 194405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str3, 3); 195405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 196405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str4, 0); 197405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str4, 1); 198405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str4, 2); 199405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str4, 3); 200405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 201405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str5, 0); 202405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str5, 1); 203405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str5, 2); 204405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str5, 3); 205405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 206405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str6, 0); 207405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str6, 1); 208405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str6, 2); 209405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str6, 3); 210405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 211405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str7, 0); 212405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str7, 1); 213405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str7, 2); 214405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str7, 3); 215405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 216405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str8, 0); 217405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str8, 1); 218405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str8, 2); 219405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham P (str8, 3); 220405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 221405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham return errors; 222405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham} 223405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#endif 224