1/* 2 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 */ 8 9#include <linux/linkage.h> 10 11#ifdef __LITTLE_ENDIAN__ 12#define WORD2 r2 13#define SHIFT r3 14#else /* BIG ENDIAN */ 15#define WORD2 r3 16#define SHIFT r2 17#endif 18 19ENTRY_CFI(memcmp) 20 or r12,r0,r1 21 asl_s r12,r12,30 22 sub r3,r2,1 23 brls r2,r12,.Lbytewise 24 ld r4,[r0,0] 25 ld r5,[r1,0] 26 lsr.f lp_count,r3,3 27#ifdef CONFIG_ISA_ARCV2 28 /* In ARCv2 a branch can't be the last instruction in a zero overhead 29 * loop. 30 * So we move the branch to the start of the loop, duplicate it 31 * after the end, and set up r12 so that the branch isn't taken 32 * initially. 33 */ 34 mov_s r12,WORD2 35 lpne .Loop_end 36 brne WORD2,r12,.Lodd 37 ld WORD2,[r0,4] 38#else 39 lpne .Loop_end 40 ld_s WORD2,[r0,4] 41#endif 42 ld_s r12,[r1,4] 43 brne r4,r5,.Leven 44 ld.a r4,[r0,8] 45 ld.a r5,[r1,8] 46#ifdef CONFIG_ISA_ARCV2 47.Loop_end: 48 brne WORD2,r12,.Lodd 49#else 50 brne WORD2,r12,.Lodd 51.Loop_end: 52#endif 53 asl_s SHIFT,SHIFT,3 54 bhs_s .Last_cmp 55 brne r4,r5,.Leven 56 ld r4,[r0,4] 57 ld r5,[r1,4] 58#ifdef __LITTLE_ENDIAN__ 59 nop_s 60 ; one more load latency cycle 61.Last_cmp: 62 xor r0,r4,r5 63 bset r0,r0,SHIFT 64 sub_s r1,r0,1 65 bic_s r1,r1,r0 66 norm r1,r1 67 b.d .Leven_cmp 68 and r1,r1,24 69.Leven: 70 xor r0,r4,r5 71 sub_s r1,r0,1 72 bic_s r1,r1,r0 73 norm r1,r1 74 ; slow track insn 75 and r1,r1,24 76.Leven_cmp: 77 asl r2,r4,r1 78 asl r12,r5,r1 79 lsr_s r2,r2,1 80 lsr_s r12,r12,1 81 j_s.d [blink] 82 sub r0,r2,r12 83 .balign 4 84.Lodd: 85 xor r0,WORD2,r12 86 sub_s r1,r0,1 87 bic_s r1,r1,r0 88 norm r1,r1 89 ; slow track insn 90 and r1,r1,24 91 asl_s r2,r2,r1 92 asl_s r12,r12,r1 93 lsr_s r2,r2,1 94 lsr_s r12,r12,1 95 j_s.d [blink] 96 sub r0,r2,r12 97#else /* BIG ENDIAN */ 98.Last_cmp: 99 neg_s SHIFT,SHIFT 100 lsr r4,r4,SHIFT 101 lsr r5,r5,SHIFT 102 ; slow track insn 103.Leven: 104 sub.f r0,r4,r5 105 mov.ne r0,1 106 j_s.d [blink] 107 bset.cs r0,r0,31 108.Lodd: 109 cmp_s WORD2,r12 110 mov_s r0,1 111 j_s.d [blink] 112 bset.cs r0,r0,31 113#endif /* ENDIAN */ 114 .balign 4 115.Lbytewise: 116 breq r2,0,.Lnil 117 ldb r4,[r0,0] 118 ldb r5,[r1,0] 119 lsr.f lp_count,r3 120#ifdef CONFIG_ISA_ARCV2 121 mov r12,r3 122 lpne .Lbyte_end 123 brne r3,r12,.Lbyte_odd 124#else 125 lpne .Lbyte_end 126#endif 127 ldb_s r3,[r0,1] 128 ldb r12,[r1,1] 129 brne r4,r5,.Lbyte_even 130 ldb.a r4,[r0,2] 131 ldb.a r5,[r1,2] 132#ifdef CONFIG_ISA_ARCV2 133.Lbyte_end: 134 brne r3,r12,.Lbyte_odd 135#else 136 brne r3,r12,.Lbyte_odd 137.Lbyte_end: 138#endif 139 bcc .Lbyte_even 140 brne r4,r5,.Lbyte_even 141 ldb_s r3,[r0,1] 142 ldb_s r12,[r1,1] 143.Lbyte_odd: 144 j_s.d [blink] 145 sub r0,r3,r12 146.Lbyte_even: 147 j_s.d [blink] 148 sub r0,r4,r5 149.Lnil: 150 j_s.d [blink] 151 mov r0,0 152END_CFI(memcmp) 153