Duane Sand | d4a8098 | 2012-10-12 14:25:19 -0700 | [diff] [blame] | 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 |