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 127