Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * User string length functions for kernel
4 *
5 * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
6 */
7
8#define isrc r0
9#define max r1 /* Do not change! */
10
11#define end r2
12#define tmp1 r3
13
14#define obo r6 /* off-by-one */
15#define start r7
16#define mod8 r8
17#define dbuf r15:14
18#define dcmp r13:12
19
20/*
21 * The vector mask version of this turned out *really* badly.
22 * The hardware loop version also turned out *really* badly.
23 * Seems straight pointer arithmetic basically wins here.
24 */
25
26#define fname __strnlen_user
27
28 .text
29 .global fname
30 .type fname, @function
31 .p2align 5 /* why? */
32fname:
33 {
34 mod8 = and(isrc,#7);
35 end = add(isrc,max);
36 start = isrc;
37 }
38 {
39 P0 = cmp.eq(mod8,#0);
40 mod8 = and(end,#7);
41 dcmp = #0;
42 if (P0.new) jump:t dw_loop; /* fire up the oven */
43 }
44
45alignment_loop:
46fail_1: {
47 tmp1 = memb(start++#1);
48 }
49 {
50 P0 = cmp.eq(tmp1,#0);
51 if (P0.new) jump:nt exit_found;
52 P1 = cmp.gtu(end,start);
53 mod8 = and(start,#7);
54 }
55 {
56 if (!P1) jump exit_error; /* hit the end */
57 P0 = cmp.eq(mod8,#0);
58 }
59 {
60 if (!P0) jump alignment_loop;
61 }
62
63
64
65dw_loop:
66fail_2: {
67 dbuf = memd(start);
68 obo = add(start,#1);
69 }
70 {
71 P0 = vcmpb.eq(dbuf,dcmp);
72 }
73 {
74 tmp1 = P0;
75 P0 = cmp.gtu(end,start);
76 }
77 {
78 tmp1 = ct0(tmp1);
79 mod8 = and(end,#7);
80 if (!P0) jump end_check;
81 }
82 {
83 P0 = cmp.eq(tmp1,#32);
84 if (!P0.new) jump:nt exit_found;
85 if (!P0.new) start = add(obo,tmp1);
86 }
87 {
88 start = add(start,#8);
89 jump dw_loop;
90 } /* might be nice to combine these jumps... */
91
92
93end_check:
94 {
95 P0 = cmp.gt(tmp1,mod8);
96 if (P0.new) jump:nt exit_error; /* neverfound! */
97 start = add(obo,tmp1);
98 }
99
100exit_found:
101 {
102 R0 = sub(start,isrc);
103 jumpr R31;
104 }
105
106exit_error:
107 {
108 R0 = add(max,#1);
109 jumpr R31;
110 }
111
112 /* Uh, what does the "fixup" return here? */
113 .falign
114fix_1:
115 {
116 R0 = #0;
117 jumpr R31;
118 }
119
120 .size fname,.-fname
121
122
123.section __ex_table,"a"
124.long fail_1,fix_1
125.long fail_2,fix_1
126.previous