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

source code of linux/arch/openrisc/lib/string.S