1/* strchr (str, ch) -- Return pointer to first occurrence of CH in STR. 2 For SPARC v9. 3 Copyright (C) 1998-2022 Free Software Foundation, Inc. 4 This file is part of the GNU C Library. 5 6 The GNU C Library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License as published by the Free Software Foundation; either 9 version 2.1 of the License, or (at your option) any later version. 10 11 The GNU C Library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with the GNU C Library; if not, see 18 <https://www.gnu.org/licenses/>. */ 19 20#include <sysdep.h> 21#include <asm/asi.h> 22#ifndef XCC 23#define XCC xcc 24#define USE_BPR 25 .register %g2, #scratch 26 .register %g3, #scratch 27 .register %g6, #scratch 28#endif 29 30 /* Normally, this uses 31 ((xword - 0x0101010101010101) & 0x8080808080808080) test 32 to find out if any byte in xword could be zero. This is fast, but 33 also gives false alarm for any byte in range 0x81-0xff. It does 34 not matter for correctness, as if this test tells us there could 35 be some zero byte, we check it byte by byte, but if bytes with 36 high bits set are common in the strings, then this will give poor 37 performance. You can #define EIGHTBIT_NOT_RARE and the algorithm 38 will use one tick slower, but more precise test 39 ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080), 40 which does not give any false alarms (but if some bits are set, 41 one cannot assume from it which bytes are zero and which are not). 42 It is yet to be measured, what is the correct default for glibc 43 in these days for an average user. 44 */ 45 46 .text 47 .align 32 48ENTRY(strchr) 49 andcc %o1, 0xff, %o1 /* IEU1 Group */ 50 be,pn %icc, 17f /* CTI */ 51 sllx %o1, 8, %g3 /* IEU0 Group */ 52 sethi %hi(0x01010101), %g1 /* IEU1 */ 53 54 or %g3, %o1, %g3 /* IEU0 Group */ 55 ldub [%o0], %o3 /* Load */ 56 sllx %g3, 16, %g5 /* IEU0 Group */ 57 or %g1, %lo(0x01010101), %g1 /* IEU1 */ 58 59 sllx %g1, 32, %g2 /* IEU0 Group */ 60 brz,pn %o3, 5f /* CTI+IEU1 */ 61 orcc %g3, %g5, %g3 /* IEU1 Group */ 62 sllx %g3, 32, %g5 /* IEU0 */ 63 64 cmp %o3, %o1 /* IEU1 Group */ 65 be,pn %xcc, 14f /* CTI */ 66 or %g1, %g2, %g1 /* IEU0 */ 67 andcc %o0, 7, %g0 /* IEU1 Group */ 68 69 bne,a,pn %icc, 15f /* CTI */ 70 add %o0, 1, %o0 /* IEU0 */ 71 ldx [%o0], %o3 /* Load Group */ 721: sllx %g1, 7, %g2 /* IEU0 */ 73 74 or %g3, %g5, %g3 /* IEU1 */ 75 add %o0, 8, %o0 /* IEU0 Group */ 76 xor %o3, %g3, %o4 /* IEU1 */ 77 /* %g1 = 0101010101010101 * 78 * %g2 = 8080088080808080 * 79 * %g3 = c c c c c c c c * 80 * %o3 = value * 81 * %o4 = value XOR c */ 822: sub %o3, %g1, %o2 /* IEU0 Group */ 83 84 sub %o4, %g1, %o5 /* IEU1 */ 85#ifdef EIGHTBIT_NOT_RARE 86 andn %o2, %o3, %g6 /* IEU0 Group */ 87 andn %o5, %o4, %o5 /* IEU1 */ 88 ldxa [%o0] ASI_PNF, %o3 /* Load */ 89 or %o5, %g6, %o5 /* IEU0 Group */ 90#else 91 ldxa [%o0] ASI_PNF, %o3 /* Load */ 92 or %o5, %o2, %o5 /* IEU0 Group */ 93#endif 94 add %o0, 8, %o0 /* IEU1 */ 95 96 andcc %o5, %g2, %g0 /* IEU1 Group */ 97 be,a,pt %xcc, 2b /* CTI */ 98 xor %o3, %g3, %o4 /* IEU0 */ 99 srlx %o5, 32, %g5 /* IEU0 Group */ 100 101 add %o2, %g1, %o2 /* IEU1 */ 1023: andcc %g5, %g2, %g0 /* IEU1 Group */ 103 be,pn %xcc, 4f /* CTI */ 104 srlx %o2, 56, %g5 /* IEU0 */ 105 106 andcc %g5, 0xff, %g0 /* IEU1 Group */ 107 be,pn %icc, 5f /* CTI */ 108 srlx %o4, 56, %g5 /* IEU0 */ 109 andcc %g5, 0xff, %g0 /* IEU1 Group */ 110 111 be,pn %icc, 6f /* CTI */ 112 srlx %o2, 48, %g5 /* IEU0 */ 113 andcc %g5, 0xff, %g0 /* IEU1 Group */ 114 be,pn %icc, 5f /* CTI */ 115 116 srlx %o4, 48, %g5 /* IEU0 */ 117 andcc %g5, 0xff, %g0 /* IEU1 Group */ 118 be,pn %icc, 7f /* CTI */ 119 srlx %o2, 40, %g5 /* IEU0 */ 120 121 andcc %g5, 0xff, %g0 /* IEU1 Group */ 122 be,pn %icc, 5f /* CTI */ 123 srlx %o4, 40, %g5 /* IEU0 */ 124 andcc %g5, 0xff, %g0 /* IEU1 Group */ 125 126 be,pn %icc, 8f /* CTI */ 127 srlx %o2, 32, %g5 /* IEU0 */ 128 andcc %g5, 0xff, %g0 /* IEU1 Group */ 129 be,pn %icc, 5f /* CTI */ 130 131 srlx %o4, 32, %g5 /* IEU0 */ 132 andcc %g5, 0xff, %g0 /* IEU1 Group */ 133 be,pn %icc, 9f /* CTI */ 1344: srlx %o2, 24, %g5 /* IEU0 */ 135 136 andcc %g5, 0xff, %g0 /* IEU1 Group */ 137 be,pn %icc, 5f /* CTI */ 138 srlx %o4, 24, %g5 /* IEU0 */ 139 andcc %g5, 0xff, %g0 /* IEU1 Group */ 140 141 be,pn %icc, 10f /* CTI */ 142 srlx %o2, 16, %g5 /* IEU0 */ 143 andcc %g5, 0xff, %g0 /* IEU1 Group */ 144 be,pn %icc, 5f /* CTI */ 145 146 srlx %o4, 16, %g5 /* IEU0 */ 147 andcc %g5, 0xff, %g0 /* IEU1 Group */ 148 be,pn %icc, 11f /* CTI */ 149 srlx %o2, 8, %g5 /* IEU0 */ 150 151 andcc %g5, 0xff, %g0 /* IEU1 Group */ 152 be,pn %icc, 5f /* CTI */ 153 srlx %o4, 8, %g5 /* IEU0 */ 154 andcc %g5, 0xff, %g0 /* IEU1 Group */ 155 156 be,pn %icc, 12f /* CTI */ 157 andcc %o2, 0xff, %g0 /* IEU1 Group */ 158 be,pn %icc, 5f /* CTI */ 159 sub %o3, %g1, %o2 /* IEU0 */ 160 161 andcc %o4, 0xff, %g0 /* IEU1 Group */ 162 be,pn %icc, 13f /* CTI */ 163 xor %o3, %g3, %o4 /* IEU0 */ 164 ldxa [%o0] ASI_PNF, %o3 /* Load Group */ 165 166 sub %o4, %g1, %o5 /* IEU0 */ 167 or %o5, %o2, %o5 /* IEU1 */ 168 add %o0, 8, %o0 /* IEU0 Group */ 169 andcc %o5, %g2, %g0 /* IEU1 */ 170 171 be,a,pt %xcc, 2b /* CTI */ 172 xor %o3, %g3, %o4 /* IEU0 Group */ 173 srlx %o5, 32, %g5 /* IEU0 Group */ 174 ba,pt %xcc, 3b /* CTI */ 175 176 add %o2, %g1, %o2 /* IEU1 */ 177 178 .align 16 1795: retl /* CTI+IEU1 Group */ 180 clr %o0 /* IEU0 */ 1816: retl /* CTI+IEU1 Group */ 182 add %o0, -16, %o0 /* IEU0 */ 183 1847: retl /* CTI+IEU1 Group */ 185 add %o0, -15, %o0 /* IEU0 */ 1868: retl /* CTI+IEU1 Group */ 187 add %o0, -14, %o0 /* IEU0 */ 188 1899: retl /* CTI+IEU1 Group */ 190 add %o0, -13, %o0 /* IEU0 */ 19110: retl /* CTI+IEU1 Group */ 192 add %o0, -12, %o0 /* IEU0 */ 193 19411: retl /* CTI+IEU1 Group */ 195 add %o0, -11, %o0 /* IEU0 */ 19612: retl /* CTI+IEU1 Group */ 197 add %o0, -10, %o0 /* IEU0 */ 198 19913: retl /* CTI+IEU1 Group */ 200 add %o0, -9, %o0 /* IEU0 */ 20114: retl /* CTI+IEU1 Group */ 202 nop /* IEU0 */ 203 204 .align 16 20515: ldub [%o0], %o3 /* Load Group */ 20616: andcc %o0, 7, %g0 /* IEU1 */ 207 be,a,pn %icc, 1b /* CTI */ 208 ldx [%o0], %o3 /* Load Group */ 209 210 andcc %o3, 0xff, %g0 /* IEU1 Group */ 211 be,pn %icc, 5b /* CTI */ 212 add %o0, 1, %o0 /* IEU0 */ 213 cmp %o3, %o1 /* IEU1 Group */ 214 215 bne,a,pn %icc, 16b /* CTI */ 216 ldub [%o0], %o3 /* Load */ 217 retl /* CTI+IEU1 Group */ 218 add %o0, -1, %o0 /* IEU0 */ 219 220 /* strchr (str, 0) */ 221 .align 32 222 nop 223 .align 16 22417: sethi %hi(0x01010101), %g1 /* IEU0 Group */ 225 ldub [%o0], %o3 /* Load */ 226 or %g1, %lo(0x01010101), %g1 /* IEU0 Group */ 227 sllx %g1, 32, %g2 /* IEU0 Group */ 228 229 andcc %o0, 7, %g0 /* IEU1 */ 230 or %g1, %g2, %g1 /* IEU0 Group */ 231 bne,pn %icc, 32f /* CTI */ 232 sllx %g1, 7, %g2 /* IEU0 Group */ 233 234 brz,pn %o3, 30f /* CTI+IEU1 */ 235 ldx [%o0], %o3 /* Load */ 23618: add %o0, 8, %o0 /* IEU0 Group */ 23719: sub %o3, %g1, %o2 /* IEU0 Group */ 238 239#ifdef EIGHTBIT_NOT_RARE 240 andn %o2, %o3, %g6 /* IEU0 Group */ 241 ldxa [%o0] ASI_PNF, %o3 /* Load */ 242 andcc %g6, %g2, %g0 /* IEU1 Group */ 243#else 244 ldxa [%o0] ASI_PNF, %o3 /* Load */ 245 andcc %o2, %g2, %g0 /* IEU1 Group */ 246#endif 247 be,pt %xcc, 19b /* CTI */ 248 add %o0, 8, %o0 /* IEU0 */ 249 250 addcc %o2, %g1, %g3 /* IEU1 Group */ 251 srlx %o2, 32, %o2 /* IEU0 */ 25220: andcc %o2, %g2, %g0 /* IEU1 Group */ 253 be,pn %xcc, 21f /* CTI */ 254 255 srlx %g3, 56, %o2 /* IEU0 */ 256 andcc %o2, 0xff, %g0 /* IEU1 Group */ 257 be,pn %icc, 29f /* CTI */ 258 srlx %g3, 48, %o2 /* IEU0 */ 259 260 andcc %o2, 0xff, %g0 /* IEU1 Group */ 261 be,pn %icc, 28f /* CTI */ 262 srlx %g3, 40, %o2 /* IEU0 */ 263 andcc %o2, 0xff, %g0 /* IEU1 Group */ 264 265 be,pn %icc, 27f /* CTI */ 266 srlx %g3, 32, %o2 /* IEU0 */ 267 andcc %o2, 0xff, %g0 /* IEU1 Group */ 268 be,pn %icc, 26f /* CTI */ 269 27021: srlx %g3, 24, %o2 /* IEU0 */ 271 andcc %o2, 0xff, %g0 /* IEU1 Group */ 272 be,pn %icc, 25f /* CTI */ 273 srlx %g3, 16, %o2 /* IEU0 */ 274 275 andcc %o2, 0xff, %g0 /* IEU1 Group */ 276 be,pn %icc, 24f /* CTI */ 277 srlx %g3, 8, %o2 /* IEU0 */ 278 andcc %o2, 0xff, %g0 /* IEU1 Group */ 279 280 be,pn %icc, 23f /* CTI */ 281 sub %o3, %g1, %o2 /* IEU0 */ 282 andcc %g3, 0xff, %g0 /* IEU1 Group */ 283 be,pn %icc, 22f /* CTI */ 284 285 ldxa [%o0] ASI_PNF, %o3 /* Load */ 286 andcc %o2, %g2, %g0 /* IEU1 Group */ 287 be,pt %xcc, 19b /* CTI */ 288 add %o0, 8, %o0 /* IEU0 */ 289 290 addcc %o2, %g1, %g3 /* IEU1 Group */ 291 ba,pt %xcc, 20b /* CTI */ 292 srlx %o2, 32, %o2 /* IEU0 */ 293 294 .align 16 29522: retl /* CTI+IEU1 Group */ 296 add %o0, -9, %o0 /* IEU0 */ 29723: retl /* CTI+IEU1 Group */ 298 add %o0, -10, %o0 /* IEU0 */ 299 30024: retl /* CTI+IEU1 Group */ 301 add %o0, -11, %o0 /* IEU0 */ 30225: retl /* CTI+IEU1 Group */ 303 add %o0, -12, %o0 /* IEU0 */ 304 30526: retl /* CTI+IEU1 Group */ 306 add %o0, -13, %o0 /* IEU0 */ 30727: retl /* CTI+IEU1 Group */ 308 add %o0, -14, %o0 /* IEU0 */ 309 31028: retl /* CTI+IEU1 Group */ 311 add %o0, -15, %o0 /* IEU0 */ 31229: retl /* CTI+IEU1 Group */ 313 add %o0, -16, %o0 /* IEU0 */ 314 31530: retl /* CTI+IEU1 Group */ 316 nop /* IEU0 */ 317 318 .align 16 31932: andcc %o0, 7, %g0 /* IEU1 Group */ 320 be,a,pn %icc, 18b /* CTI */ 321 ldx [%o0], %o3 /* Load */ 322 add %o0, 1, %o0 /* IEU0 Group */ 323 324 brnz,a,pt %o3, 32b /* CTI+IEU1 */ 325 lduba [%o0] ASI_PNF, %o3 /* Load */ 326 retl /* CTI+IEU1 Group */ 327 add %o0, -1, %o0 /* IEU0 */ 328END(strchr) 329 330 .align 32 331ENTRY(strrchr) 332 andcc %o1, 0xff, %o1 /* IEU1 Group */ 333 be,pn %icc, 17b /* CTI */ 334 clr %g4 /* IEU0 */ 335 andcc %o0, 7, %g0 /* IEU1 Group */ 336 337 bne,pn %icc, 13f /* CTI */ 338 sllx %o1, 8, %g3 /* IEU0 */ 339 ldx [%o0], %o3 /* Load Group */ 3401: sethi %hi(0x01010101), %g1 /* IEU0 */ 341 342 or %g3, %o1, %g3 /* IEU1 */ 343 sllx %g3, 16, %g5 /* IEU0 Group */ 344 or %g1, %lo(0x01010101), %g1 /* IEU1 */ 345 sllx %g1, 32, %g2 /* IEU0 Group */ 346 347 or %g3, %g5, %g3 /* IEU1 */ 348 sllx %g3, 32, %g5 /* IEU0 Group */ 349 or %g1, %g2, %g1 /* IEU1 */ 350 sllx %g1, 7, %g2 /* IEU0 Group */ 351 352 or %g3, %g5, %g3 /* IEU1 */ 353 add %o0, 8, %o0 /* IEU0 Group */ 354 xor %o3, %g3, %o4 /* IEU1 */ 355 /* %g1 = 0101010101010101 * 356 * %g2 = 8080088080808080 * 357 * %g3 = c c c c c c c c * 358 * %o3 = value * 359 * %o4 = value XOR c */ 3602: sub %o3, %g1, %o2 /* IEU0 Group */ 361 3623: sub %o4, %g1, %o5 /* IEU1 */ 363#ifdef EIGHTBIT_NOT_RARE 364 andn %o2, %o3, %g6 /* IEU0 Group */ 365 andn %o5, %o4, %o5 /* IEU1 */ 366 ldxa [%o0] ASI_PNF, %o3 /* Load */ 367 368 or %o5, %g6, %o5 /* IEU0 Group */ 369#else 370 ldxa [%o0] ASI_PNF, %o3 /* Load */ 371 372 or %o5, %o2, %o5 /* IEU0 Group */ 373#endif 374 add %o0, 8, %o0 /* IEU1 */ 375 andcc %o5, %g2, %g0 /* IEU1 Group */ 376 be,a,pt %xcc, 2b /* CTI */ 377 378 xor %o3, %g3, %o4 /* IEU0 */ 379 srlx %o5, 32, %g5 /* IEU0 Group */ 380 add %o2, %g1, %o2 /* IEU1 */ 381 andcc %g5, %g2, %g0 /* IEU1 Group */ 382 383 be,pn %xcc, 7f /* CTI */ 384 srlx %o2, 56, %g5 /* IEU0 */ 385 andcc %g5, 0xff, %g0 /* IEU1 Group */ 386 be,pn %icc, 12f /* CTI */ 387 388 srlx %o4, 56, %g5 /* IEU0 */ 389 andcc %g5, 0xff, %g0 /* IEU1 Group */ 390 srlx %o2, 48, %g5 /* IEU0 */ 391 be,a,pn %icc, 4f /* CTI */ 392 393 add %o0, -16, %g4 /* IEU0 Group */ 3944: andcc %g5, 0xff, %g0 /* IEU1 Group */ 395 be,pn %icc, 12f /* CTI */ 396 srlx %o4, 48, %g5 /* IEU0 */ 397 398 andcc %g5, 0xff, %g0 /* IEU1 Group */ 399 srlx %o2, 40, %g5 /* IEU0 */ 400 be,a,pn %icc, 5f /* CTI */ 401 add %o0, -15, %g4 /* IEU0 Group */ 402 4035: andcc %g5, 0xff, %g0 /* IEU1 Group */ 404 be,pn %icc, 12f /* CTI */ 405 srlx %o4, 40, %g5 /* IEU0 */ 406 andcc %g5, 0xff, %g0 /* IEU1 Group */ 407 408 srlx %o2, 32, %g5 /* IEU0 */ 409 be,a,pn %icc, 6f /* CTI */ 410 add %o0, -14, %g4 /* IEU0 Group */ 4116: andcc %g5, 0xff, %g0 /* IEU1 Group */ 412 413 be,pn %icc, 12f /* CTI */ 414 srlx %o4, 32, %g5 /* IEU0 */ 415 andcc %g5, 0xff, %g0 /* IEU1 Group */ 416 be,a,pn %icc, 7f /* CTI */ 417 418 add %o0, -13, %g4 /* IEU0 */ 4197: srlx %o2, 24, %g5 /* IEU0 */ 420 andcc %g5, 0xff, %g0 /* IEU1 Group */ 421 be,pn %icc, 12f /* CTI */ 422 423 srlx %o4, 24, %g5 /* IEU0 */ 424 andcc %g5, 0xff, %g0 /* IEU1 Group */ 425 srlx %o2, 16, %g5 /* IEU0 */ 426 be,a,pn %icc, 8f /* CTI */ 427 428 add %o0, -12, %g4 /* IEU0 Group */ 4298: andcc %g5, 0xff, %g0 /* IEU1 Group */ 430 be,pn %icc, 12f /* CTI */ 431 srlx %o4, 16, %g5 /* IEU0 */ 432 433 andcc %g5, 0xff, %g0 /* IEU1 Group */ 434 srlx %o2, 8, %g5 /* IEU0 */ 435 be,a,pn %icc, 9f /* CTI */ 436 add %o0, -11, %g4 /* IEU0 Group */ 437 4389: andcc %g5, 0xff, %g0 /* IEU1 Group */ 439 be,pn %icc, 12f /* CTI */ 440 srlx %o4, 8, %g5 /* IEU0 */ 441 andcc %g5, 0xff, %g0 /* IEU1 Group */ 442 443 be,a,pn %icc, 10f /* CTI */ 444 add %o0, -10, %g4 /* IEU0 */ 44510: andcc %o2, 0xff, %g0 /* IEU1 Group */ 446 be,pn %icc, 12f /* CTI */ 447 448 sub %o3, %g1, %o2 /* IEU0 */ 449 andcc %o4, 0xff, %g0 /* IEU1 Group */ 450 be,a,pn %icc, 11f /* CTI */ 451 add %o0, -9, %g4 /* IEU0 */ 452 45311: ba,pt %xcc, 3b /* CTI Group */ 454 xor %o3, %g3, %o4 /* IEU0 Group */ 45512: retl /* CTI+IEU1 Group */ 456 mov %g4, %o0 /* IEU0 */ 457 458 .align 16 45913: ldub [%o0], %o3 /* Load Group */ 460 add %o0, 1, %o0 /* IEU0 */ 46114: andcc %o3, 0xff, %g0 /* IEU1 Group */ 462 be,pn %icc, 12b /* CTI */ 463 464 cmp %o3, %o1 /* IEU1 Group */ 465 ldub [%o0], %o3 /* Load */ 466 be,a,pn %icc, 15f /* CTI */ 467 add %o0, -1, %g4 /* IEU0 Group */ 468 46915: andcc %o0, 7, %g0 /* IEU1 Group */ 470 bne,a,pt %icc, 14b /* CTI */ 471 add %o0, 1, %o0 /* IEU0 */ 472 ba,pt %xcc, 1b /* CTI Group */ 473 474 ldx [%o0], %o3 /* Load */ 475END(strrchr) 476 477weak_alias (strchr, index) 478weak_alias (strrchr, rindex) 479libc_hidden_builtin_def (strchr) 480libc_hidden_builtin_def (strrchr) 481