diff options
Diffstat (limited to 'arch/sparc/lib/memscan_32.S')
-rw-r--r-- | arch/sparc/lib/memscan_32.S | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/arch/sparc/lib/memscan_32.S b/arch/sparc/lib/memscan_32.S new file mode 100644 index 000000000000..4ff1657dfc24 --- /dev/null +++ b/arch/sparc/lib/memscan_32.S | |||
@@ -0,0 +1,133 @@ | |||
1 | /* | ||
2 | * memscan.S: Optimized memscan for the Sparc. | ||
3 | * | ||
4 | * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) | ||
5 | */ | ||
6 | |||
7 | /* In essence, this is just a fancy strlen. */ | ||
8 | |||
9 | #define LO_MAGIC 0x01010101 | ||
10 | #define HI_MAGIC 0x80808080 | ||
11 | |||
12 | .text | ||
13 | .align 4 | ||
14 | .globl __memscan_zero, __memscan_generic | ||
15 | .globl memscan | ||
16 | __memscan_zero: | ||
17 | /* %o0 = addr, %o1 = size */ | ||
18 | cmp %o1, 0 | ||
19 | bne,a 1f | ||
20 | andcc %o0, 3, %g0 | ||
21 | |||
22 | retl | ||
23 | nop | ||
24 | |||
25 | 1: | ||
26 | be mzero_scan_word | ||
27 | sethi %hi(HI_MAGIC), %g2 | ||
28 | |||
29 | ldsb [%o0], %g3 | ||
30 | mzero_still_not_word_aligned: | ||
31 | cmp %g3, 0 | ||
32 | bne 1f | ||
33 | add %o0, 1, %o0 | ||
34 | |||
35 | retl | ||
36 | sub %o0, 1, %o0 | ||
37 | |||
38 | 1: | ||
39 | subcc %o1, 1, %o1 | ||
40 | bne,a 1f | ||
41 | andcc %o0, 3, %g0 | ||
42 | |||
43 | retl | ||
44 | nop | ||
45 | |||
46 | 1: | ||
47 | bne,a mzero_still_not_word_aligned | ||
48 | ldsb [%o0], %g3 | ||
49 | |||
50 | sethi %hi(HI_MAGIC), %g2 | ||
51 | mzero_scan_word: | ||
52 | or %g2, %lo(HI_MAGIC), %o3 | ||
53 | sethi %hi(LO_MAGIC), %g3 | ||
54 | or %g3, %lo(LO_MAGIC), %o2 | ||
55 | mzero_next_word: | ||
56 | ld [%o0], %g2 | ||
57 | mzero_next_word_preloaded: | ||
58 | sub %g2, %o2, %g2 | ||
59 | mzero_next_word_preloaded_next: | ||
60 | andcc %g2, %o3, %g0 | ||
61 | bne mzero_byte_zero | ||
62 | add %o0, 4, %o0 | ||
63 | |||
64 | mzero_check_out_of_fuel: | ||
65 | subcc %o1, 4, %o1 | ||
66 | bg,a 1f | ||
67 | ld [%o0], %g2 | ||
68 | |||
69 | retl | ||
70 | nop | ||
71 | |||
72 | 1: | ||
73 | b mzero_next_word_preloaded_next | ||
74 | sub %g2, %o2, %g2 | ||
75 | |||
76 | /* Check every byte. */ | ||
77 | mzero_byte_zero: | ||
78 | ldsb [%o0 - 4], %g2 | ||
79 | cmp %g2, 0 | ||
80 | bne mzero_byte_one | ||
81 | sub %o0, 4, %g3 | ||
82 | |||
83 | retl | ||
84 | mov %g3, %o0 | ||
85 | |||
86 | mzero_byte_one: | ||
87 | ldsb [%o0 - 3], %g2 | ||
88 | cmp %g2, 0 | ||
89 | bne,a mzero_byte_two_and_three | ||
90 | ldsb [%o0 - 2], %g2 | ||
91 | |||
92 | retl | ||
93 | sub %o0, 3, %o0 | ||
94 | |||
95 | mzero_byte_two_and_three: | ||
96 | cmp %g2, 0 | ||
97 | bne,a 1f | ||
98 | ldsb [%o0 - 1], %g2 | ||
99 | |||
100 | retl | ||
101 | sub %o0, 2, %o0 | ||
102 | |||
103 | 1: | ||
104 | cmp %g2, 0 | ||
105 | bne,a mzero_next_word_preloaded | ||
106 | ld [%o0], %g2 | ||
107 | |||
108 | retl | ||
109 | sub %o0, 1, %o0 | ||
110 | |||
111 | mzero_found_it: | ||
112 | retl | ||
113 | sub %o0, 2, %o0 | ||
114 | |||
115 | memscan: | ||
116 | __memscan_generic: | ||
117 | /* %o0 = addr, %o1 = c, %o2 = size */ | ||
118 | cmp %o2, 0 | ||
119 | bne,a 0f | ||
120 | ldub [%o0], %g2 | ||
121 | |||
122 | b,a 2f | ||
123 | 1: | ||
124 | ldub [%o0], %g2 | ||
125 | 0: | ||
126 | cmp %g2, %o1 | ||
127 | be 2f | ||
128 | addcc %o2, -1, %o2 | ||
129 | bne 1b | ||
130 | add %o0, 1, %o0 | ||
131 | 2: | ||
132 | retl | ||
133 | nop | ||