15210d1e6SVineet Gupta/* 25210d1e6SVineet Gupta * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 35210d1e6SVineet Gupta * 45210d1e6SVineet Gupta * This program is free software; you can redistribute it and/or modify 55210d1e6SVineet Gupta * it under the terms of the GNU General Public License version 2 as 65210d1e6SVineet Gupta * published by the Free Software Foundation. 75210d1e6SVineet Gupta */ 85210d1e6SVineet Gupta 95210d1e6SVineet Gupta/* ARC700 has a relatively long pipeline and branch prediction, so we want 105210d1e6SVineet Gupta to avoid branches that are hard to predict. On the other hand, the 115210d1e6SVineet Gupta presence of the norm instruction makes it easier to operate on whole 125210d1e6SVineet Gupta words branch-free. */ 135210d1e6SVineet Gupta 14*ec7ac6afSVineet Gupta#include <linux/linkage.h> 155210d1e6SVineet Gupta 16*ec7ac6afSVineet GuptaENTRY(strchr) 175210d1e6SVineet Gupta extb_s r1,r1 185210d1e6SVineet Gupta asl r5,r1,8 195210d1e6SVineet Gupta bmsk r2,r0,1 205210d1e6SVineet Gupta or r5,r5,r1 215210d1e6SVineet Gupta mov_s r3,0x01010101 225210d1e6SVineet Gupta breq.d r2,r0,.Laligned 235210d1e6SVineet Gupta asl r4,r5,16 245210d1e6SVineet Gupta sub_s r0,r0,r2 255210d1e6SVineet Gupta asl r7,r2,3 265210d1e6SVineet Gupta ld_s r2,[r0] 275210d1e6SVineet Gupta#ifdef __LITTLE_ENDIAN__ 285210d1e6SVineet Gupta asl r7,r3,r7 295210d1e6SVineet Gupta#else 305210d1e6SVineet Gupta lsr r7,r3,r7 315210d1e6SVineet Gupta#endif 325210d1e6SVineet Gupta or r5,r5,r4 335210d1e6SVineet Gupta ror r4,r3 345210d1e6SVineet Gupta sub r12,r2,r7 355210d1e6SVineet Gupta bic_s r12,r12,r2 365210d1e6SVineet Gupta and r12,r12,r4 375210d1e6SVineet Gupta brne.d r12,0,.Lfound0_ua 385210d1e6SVineet Gupta xor r6,r2,r5 395210d1e6SVineet Gupta ld.a r2,[r0,4] 405210d1e6SVineet Gupta sub r12,r6,r7 415210d1e6SVineet Gupta bic r12,r12,r6 42b0f55f2aSJoern Rennecke#ifdef __LITTLE_ENDIAN__ 435210d1e6SVineet Gupta and r7,r12,r4 445210d1e6SVineet Gupta breq r7,0,.Loop ; For speed, we want this branch to be unaligned. 455210d1e6SVineet Gupta b .Lfound_char ; Likewise this one. 46b0f55f2aSJoern Rennecke#else 47b0f55f2aSJoern Rennecke and r12,r12,r4 48b0f55f2aSJoern Rennecke breq r12,0,.Loop ; For speed, we want this branch to be unaligned. 49b0f55f2aSJoern Rennecke lsr_s r12,r12,7 50b0f55f2aSJoern Rennecke bic r2,r7,r6 51b0f55f2aSJoern Rennecke b.d .Lfound_char_b 52b0f55f2aSJoern Rennecke and_s r2,r2,r12 53b0f55f2aSJoern Rennecke#endif 545210d1e6SVineet Gupta; /* We require this code address to be unaligned for speed... */ 555210d1e6SVineet Gupta.Laligned: 565210d1e6SVineet Gupta ld_s r2,[r0] 575210d1e6SVineet Gupta or r5,r5,r4 585210d1e6SVineet Gupta ror r4,r3 595210d1e6SVineet Gupta; /* ... so that this code address is aligned, for itself and ... */ 605210d1e6SVineet Gupta.Loop: 615210d1e6SVineet Gupta sub r12,r2,r3 625210d1e6SVineet Gupta bic_s r12,r12,r2 635210d1e6SVineet Gupta and r12,r12,r4 645210d1e6SVineet Gupta brne.d r12,0,.Lfound0 655210d1e6SVineet Gupta xor r6,r2,r5 665210d1e6SVineet Gupta ld.a r2,[r0,4] 675210d1e6SVineet Gupta sub r12,r6,r3 685210d1e6SVineet Gupta bic r12,r12,r6 695210d1e6SVineet Gupta and r7,r12,r4 705210d1e6SVineet Gupta breq r7,0,.Loop /* ... so that this branch is unaligned. */ 715210d1e6SVineet Gupta ; Found searched-for character. r0 has already advanced to next word. 725210d1e6SVineet Gupta#ifdef __LITTLE_ENDIAN__ 735210d1e6SVineet Gupta/* We only need the information about the first matching byte 745210d1e6SVineet Gupta (i.e. the least significant matching byte) to be exact, 755210d1e6SVineet Gupta hence there is no problem with carry effects. */ 765210d1e6SVineet Gupta.Lfound_char: 775210d1e6SVineet Gupta sub r3,r7,1 785210d1e6SVineet Gupta bic r3,r3,r7 795210d1e6SVineet Gupta norm r2,r3 805210d1e6SVineet Gupta sub_s r0,r0,1 815210d1e6SVineet Gupta asr_s r2,r2,3 825210d1e6SVineet Gupta j.d [blink] 835210d1e6SVineet Gupta sub_s r0,r0,r2 845210d1e6SVineet Gupta 855210d1e6SVineet Gupta .balign 4 865210d1e6SVineet Gupta.Lfound0_ua: 875210d1e6SVineet Gupta mov r3,r7 885210d1e6SVineet Gupta.Lfound0: 895210d1e6SVineet Gupta sub r3,r6,r3 905210d1e6SVineet Gupta bic r3,r3,r6 915210d1e6SVineet Gupta and r2,r3,r4 925210d1e6SVineet Gupta or_s r12,r12,r2 935210d1e6SVineet Gupta sub_s r3,r12,1 945210d1e6SVineet Gupta bic_s r3,r3,r12 955210d1e6SVineet Gupta norm r3,r3 965210d1e6SVineet Gupta add_s r0,r0,3 975210d1e6SVineet Gupta asr_s r12,r3,3 985210d1e6SVineet Gupta asl.f 0,r2,r3 995210d1e6SVineet Gupta sub_s r0,r0,r12 1005210d1e6SVineet Gupta j_s.d [blink] 1015210d1e6SVineet Gupta mov.pl r0,0 1025210d1e6SVineet Gupta#else /* BIG ENDIAN */ 1035210d1e6SVineet Gupta.Lfound_char: 1045210d1e6SVineet Gupta lsr r7,r7,7 1055210d1e6SVineet Gupta 1065210d1e6SVineet Gupta bic r2,r7,r6 107b0f55f2aSJoern Rennecke.Lfound_char_b: 1085210d1e6SVineet Gupta norm r2,r2 1095210d1e6SVineet Gupta sub_s r0,r0,4 1105210d1e6SVineet Gupta asr_s r2,r2,3 1115210d1e6SVineet Gupta j.d [blink] 1125210d1e6SVineet Gupta add_s r0,r0,r2 1135210d1e6SVineet Gupta 1145210d1e6SVineet Gupta.Lfound0_ua: 1155210d1e6SVineet Gupta mov_s r3,r7 1165210d1e6SVineet Gupta.Lfound0: 1175210d1e6SVineet Gupta asl_s r2,r2,7 1185210d1e6SVineet Gupta or r7,r6,r4 1195210d1e6SVineet Gupta bic_s r12,r12,r2 1205210d1e6SVineet Gupta sub r2,r7,r3 1215210d1e6SVineet Gupta or r2,r2,r6 1225210d1e6SVineet Gupta bic r12,r2,r12 1235210d1e6SVineet Gupta bic.f r3,r4,r12 1245210d1e6SVineet Gupta norm r3,r3 1255210d1e6SVineet Gupta 1265210d1e6SVineet Gupta add.pl r3,r3,1 1275210d1e6SVineet Gupta asr_s r12,r3,3 1285210d1e6SVineet Gupta asl.f 0,r2,r3 1295210d1e6SVineet Gupta add_s r0,r0,r12 1305210d1e6SVineet Gupta j_s.d [blink] 1315210d1e6SVineet Gupta mov.mi r0,0 1325210d1e6SVineet Gupta#endif /* ENDIAN */ 133*ec7ac6afSVineet GuptaEND(strchr) 134