Merge tag 'v4.14-rc2' into patchwork
[linux/fpc-iii.git] / arch / openrisc / lib / string.S
blobc09fee7dec1455082273c9e46b6b2665603f856a
1 /*
2  * OpenRISC string.S
3  *
4  * Linux architectural port borrowing liberally from similar works of
5  * others.  All original copyrights apply as per the original source
6  * declaration.
7  *
8  * Modifications for the OpenRISC architecture:
9  * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
10  * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
11  *
12  *      This program is free software; you can redistribute it and/or
13  *      modify it under the terms of the GNU General Public License
14  *      as published by the Free Software Foundation; either version
15  *      2 of the License, or (at your option) any later version.
16  */
18 #include <linux/linkage.h>
19 #include <asm/errno.h>
21         /*
22          * this can be optimized by doing gcc inline assemlby with
23          * proper constraints (no need to save args registers...)
24          *
25          */
29  *
30  * int __copy_tofrom_user(void *to, const void *from, unsigned long size);
31  *
32  * NOTE: it returns number of bytes NOT copied !!!
33  *
34  */
35         .global __copy_tofrom_user
36 __copy_tofrom_user:
37         l.addi  r1,r1,-12
38         l.sw    0(r1),r6
39         l.sw    4(r1),r4
40         l.sw    8(r1),r3
42         l.addi  r11,r5,0
43 2:      l.sfeq  r11,r0
44         l.bf    1f
45         l.addi  r11,r11,-1
46 8:      l.lbz   r6,0(r4)
47 9:      l.sb    0(r3),r6
48         l.addi  r3,r3,1
49         l.j     2b
50         l.addi  r4,r4,1
52         l.addi  r11,r11,1               // r11 holds the return value
54         l.lwz   r6,0(r1)
55         l.lwz   r4,4(r1)
56         l.lwz   r3,8(r1)
57         l.jr    r9
58         l.addi  r1,r1,12
60         .section .fixup, "ax"
61 99:
62                 l.j     1b
63                 l.nop
64         .previous
66         .section __ex_table, "a"
67                 .long 8b, 99b           // read fault
68                 .long 9b, 99b           // write fault
69         .previous
72  * unsigned long clear_user(void *addr, unsigned long size) ;
73  *
74  * NOTE: it returns number of bytes NOT cleared !!!
75  */
76         .global __clear_user
77 __clear_user:
78         l.addi  r1,r1,-8
79         l.sw    0(r1),r4
80         l.sw    4(r1),r3
82 2:      l.sfeq  r4,r0
83         l.bf    1f
84         l.addi  r4,r4,-1
85 9:      l.sb    0(r3),r0
86         l.j     2b
87         l.addi  r3,r3,1
90         l.addi  r11,r4,1
92         l.lwz   r4,0(r1)
93         l.lwz   r3,4(r1)
94         l.jr    r9
95         l.addi  r1,r1,8
97         .section .fixup, "ax"
98 99:
99                 l.j     1b
100                 l.nop
101         .previous
103         .section __ex_table, "a"
104                 .long 9b, 99b           // write fault
105         .previous