1*d2912cb1SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */ 25210d1e6SVineet Gupta/* 35210d1e6SVineet Gupta * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 45210d1e6SVineet Gupta */ 55210d1e6SVineet Gupta 6ec7ac6afSVineet Gupta#include <linux/linkage.h> 75210d1e6SVineet Gupta 85210d1e6SVineet Gupta#ifdef __LITTLE_ENDIAN__ 95210d1e6SVineet Gupta#define WORD2 r2 105210d1e6SVineet Gupta#define SHIFT r3 115210d1e6SVineet Gupta#else /* BIG ENDIAN */ 125210d1e6SVineet Gupta#define WORD2 r3 135210d1e6SVineet Gupta#define SHIFT r2 145210d1e6SVineet Gupta#endif 155210d1e6SVineet Gupta 1686effd0dSVineet GuptaENTRY_CFI(memcmp) 175210d1e6SVineet Gupta or r12,r0,r1 185210d1e6SVineet Gupta asl_s r12,r12,30 195210d1e6SVineet Gupta sub r3,r2,1 205210d1e6SVineet Gupta brls r2,r12,.Lbytewise 215210d1e6SVineet Gupta ld r4,[r0,0] 225210d1e6SVineet Gupta ld r5,[r1,0] 235210d1e6SVineet Gupta lsr.f lp_count,r3,3 248922bc30SVineet Gupta#ifdef CONFIG_ISA_ARCV2 258922bc30SVineet Gupta /* In ARCv2 a branch can't be the last instruction in a zero overhead 268922bc30SVineet Gupta * loop. 278922bc30SVineet Gupta * So we move the branch to the start of the loop, duplicate it 288922bc30SVineet Gupta * after the end, and set up r12 so that the branch isn't taken 298922bc30SVineet Gupta * initially. 308922bc30SVineet Gupta */ 318922bc30SVineet Gupta mov_s r12,WORD2 328922bc30SVineet Gupta lpne .Loop_end 338922bc30SVineet Gupta brne WORD2,r12,.Lodd 348922bc30SVineet Gupta ld WORD2,[r0,4] 358922bc30SVineet Gupta#else 365210d1e6SVineet Gupta lpne .Loop_end 375210d1e6SVineet Gupta ld_s WORD2,[r0,4] 388922bc30SVineet Gupta#endif 395210d1e6SVineet Gupta ld_s r12,[r1,4] 405210d1e6SVineet Gupta brne r4,r5,.Leven 415210d1e6SVineet Gupta ld.a r4,[r0,8] 425210d1e6SVineet Gupta ld.a r5,[r1,8] 438922bc30SVineet Gupta#ifdef CONFIG_ISA_ARCV2 448922bc30SVineet Gupta.Loop_end: 458922bc30SVineet Gupta brne WORD2,r12,.Lodd 468922bc30SVineet Gupta#else 475210d1e6SVineet Gupta brne WORD2,r12,.Lodd 485210d1e6SVineet Gupta.Loop_end: 498922bc30SVineet Gupta#endif 505210d1e6SVineet Gupta asl_s SHIFT,SHIFT,3 515210d1e6SVineet Gupta bhs_s .Last_cmp 525210d1e6SVineet Gupta brne r4,r5,.Leven 535210d1e6SVineet Gupta ld r4,[r0,4] 545210d1e6SVineet Gupta ld r5,[r1,4] 555210d1e6SVineet Gupta#ifdef __LITTLE_ENDIAN__ 565210d1e6SVineet Gupta nop_s 575210d1e6SVineet Gupta ; one more load latency cycle 585210d1e6SVineet Gupta.Last_cmp: 595210d1e6SVineet Gupta xor r0,r4,r5 605210d1e6SVineet Gupta bset r0,r0,SHIFT 615210d1e6SVineet Gupta sub_s r1,r0,1 625210d1e6SVineet Gupta bic_s r1,r1,r0 635210d1e6SVineet Gupta norm r1,r1 645210d1e6SVineet Gupta b.d .Leven_cmp 655210d1e6SVineet Gupta and r1,r1,24 665210d1e6SVineet Gupta.Leven: 675210d1e6SVineet Gupta xor r0,r4,r5 685210d1e6SVineet Gupta sub_s r1,r0,1 695210d1e6SVineet Gupta bic_s r1,r1,r0 705210d1e6SVineet Gupta norm r1,r1 715210d1e6SVineet Gupta ; slow track insn 725210d1e6SVineet Gupta and r1,r1,24 735210d1e6SVineet Gupta.Leven_cmp: 745210d1e6SVineet Gupta asl r2,r4,r1 755210d1e6SVineet Gupta asl r12,r5,r1 765210d1e6SVineet Gupta lsr_s r2,r2,1 775210d1e6SVineet Gupta lsr_s r12,r12,1 785210d1e6SVineet Gupta j_s.d [blink] 795210d1e6SVineet Gupta sub r0,r2,r12 805210d1e6SVineet Gupta .balign 4 815210d1e6SVineet Gupta.Lodd: 825210d1e6SVineet Gupta xor r0,WORD2,r12 835210d1e6SVineet Gupta sub_s r1,r0,1 845210d1e6SVineet Gupta bic_s r1,r1,r0 855210d1e6SVineet Gupta norm r1,r1 865210d1e6SVineet Gupta ; slow track insn 875210d1e6SVineet Gupta and r1,r1,24 885210d1e6SVineet Gupta asl_s r2,r2,r1 895210d1e6SVineet Gupta asl_s r12,r12,r1 905210d1e6SVineet Gupta lsr_s r2,r2,1 915210d1e6SVineet Gupta lsr_s r12,r12,1 925210d1e6SVineet Gupta j_s.d [blink] 935210d1e6SVineet Gupta sub r0,r2,r12 945210d1e6SVineet Gupta#else /* BIG ENDIAN */ 955210d1e6SVineet Gupta.Last_cmp: 965210d1e6SVineet Gupta neg_s SHIFT,SHIFT 975210d1e6SVineet Gupta lsr r4,r4,SHIFT 985210d1e6SVineet Gupta lsr r5,r5,SHIFT 995210d1e6SVineet Gupta ; slow track insn 1005210d1e6SVineet Gupta.Leven: 1015210d1e6SVineet Gupta sub.f r0,r4,r5 1025210d1e6SVineet Gupta mov.ne r0,1 1035210d1e6SVineet Gupta j_s.d [blink] 1045210d1e6SVineet Gupta bset.cs r0,r0,31 1055210d1e6SVineet Gupta.Lodd: 1065210d1e6SVineet Gupta cmp_s WORD2,r12 1075210d1e6SVineet Gupta mov_s r0,1 1085210d1e6SVineet Gupta j_s.d [blink] 1095210d1e6SVineet Gupta bset.cs r0,r0,31 1105210d1e6SVineet Gupta#endif /* ENDIAN */ 1115210d1e6SVineet Gupta .balign 4 1125210d1e6SVineet Gupta.Lbytewise: 1135210d1e6SVineet Gupta breq r2,0,.Lnil 1145210d1e6SVineet Gupta ldb r4,[r0,0] 1155210d1e6SVineet Gupta ldb r5,[r1,0] 1165210d1e6SVineet Gupta lsr.f lp_count,r3 1178922bc30SVineet Gupta#ifdef CONFIG_ISA_ARCV2 1188922bc30SVineet Gupta mov r12,r3 1195210d1e6SVineet Gupta lpne .Lbyte_end 1208922bc30SVineet Gupta brne r3,r12,.Lbyte_odd 1218922bc30SVineet Gupta#else 1228922bc30SVineet Gupta lpne .Lbyte_end 1238922bc30SVineet Gupta#endif 1245210d1e6SVineet Gupta ldb_s r3,[r0,1] 1255210d1e6SVineet Gupta ldb r12,[r1,1] 1265210d1e6SVineet Gupta brne r4,r5,.Lbyte_even 1275210d1e6SVineet Gupta ldb.a r4,[r0,2] 1285210d1e6SVineet Gupta ldb.a r5,[r1,2] 1298922bc30SVineet Gupta#ifdef CONFIG_ISA_ARCV2 1308922bc30SVineet Gupta.Lbyte_end: 1318922bc30SVineet Gupta brne r3,r12,.Lbyte_odd 1328922bc30SVineet Gupta#else 1335210d1e6SVineet Gupta brne r3,r12,.Lbyte_odd 1345210d1e6SVineet Gupta.Lbyte_end: 1358922bc30SVineet Gupta#endif 1365210d1e6SVineet Gupta bcc .Lbyte_even 1375210d1e6SVineet Gupta brne r4,r5,.Lbyte_even 1385210d1e6SVineet Gupta ldb_s r3,[r0,1] 1395210d1e6SVineet Gupta ldb_s r12,[r1,1] 1405210d1e6SVineet Gupta.Lbyte_odd: 1415210d1e6SVineet Gupta j_s.d [blink] 1425210d1e6SVineet Gupta sub r0,r3,r12 1435210d1e6SVineet Gupta.Lbyte_even: 1445210d1e6SVineet Gupta j_s.d [blink] 1455210d1e6SVineet Gupta sub r0,r4,r5 1465210d1e6SVineet Gupta.Lnil: 1475210d1e6SVineet Gupta j_s.d [blink] 1485210d1e6SVineet Gupta mov r0,0 14986effd0dSVineet GuptaEND_CFI(memcmp) 150