| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* $Id: memscan.S,v 1.4 1996/09/08 02:01:20 davem Exp $ | 
|  | 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 |