1 /* 2 * Copyright (C) 2006 The android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifdef NDEBUG 18 #define DBG # 19 #else 20 #define DBG 21 #endif 22 23 .text 24 .align 25 26 /* 27 * Optimized memset16 for MIPS 28 * 29 * void android_memset16_test(uint16_t* dst, uint16_t value, size_t size); 30 * 31 */ 32 33 .global android_memset16_test 34 .type android_memset16_test, @function 35 android_memset16_test: 36 .ent android_memset16_test 37 .set noreorder 38 39 /* Check parameters */ 40 DBG andi $t0,$a0,1 /* $a0 must be halfword aligned */ 41 DBG tne $t0 42 DBG lui $t1,0xffff /* $a1 must be 16bits */ 43 DBG and $t1,$a1 44 DBG tne $t1 45 DBG andi $t2,$a2,1 /* $a2 must be even */ 46 DBG tne $t2 47 48 #if (__mips==32) && (__mips_isa_rev>=2) 49 ins $a2,$0,0,1 50 #else 51 li $t0,~1 52 and $a2,$t0 53 #endif 54 55 move $t8,$ra 56 blez $a2,9f /* Anything to do? */ 57 andi $t0,$a0,2 /* Check dst alignment */ 58 /* Expand value to 32 bits and check destination alignment */ 59 #if (__mips==32) && (__mips_isa_rev>=2) 60 beqz $t0,.Laligned32 /* dst is 32 bit aligned */ 61 ins $a1,$a1,16,16 62 #else 63 sll $t2,$a1,16 64 beqz $t0,.Laligned32 /* dst is 32 bit aligned */ 65 or $a1,$t2 66 #endif 67 sh $a1,($a0) /* do one halfword to get aligned */ 68 subu $a2,2 69 addu $a0,2 70 71 .Laligned32: 72 and $t1,$a2,63 /* is there enough left to do a full 64 byte loop? */ 73 beq $a2,$t1,1f 74 subu $t2,$a2,$t1 /* $t2 is the number of bytes to do in loop64 */ 75 addu $t3,$a0,$t2 /* $t3 is the end marker for loop64 */ 76 subu $a2,$t2 77 .Lloop64: 78 addu $a0,64 79 sw $a1,-64($a0) 80 sw $a1,-60($a0) 81 sw $a1,-56($a0) 82 sw $a1,-52($a0) 83 sw $a1,-48($a0) 84 sw $a1,-44($a0) 85 sw $a1,-40($a0) 86 sw $a1,-36($a0) 87 sw $a1,-32($a0) 88 sw $a1,-28($a0) 89 sw $a1,-24($a0) 90 sw $a1,-20($a0) 91 sw $a1,-16($a0) 92 sw $a1,-12($a0) 93 sw $a1,-8($a0) 94 bne $a0,$t3,.Lloop64 95 sw $a1,-4($a0) 96 97 /* Do the last 0..62 bytes */ 98 1: li $t0,64+12 99 andi $t1,$a2,0x3c /* $t1 how many bytes to store using sw */ 100 bal 1f 101 subu $t0,$t1 /* 64+12-$t0 is offset to jump from 1f */ 102 1: addu $ra,$t0 103 j $ra 104 subu $a2,$t1 105 2: sw $a1,60($a0) 106 sw $a1,56($a0) 107 sw $a1,52($a0) 108 sw $a1,48($a0) 109 sw $a1,44($a0) 110 sw $a1,40($a0) 111 sw $a1,36($a0) 112 sw $a1,32($a0) 113 sw $a1,28($a0) 114 sw $a1,24($a0) 115 sw $a1,20($a0) 116 sw $a1,16($a0) 117 sw $a1,12($a0) 118 sw $a1,8($a0) 119 sw $a1,4($a0) 120 sw $a1,0($a0) 121 122 beqz $a2,9f 123 addu $a0,$t1 124 sh $a1,($a0) 125 126 9: j $t8 127 nop 128 .end android_memset16_test 129 .size android_memset16_test,.-android_memset16_test 130 131 /* 132 * Optimized memset32 for MIPS 133 * 134 * void android_memset32_test(uint32_t* dst, uint32_t value, size_t size); 135 * 136 */ 137 .global android_memset32_test 138 .type android_memset32_test, @function 139 android_memset32_test: 140 .ent android_memset32_test 141 .set noreorder 142 143 /* Check parameters */ 144 DBG andi $t0,$a0,3 /* $a0 must be word aligned */ 145 DBG tne $t0 146 DBG andi $t2,$a2,3 /* $a2 must be a multiple of 4 bytes */ 147 DBG tne $t2 148 149 b .Laligned32 150 move $t8,$ra 151 .end android_memset32_test 152 .size android_memset32_test,.-android_memset32_test 153