Home | History | Annotate | Download | only in memset_mips
      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