xref: /openbmc/linux/arch/openrisc/lib/string.S (revision 3dc4b6fb)
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * OpenRISC string.S
4 *
5 * Linux architectural port borrowing liberally from similar works of
6 * others.  All original copyrights apply as per the original source
7 * declaration.
8 *
9 * Modifications for the OpenRISC architecture:
10 * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
11 * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
12 */
13
14#include <linux/linkage.h>
15#include <asm/errno.h>
16
17	/*
18	 * this can be optimized by doing gcc inline assemlby with
19	 * proper constraints (no need to save args registers...)
20	 *
21	 */
22
23
24/*
25 *
26 * int __copy_tofrom_user(void *to, const void *from, unsigned long size);
27 *
28 * NOTE: it returns number of bytes NOT copied !!!
29 *
30 */
31	.global	__copy_tofrom_user
32__copy_tofrom_user:
33	l.addi  r1,r1,-12
34	l.sw    0(r1),r6
35	l.sw    4(r1),r4
36	l.sw    8(r1),r3
37
38	l.addi  r11,r5,0
392:  	l.sfeq  r11,r0
40	l.bf    1f
41	l.addi  r11,r11,-1
428:    	l.lbz   r6,0(r4)
439:    	l.sb    0(r3),r6
44	l.addi  r3,r3,1
45	l.j     2b
46	l.addi  r4,r4,1
471:
48	l.addi  r11,r11,1               // r11 holds the return value
49
50	l.lwz   r6,0(r1)
51	l.lwz   r4,4(r1)
52	l.lwz   r3,8(r1)
53	l.jr    r9
54	l.addi  r1,r1,12
55
56	.section .fixup, "ax"
5799:
58		l.j     1b
59		l.nop
60	.previous
61
62	.section __ex_table, "a"
63		.long 8b, 99b		// read fault
64		.long 9b, 99b		// write fault
65	.previous
66
67/*
68 * unsigned long clear_user(void *addr, unsigned long size) ;
69 *
70 * NOTE: it returns number of bytes NOT cleared !!!
71 */
72	.global	__clear_user
73__clear_user:
74	l.addi  r1,r1,-8
75	l.sw    0(r1),r4
76	l.sw    4(r1),r3
77
782:	l.sfeq	r4,r0
79	l.bf	1f
80	l.addi	r4,r4,-1
819:	l.sb	0(r3),r0
82	l.j	2b
83	l.addi  r3,r3,1
84
851:
86	l.addi  r11,r4,1
87
88	l.lwz	r4,0(r1)
89	l.lwz	r3,4(r1)
90	l.jr	r9
91	l.addi	r1,r1,8
92
93	.section .fixup, "ax"
9499:
95		l.j     1b
96		l.nop
97	.previous
98
99	.section __ex_table, "a"
100		.long 9b, 99b		// write fault
101	.previous
102