1/* 2 * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7/* 8 * ARC700 has a relatively long pipeline and branch prediction, so we want 9 * to avoid branches that are hard to predict. On the other hand, the 10 * presence of the norm instruction makes it easier to operate on whole 11 * words branch-free. 12 */ 13 14.global strchr 15.align 4 16strchr: 17 extb_s %r1, %r1 18 asl %r5, %r1, 8 19 bmsk %r2, %r0, 1 20 or %r5, %r5, %r1 21 mov_s %r3, 0x01010101 22 breq.d %r2, %r0, .Laligned 23 asl %r4, %r5, 16 24 sub_s %r0, %r0, %r2 25 asl %r7, %r2, 3 26 ld_s %r2, [%r0] 27#ifdef __LITTLE_ENDIAN__ 28 asl %r7, %r3, %r7 29#else /* __BIG_ENDIAN__ */ 30 lsr %r7, %r3, %r7 31#endif /* _ENDIAN__ */ 32 or %r5, %r5, %r4 33 ror %r4, %r3 34 sub %r12, %r2, %r7 35 bic_s %r12, %r12, %r2 36 and %r12, %r12, %r4 37 brne.d %r12, 0, .Lfound0_ua 38 xor %r6, %r2, %r5 39 ld.a %r2, [%r0, 4] 40 sub %r12, %r6, %r7 41 bic %r12, %r12, %r6 42#ifdef __LITTLE_ENDIAN__ 43 and %r7, %r12, %r4 44 /* For speed, we want this branch to be unaligned. */ 45 breq %r7, 0, .Loop 46 /* Likewise this one */ 47 b .Lfound_char 48#else /* __BIG_ENDIAN__ */ 49 and %r12, %r12, %r4 50 /* For speed, we want this branch to be unaligned. */ 51 breq %r12, 0, .Loop 52 lsr_s %r12, %r12, 7 53 bic %r2, %r7, %r6 54 b.d .Lfound_char_b 55 and_s %r2, %r2, %r12 56#endif /* _ENDIAN__ */ 57 /* We require this code address to be unaligned for speed... */ 58.Laligned: 59 ld_s %r2, [%r0] 60 or %r5, %r5, %r4 61 ror %r4, %r3 62 /* ... so that this code address is aligned, for itself and ... */ 63.Loop: 64 sub %r12, %r2, %r3 65 bic_s %r12, %r12, %r2 66 and %r12, %r12, %r4 67 brne.d %r12, 0, .Lfound0 68 xor %r6, %r2, %r5 69 ld.a %r2, [%r0, 4] 70 sub %r12, %r6, %r3 71 bic %r12, %r12, %r6 72 and %r7, %r12, %r4 73 breq %r7, 0, .Loop 74 /* 75 *... so that this branch is unaligned. 76 * Found searched-for character. 77 * r0 has already advanced to next word. 78 */ 79#ifdef __LITTLE_ENDIAN__ 80 /* 81 * We only need the information about the first matching byte 82 * (i.e. the least significant matching byte) to be exact, 83 * hence there is no problem with carry effects. 84 */ 85.Lfound_char: 86 sub %r3, %r7, 1 87 bic %r3, %r3, %r7 88 norm %r2, %r3 89 sub_s %r0, %r0, 1 90 asr_s %r2, %r2, 3 91 j.d [%blink] 92 sub_s %r0, %r0, %r2 93 94 .balign 4 95.Lfound0_ua: 96 mov %r3, %r7 97.Lfound0: 98 sub %r3, %r6, %r3 99 bic %r3, %r3, %r6 100 and %r2, %r3, %r4 101 or_s %r12, %r12, %r2 102 sub_s %r3, %r12, 1 103 bic_s %r3, %r3, %r12 104 norm %r3, %r3 105 add_s %r0, %r0, 3 106 asr_s %r12, %r3, 3 107 asl.f 0, %r2, %r3 108 sub_s %r0, %r0, %r12 109 j_s.d [%blink] 110 mov.pl %r0, 0 111#else /* __BIG_ENDIAN__ */ 112.Lfound_char: 113 lsr %r7, %r7, 7 114 115 bic %r2, %r7, %r6 116.Lfound_char_b: 117 norm %r2, %r2 118 sub_s %r0, %r0, 4 119 asr_s %r2, %r2, 3 120 j.d [%blink] 121 add_s %r0, %r0, %r2 122 123.Lfound0_ua: 124 mov_s %r3, %r7 125.Lfound0: 126 asl_s %r2, %r2, 7 127 or %r7, %r6, %r4 128 bic_s %r12, %r12, %r2 129 sub %r2, %r7, %r3 130 or %r2, %r2, %r6 131 bic %r12, %r2, %r12 132 bic.f %r3, %r4, %r12 133 norm %r3, %r3 134 135 add.pl %r3, %r3, 1 136 asr_s %r12, %r3, 3 137 asl.f 0, %r2, %r3 138 add_s %r0, %r0, %r12 139 j_s.d [%blink] 140 mov.mi %r0, 0 141#endif /* _ENDIAN__ */ 142