/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
*/
#include <linux/export.h>
#include <asm/alternative-asm.h>
#include <asm/asm.h>
#include <asm/asmmacro.h>
#include <asm/asm-extable.h>
#include <asm/cpu.h>
#include <asm/regdef.h>
#include <asm/unwind_hints.h>
SYM_FUNC_START(__copy_user)
/*
* Some CPUs support hardware unaligned access
*/
ALTERNATIVE "b __copy_user_generic" , \
"b __copy_user_fast" , CPU_FEATURE_UAL
SYM_FUNC_END(__copy_user)
EXPORT_SYMBOL(__copy_user)
/*
* unsigned long __copy_user_generic(void *to, const void *from, size_t n)
*
* a0: to
* a1: from
* a2: n
*/
SYM_FUNC_START(__copy_user_generic)
beqz a2, 3 f
1 : ld .b t0, a1, 0
2 : st .b t0, a0, 0
addi.d a0, a0, 1
addi.d a1, a1, 1
addi.d a2, a2, -1
bgtz a2, 1 b
3 : move a0, a2
jr ra
_asm_extable 1 b, 3 b
_asm_extable 2 b, 3 b
SYM_FUNC_END(__copy_user_generic)
/*
* unsigned long __copy_user_fast(void *to, const void *from, unsigned long n)
*
* a0: to
* a1: from
* a2: n
*/
SYM_FUNC_START(__copy_user_fast)
sltui t0, a2, 9
bnez t0, .Lsmall
0 : ld .d t0, a1, 0
1 : st .d t0, a0, 0
add.d a3, a1, a2
add.d a2, a0, a2
/* align up destination address */
andi t1, a0, 7
sub .d t0, zero, t1
addi.d t0, t0, 8
add.d a1, a1, t0
add.d a0, a0, t0
addi.d a4, a3, -64
bgeu a1, a4, .Llt64
/* copy 64 bytes at a time */
.Lloop64:
2 : ld .d t0, a1, 0
3 : ld .d t1, a1, 8
4 : ld .d t2, a1, 16
5 : ld .d t3, a1, 24
6 : ld .d t4, a1, 32
7 : ld .d t5, a1, 40
8 : ld .d t6, a1, 48
9 : ld .d t7, a1, 56
10 : st .d t0, a0, 0
11 : st .d t1, a0, 8
12 : st .d t2, a0, 16
13 : st .d t3, a0, 24
14 : st .d t4, a0, 32
15 : st .d t5, a0, 40
16 : st .d t6, a0, 48
17 : st .d t7, a0, 56
addi.d a1, a1, 64
addi.d a0, a0, 64
bltu a1, a4, .Lloop64
/* copy the remaining bytes */
.Llt64:
addi.d a4, a3, -32
bgeu a1, a4, .Llt32
18 : ld .d t0, a1, 0
19 : ld .d t1, a1, 8
20 : ld .d t2, a1, 16
21 : ld .d t3, a1, 24
22 : st .d t0, a0, 0
23 : st .d t1, a0, 8
24 : st .d t2, a0, 16
25 : st .d t3, a0, 24
addi.d a1, a1, 32
addi.d a0, a0, 32
.Llt32:
addi.d a4, a3, -16
bgeu a1, a4, .Llt16
26 : ld .d t0, a1, 0
27 : ld .d t1, a1, 8
28 : st .d t0, a0, 0
29 : st .d t1, a0, 8
addi.d a1, a1, 16
addi.d a0, a0, 16
.Llt16:
addi.d a4, a3, -8
bgeu a1, a4, .Llt8
30 : ld .d t0, a1, 0
31 : st .d t0, a0, 0
addi.d a1, a1, 8
addi.d a0, a0, 8
.Llt8:
32 : ld .d t0, a3, -8
33 : st .d t0, a2, -8
/* return */
move a0, zero
jr ra
.align 5
.Lsmall:
pcaddi t0, 8
slli.d a3, a2, 5
add.d t0, t0, a3
jr t0
.align 5
move a0, zero
jr ra
.align 5
34 : ld .b t0, a1, 0
35 : st .b t0, a0, 0
move a0, zero
jr ra
.align 5
36 : ld .h t0, a1, 0
37 : st .h t0, a0, 0
move a0, zero
jr ra
.align 5
38 : ld .h t0, a1, 0
39 : ld .b t1, a1, 2
40 : st .h t0, a0, 0
41 : st .b t1, a0, 2
move a0, zero
jr ra
.align 5
42 : ld .w t0, a1, 0
43 : st .w t0, a0, 0
move a0, zero
jr ra
.align 5
44 : ld .w t0, a1, 0
45 : ld .b t1, a1, 4
46 : st .w t0, a0, 0
47 : st .b t1, a0, 4
move a0, zero
jr ra
.align 5
48 : ld .w t0, a1, 0
49 : ld .h t1, a1, 4
50 : st .w t0, a0, 0
51 : st .h t1, a0, 4
move a0, zero
jr ra
.align 5
52 : ld .w t0, a1, 0
53 : ld .w t1, a1, 3
54 : st .w t0, a0, 0
55 : st .w t1, a0, 3
move a0, zero
jr ra
.align 5
56 : ld .d t0, a1, 0
57 : st .d t0, a0, 0
move a0, zero
jr ra
/* fixup and ex_table */
.Llarge_fixup:
sub .d a2, a2, a0
.Lsmall_fixup:
58 : ld .b t0, a1, 0
59 : st .b t0, a0, 0
addi.d a0, a0, 1
addi.d a1, a1, 1
addi.d a2, a2, -1
bgt a2, zero, 58 b
.Lexit:
move a0, a2
jr ra
_asm_extable 0 b, .Lsmall_fixup
_asm_extable 1 b, .Lsmall_fixup
_asm_extable 2 b, .Llarge_fixup
_asm_extable 3 b, .Llarge_fixup
_asm_extable 4 b, .Llarge_fixup
_asm_extable 5 b, .Llarge_fixup
_asm_extable 6 b, .Llarge_fixup
_asm_extable 7 b, .Llarge_fixup
_asm_extable 8 b, .Llarge_fixup
_asm_extable 9 b, .Llarge_fixup
_asm_extable 10 b, .Llarge_fixup
_asm_extable 11 b, .Llarge_fixup
_asm_extable 12 b, .Llarge_fixup
_asm_extable 13 b, .Llarge_fixup
_asm_extable 14 b, .Llarge_fixup
_asm_extable 15 b, .Llarge_fixup
_asm_extable 16 b, .Llarge_fixup
_asm_extable 17 b, .Llarge_fixup
_asm_extable 18 b, .Llarge_fixup
_asm_extable 19 b, .Llarge_fixup
_asm_extable 20 b, .Llarge_fixup
_asm_extable 21 b, .Llarge_fixup
_asm_extable 22 b, .Llarge_fixup
_asm_extable 23 b, .Llarge_fixup
_asm_extable 24 b, .Llarge_fixup
_asm_extable 25 b, .Llarge_fixup
_asm_extable 26 b, .Llarge_fixup
_asm_extable 27 b, .Llarge_fixup
_asm_extable 28 b, .Llarge_fixup
_asm_extable 29 b, .Llarge_fixup
_asm_extable 30 b, .Llarge_fixup
_asm_extable 31 b, .Llarge_fixup
_asm_extable 32 b, .Llarge_fixup
_asm_extable 33 b, .Llarge_fixup
_asm_extable 34 b, .Lexit
_asm_extable 35 b, .Lexit
_asm_extable 36 b, .Lsmall_fixup
_asm_extable 37 b, .Lsmall_fixup
_asm_extable 38 b, .Lsmall_fixup
_asm_extable 39 b, .Lsmall_fixup
_asm_extable 40 b, .Lsmall_fixup
_asm_extable 41 b, .Lsmall_fixup
_asm_extable 42 b, .Lsmall_fixup
_asm_extable 43 b, .Lsmall_fixup
_asm_extable 44 b, .Lsmall_fixup
_asm_extable 45 b, .Lsmall_fixup
_asm_extable 46 b, .Lsmall_fixup
_asm_extable 47 b, .Lsmall_fixup
_asm_extable 48 b, .Lsmall_fixup
_asm_extable 49 b, .Lsmall_fixup
_asm_extable 50 b, .Lsmall_fixup
_asm_extable 51 b, .Lsmall_fixup
_asm_extable 52 b, .Lsmall_fixup
_asm_extable 53 b, .Lsmall_fixup
_asm_extable 54 b, .Lsmall_fixup
_asm_extable 55 b, .Lsmall_fixup
_asm_extable 56 b, .Lsmall_fixup
_asm_extable 57 b, .Lsmall_fixup
_asm_extable 58 b, .Lexit
_asm_extable 59 b, .Lexit
SYM_FUNC_END(__copy_user_fast)
STACK_FRAME_NON_STANDARD __copy_user_fast
Messung V0.5 in Prozent C=97 H=84 G=90
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-06-07)
¤
*© Formatika GbR, Deutschland