| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | *  linux/arch/m32r/lib/memset.S | 
|  | 3 | * | 
|  | 4 | *  Copyright (C) 2001,2002  Hiroyuki Kondo, and Hirokazu Takata | 
|  | 5 | *  Copyright (C) 2004  Hirokazu Takata | 
|  | 6 | * | 
|  | 7 | *  void *memset(void *dst, int val, int len); | 
|  | 8 | * | 
|  | 9 | *        dst: r0 | 
|  | 10 | *        val: r1 | 
|  | 11 | *        len: r2 | 
|  | 12 | *        ret: r0 | 
|  | 13 | * | 
|  | 14 | */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 15 |  | 
|  | 16 | .text | 
|  | 17 | .global	memset | 
|  | 18 |  | 
|  | 19 | #ifdef CONFIG_ISA_DUAL_ISSUE | 
|  | 20 |  | 
|  | 21 | .align 4 | 
|  | 22 | memset: | 
|  | 23 | mv      r4, r0		    ||	cmpz	r2 | 
|  | 24 | jc	r14 | 
|  | 25 | cmpui	r2, #16 | 
|  | 26 | bnc	qword_align_check | 
|  | 27 | cmpui	r2, #4 | 
|  | 28 | bc	byte_set | 
|  | 29 | word_align_check:			/* len >= 4 */ | 
|  | 30 | and3	r3, r4, #3 | 
|  | 31 | beqz	r3, word_set | 
|  | 32 | addi	r3, #-4 | 
|  | 33 | neg	r3, r3			/* r3 = -(r3 - 4) */ | 
|  | 34 | align_word: | 
|  | 35 | stb	r1, @r4		    ||	addi	r4, #1 | 
|  | 36 | addi	r2, #-1		    ||	addi	r3, #-1 | 
|  | 37 | bnez	r3, align_word | 
|  | 38 | cmpui	r2, #4 | 
|  | 39 | bc	byte_set | 
|  | 40 | word_set: | 
|  | 41 | and3	r1, r1, #0x00ff		/* r1: abababab <-- ??????ab */ | 
|  | 42 | sll3	r3, r1, #8 | 
|  | 43 | or	r1, r3		    ||	addi	r4, #-4 | 
|  | 44 | sll3	r3, r1, #16 | 
|  | 45 | or	r1, r3		    ||	addi	r2, #-4 | 
|  | 46 | word_set_loop: | 
|  | 47 | st	r1, @+r4	    ||	addi	r2, #-4 | 
|  | 48 | bgtz	r2, word_set_loop | 
|  | 49 | bnez	r2, byte_set_wrap | 
|  | 50 | st	r1, @+r4 | 
|  | 51 | jmp	r14 | 
|  | 52 |  | 
|  | 53 | qword_align_check:			/* len >= 16 */ | 
|  | 54 | and3	r3, r4, #15 | 
|  | 55 | bnez	r3, word_align_check | 
|  | 56 | qword_set: | 
|  | 57 | and3	r1, r1, #0x00ff		/* r1: abababab <-- ??????ab */ | 
|  | 58 | sll3	r3, r1, #8 | 
|  | 59 | or	r1, r3		    ||	addi	r4, #-4 | 
|  | 60 | sll3	r3, r1, #16 | 
|  | 61 | or	r1, r3		    ||	ldi	r5, #16 | 
|  | 62 | qword_set_loop: | 
|  | 63 | ld	r3, @(4,r4)		/* cache line allocate */ | 
|  | 64 | st	r1, @+r4	    ||	addi	r2, #-16 | 
|  | 65 | st	r1, @+r4	    ||	cmpu	r2, r5 | 
|  | 66 | st	r1, @+r4 | 
|  | 67 | st	r1, @+r4 | 
|  | 68 | bnc	qword_set_loop	    ||  cmpz	r2 | 
|  | 69 | jc	r14 | 
|  | 70 | set_remainder: | 
|  | 71 | cmpui	r2, #4 | 
|  | 72 | bc	byte_set_wrap1 | 
|  | 73 | addi	r2, #-4 | 
|  | 74 | bra	word_set_loop | 
|  | 75 |  | 
|  | 76 | byte_set_wrap: | 
|  | 77 | addi	r2, #4 | 
|  | 78 | cmpz	r2 | 
|  | 79 | jc	r14 | 
|  | 80 | byte_set_wrap1: | 
|  | 81 | addi	r4, #4 | 
|  | 82 | #if defined(CONFIG_ISA_M32R2) | 
|  | 83 | byte_set: | 
|  | 84 | addi	r2, #-1		    ||	stb	r1, @r4+ | 
|  | 85 | bnez	r2, byte_set | 
|  | 86 | #elif defined(CONFIG_ISA_M32R) | 
|  | 87 | byte_set: | 
|  | 88 | addi	r2, #-1		    ||	stb	r1, @r4 | 
|  | 89 | addi	r4, #1 | 
|  | 90 | bnez	r2, byte_set | 
|  | 91 | #else | 
|  | 92 | #error unknown isa configuration | 
|  | 93 | #endif | 
|  | 94 | end_memset: | 
|  | 95 | jmp	r14 | 
|  | 96 |  | 
|  | 97 | #else /* not CONFIG_ISA_DUAL_ISSUE */ | 
|  | 98 |  | 
|  | 99 | .align 4 | 
|  | 100 | memset: | 
|  | 101 | mv      r4, r0 | 
|  | 102 | beqz	r2, end_memset | 
|  | 103 | cmpui	r2, #16 | 
|  | 104 | bnc	qword_align_check | 
|  | 105 | cmpui	r2, #4 | 
|  | 106 | bc	byte_set | 
|  | 107 | word_align_check:			/* len >= 4 */ | 
|  | 108 | and3	r3, r4, #3 | 
|  | 109 | beqz	r3, word_set | 
|  | 110 | addi	r3, #-4 | 
|  | 111 | neg	r3, r3			/* r3 = -(r3 - 4) */ | 
|  | 112 | align_word: | 
|  | 113 | stb	r1, @r4 | 
|  | 114 | addi	r4, #1 | 
|  | 115 | addi	r2, #-1 | 
|  | 116 | addi	r3, #-1 | 
|  | 117 | bnez	r3, align_word | 
|  | 118 | cmpui	r2, #4 | 
|  | 119 | bc	byte_set | 
|  | 120 | word_set: | 
|  | 121 | and3	r1, r1, #0x00ff		/* r1: abababab <-- ??????ab */ | 
|  | 122 | sll3	r3, r1, #8 | 
|  | 123 | or	r1, r3 | 
|  | 124 | sll3	r3, r1, #16 | 
|  | 125 | or	r1, r3 | 
|  | 126 | addi	r2, #-4 | 
|  | 127 | addi	r4, #-4 | 
|  | 128 | word_set_loop: | 
|  | 129 | st	r1, @+r4 | 
|  | 130 | addi	r2, #-4 | 
|  | 131 | bgtz    r2, word_set_loop | 
|  | 132 | bnez	r2, byte_set_wrap | 
|  | 133 | st	r1, @+r4 | 
|  | 134 | jmp	r14 | 
|  | 135 |  | 
|  | 136 | qword_align_check:			/* len >= 16 */ | 
|  | 137 | and3	r3, r4, #15 | 
|  | 138 | bnez	r3, word_align_check | 
|  | 139 | qword_set: | 
|  | 140 | and3	r1, r1, #0x00ff		/* r1: abababab <-- ??????ab */ | 
|  | 141 | sll3	r3, r1, #8 | 
|  | 142 | or	r1, r3 | 
|  | 143 | sll3	r3, r1, #16 | 
|  | 144 | or	r1, r3 | 
|  | 145 | addi	r4, #-4 | 
|  | 146 | qword_set_loop: | 
|  | 147 | ld	r3, @(4,r4)		/* cache line allocate */ | 
|  | 148 | addi	r2, #-16 | 
|  | 149 | st	r1, @+r4 | 
|  | 150 | st	r1, @+r4 | 
|  | 151 | cmpui	r2, #16 | 
|  | 152 | st	r1, @+r4 | 
|  | 153 | st	r1, @+r4 | 
|  | 154 | bnc	qword_set_loop | 
|  | 155 | bnez	r2, set_remainder | 
|  | 156 | jmp	r14 | 
|  | 157 | set_remainder: | 
|  | 158 | cmpui	r2, #4 | 
|  | 159 | bc	byte_set_wrap1 | 
|  | 160 | addi	r2, #-4 | 
|  | 161 | bra	word_set_loop | 
|  | 162 |  | 
|  | 163 | byte_set_wrap: | 
|  | 164 | addi	r2, #4 | 
|  | 165 | beqz	r2, end_memset | 
|  | 166 | byte_set_wrap1: | 
|  | 167 | addi	r4, #4 | 
|  | 168 | byte_set: | 
|  | 169 | addi	r2, #-1 | 
|  | 170 | stb	r1, @r4 | 
|  | 171 | addi	r4, #1 | 
|  | 172 | bnez	r2, byte_set | 
|  | 173 | end_memset: | 
|  | 174 | jmp	r14 | 
|  | 175 |  | 
|  | 176 | #endif /* not CONFIG_ISA_DUAL_ISSUE */ | 
|  | 177 |  | 
|  | 178 | .end |