Merge branch 'fix/hda' into for-linus
[sfrench/cifs-2.6.git] / arch / blackfin / lib / memset.S
1 /*
2  * Copyright 2004-2009 Analog Devices Inc.
3  *
4  * Licensed under the ADI BSD license or the GPL-2 (or later)
5  */
6
7 #include <linux/linkage.h>
8
9 .align 2
10
11 #ifdef CONFIG_MEMSET_L1
12 .section .l1.text
13 #else
14 .text
15 #endif
16
17 /*
18  * C Library function MEMSET
19  * R0 = address (leave unchanged to form result)
20  * R1 = filler byte
21  * R2 = count
22  * Favours word aligned data.
23  */
24
25 ENTRY(_memset)
26         P0 = R0 ;              /* P0 = address */
27         P2 = R2 ;              /* P2 = count   */
28         R3 = R0 + R2;          /* end          */
29         CC = R2 <= 7(IU);
30         IF CC JUMP  .Ltoo_small;
31         R1 = R1.B (Z);         /* R1 = fill char */
32         R2 =  3;
33         R2 = R0 & R2;          /* addr bottom two bits */
34         CC =  R2 == 0;             /* AZ set if zero.   */
35         IF !CC JUMP  .Lforce_align ;  /* Jump if addr not aligned. */
36
37 .Laligned:
38         P1 = P2 >> 2;          /* count = n/4        */
39         R2 = R1 <<  8;         /* create quad filler */
40         R2.L = R2.L + R1.L(NS);
41         R2.H = R2.L + R1.H(NS);
42         P2 = R3;
43
44         LSETUP (.Lquad_loop , .Lquad_loop) LC0=P1;
45 .Lquad_loop:
46         [P0++] = R2;
47
48         CC = P0 == P2;
49         IF !CC JUMP .Lbytes_left;
50         RTS;
51
52 .Lbytes_left:
53         R2 = R3;                /* end point */
54         R3 = P0;                /* current position */
55         R2 = R2 - R3;           /* bytes left */
56         P2 = R2;
57
58 .Ltoo_small:
59         CC = P2 == 0;           /* Check zero count */
60         IF CC JUMP .Lfinished;    /* Unusual */
61
62 .Lbytes:
63         LSETUP (.Lbyte_loop , .Lbyte_loop) LC0=P2;
64 .Lbyte_loop:
65         B[P0++] = R1;
66
67 .Lfinished:
68         RTS;
69
70 .Lforce_align:
71         CC = BITTST (R0, 0);  /* odd byte */
72         R0 = 4;
73         R0 = R0 - R2;
74         P1 = R0;
75         R0 = P0;                    /* Recover return address */
76         IF !CC JUMP .Lskip1;
77         B[P0++] = R1;
78 .Lskip1:
79         CC = R2 <= 2;          /* 2 bytes */
80         P2 -= P1;              /* reduce count */
81         IF !CC JUMP .Laligned;
82         B[P0++] = R1;
83         B[P0++] = R1;
84         JUMP .Laligned;
85
86 ENDPROC(_memset)