1 /* SPDX-License-Identifier: GPL-2.0-only */ !! 1 /* Sparc optimized memcmp code. 2 /* !! 2 * 3 * Copyright (C) 2004, 2007-2010, 2011-2012 Sy !! 3 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) >> 4 * Copyright (C) 2000, 2008 David S. Miller (davem@davemloft.net) 4 */ 5 */ 5 6 6 #include <linux/linkage.h> 7 #include <linux/linkage.h> >> 8 #include <asm/asm.h> 7 9 8 #ifdef __LITTLE_ENDIAN__ !! 10 .text 9 #define WORD2 r2 !! 11 ENTRY(memcmp) 10 #define SHIFT r3 !! 12 cmp %o2, 0 11 #else /* BIG ENDIAN */ !! 13 1: BRANCH32(be, pn, 2f) 12 #define WORD2 r3 !! 14 nop 13 #define SHIFT r2 !! 15 ldub [%o0], %g7 14 #endif !! 16 ldub [%o1], %g3 15 !! 17 sub %o2, 1, %o2 16 ENTRY_CFI(memcmp) !! 18 add %o0, 1, %o0 17 or r12,r0,r1 !! 19 add %o1, 1, %o1 18 asl_s r12,r12,30 !! 20 subcc %g7, %g3, %g3 19 sub r3,r2,1 !! 21 BRANCH32(be, pt, 1b) 20 brls r2,r12,.Lbytewise !! 22 cmp %o2, 0 21 ld r4,[r0,0] !! 23 retl 22 ld r5,[r1,0] !! 24 mov %g3, %o0 23 lsr.f lp_count,r3,3 !! 25 2: retl 24 #ifdef CONFIG_ISA_ARCV2 !! 26 mov 0, %o0 25 /* In ARCv2 a branch can't be the last !! 27 ENDPROC(memcmp) 26 * loop. << 27 * So we move the branch to the start << 28 * after the end, and set up r12 so th << 29 * initially. << 30 */ << 31 mov_s r12,WORD2 << 32 lpne .Loop_end << 33 brne WORD2,r12,.Lodd << 34 ld WORD2,[r0,4] << 35 #else << 36 lpne .Loop_end << 37 ld_s WORD2,[r0,4] << 38 #endif << 39 ld_s r12,[r1,4] << 40 brne r4,r5,.Leven << 41 ld.a r4,[r0,8] << 42 ld.a r5,[r1,8] << 43 #ifdef CONFIG_ISA_ARCV2 << 44 .Loop_end: << 45 brne WORD2,r12,.Lodd << 46 #else << 47 brne WORD2,r12,.Lodd << 48 .Loop_end: << 49 #endif << 50 asl_s SHIFT,SHIFT,3 << 51 bhs_s .Last_cmp << 52 brne r4,r5,.Leven << 53 ld r4,[r0,4] << 54 ld r5,[r1,4] << 55 #ifdef __LITTLE_ENDIAN__ << 56 nop_s << 57 ; one more load latency cycle << 58 .Last_cmp: << 59 xor r0,r4,r5 << 60 bset r0,r0,SHIFT << 61 sub_s r1,r0,1 << 62 bic_s r1,r1,r0 << 63 norm r1,r1 << 64 b.d .Leven_cmp << 65 and r1,r1,24 << 66 .Leven: << 67 xor r0,r4,r5 << 68 sub_s r1,r0,1 << 69 bic_s r1,r1,r0 << 70 norm r1,r1 << 71 ; slow track insn << 72 and r1,r1,24 << 73 .Leven_cmp: << 74 asl r2,r4,r1 << 75 asl r12,r5,r1 << 76 lsr_s r2,r2,1 << 77 lsr_s r12,r12,1 << 78 j_s.d [blink] << 79 sub r0,r2,r12 << 80 .balign 4 << 81 .Lodd: << 82 xor r0,WORD2,r12 << 83 sub_s r1,r0,1 << 84 bic_s r1,r1,r0 << 85 norm r1,r1 << 86 ; slow track insn << 87 and r1,r1,24 << 88 asl_s r2,r2,r1 << 89 asl_s r12,r12,r1 << 90 lsr_s r2,r2,1 << 91 lsr_s r12,r12,1 << 92 j_s.d [blink] << 93 sub r0,r2,r12 << 94 #else /* BIG ENDIAN */ << 95 .Last_cmp: << 96 neg_s SHIFT,SHIFT << 97 lsr r4,r4,SHIFT << 98 lsr r5,r5,SHIFT << 99 ; slow track insn << 100 .Leven: << 101 sub.f r0,r4,r5 << 102 mov.ne r0,1 << 103 j_s.d [blink] << 104 bset.cs r0,r0,31 << 105 .Lodd: << 106 cmp_s WORD2,r12 << 107 mov_s r0,1 << 108 j_s.d [blink] << 109 bset.cs r0,r0,31 << 110 #endif /* ENDIAN */ << 111 .balign 4 << 112 .Lbytewise: << 113 breq r2,0,.Lnil << 114 ldb r4,[r0,0] << 115 ldb r5,[r1,0] << 116 lsr.f lp_count,r3 << 117 #ifdef CONFIG_ISA_ARCV2 << 118 mov r12,r3 << 119 lpne .Lbyte_end << 120 brne r3,r12,.Lbyte_odd << 121 #else << 122 lpne .Lbyte_end << 123 #endif << 124 ldb_s r3,[r0,1] << 125 ldb r12,[r1,1] << 126 brne r4,r5,.Lbyte_even << 127 ldb.a r4,[r0,2] << 128 ldb.a r5,[r1,2] << 129 #ifdef CONFIG_ISA_ARCV2 << 130 .Lbyte_end: << 131 brne r3,r12,.Lbyte_odd << 132 #else << 133 brne r3,r12,.Lbyte_odd << 134 .Lbyte_end: << 135 #endif << 136 bcc .Lbyte_even << 137 brne r4,r5,.Lbyte_even << 138 ldb_s r3,[r0,1] << 139 ldb_s r12,[r1,1] << 140 .Lbyte_odd: << 141 j_s.d [blink] << 142 sub r0,r3,r12 << 143 .Lbyte_even: << 144 j_s.d [blink] << 145 sub r0,r4,r5 << 146 .Lnil: << 147 j_s.d [blink] << 148 mov r0,0 << 149 END_CFI(memcmp) <<
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.