162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * arch/alpha/lib/strncpy.S 462306a36Sopenharmony_ci * Contributed by Richard Henderson (rth@tamu.edu) 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copy no more than COUNT bytes of the null-terminated string from 762306a36Sopenharmony_ci * SRC to DST. If SRC does not cover all of COUNT, the balance is 862306a36Sopenharmony_ci * zeroed. 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * Or, rather, if the kernel cared about that weird ANSI quirk. This 1162306a36Sopenharmony_ci * version has cropped that bit o' nastiness as well as assuming that 1262306a36Sopenharmony_ci * __stxncpy is in range of a branch. 1362306a36Sopenharmony_ci */ 1462306a36Sopenharmony_ci#include <linux/export.h> 1562306a36Sopenharmony_ci .set noat 1662306a36Sopenharmony_ci .set noreorder 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci .text 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci .align 4 2162306a36Sopenharmony_ci .globl strncpy 2262306a36Sopenharmony_ci .ent strncpy 2362306a36Sopenharmony_cistrncpy: 2462306a36Sopenharmony_ci .frame $30, 0, $26 2562306a36Sopenharmony_ci .prologue 0 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci mov $16, $0 # set return value now 2862306a36Sopenharmony_ci beq $18, $zerolen 2962306a36Sopenharmony_ci unop 3062306a36Sopenharmony_ci bsr $23, __stxncpy # do the work of the copy 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci unop 3362306a36Sopenharmony_ci bne $18, $multiword # do we have full words left? 3462306a36Sopenharmony_ci subq $24, 1, $3 # nope 3562306a36Sopenharmony_ci subq $27, 1, $4 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci or $3, $24, $3 # clear the bits between the last 3862306a36Sopenharmony_ci or $4, $27, $4 # written byte and the last byte in COUNT 3962306a36Sopenharmony_ci andnot $3, $4, $4 4062306a36Sopenharmony_ci zap $1, $4, $1 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci stq_u $1, 0($16) 4362306a36Sopenharmony_ci ret 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci .align 4 4662306a36Sopenharmony_ci$multiword: 4762306a36Sopenharmony_ci subq $27, 1, $2 # clear the final bits in the prev word 4862306a36Sopenharmony_ci or $2, $27, $2 4962306a36Sopenharmony_ci zapnot $1, $2, $1 5062306a36Sopenharmony_ci subq $18, 1, $18 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci stq_u $1, 0($16) 5362306a36Sopenharmony_ci addq $16, 8, $16 5462306a36Sopenharmony_ci unop 5562306a36Sopenharmony_ci beq $18, 1f 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci nop 5862306a36Sopenharmony_ci unop 5962306a36Sopenharmony_ci nop 6062306a36Sopenharmony_ci blbc $18, 0f 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci stq_u $31, 0($16) # zero one word 6362306a36Sopenharmony_ci subq $18, 1, $18 6462306a36Sopenharmony_ci addq $16, 8, $16 6562306a36Sopenharmony_ci beq $18, 1f 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci0: stq_u $31, 0($16) # zero two words 6862306a36Sopenharmony_ci subq $18, 2, $18 6962306a36Sopenharmony_ci stq_u $31, 8($16) 7062306a36Sopenharmony_ci addq $16, 16, $16 7162306a36Sopenharmony_ci bne $18, 0b 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci1: ldq_u $1, 0($16) # clear the leading bits in the final word 7462306a36Sopenharmony_ci subq $24, 1, $2 7562306a36Sopenharmony_ci or $2, $24, $2 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci zap $1, $2, $1 7862306a36Sopenharmony_ci stq_u $1, 0($16) 7962306a36Sopenharmony_ci$zerolen: 8062306a36Sopenharmony_ci ret 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci .end strncpy 8362306a36Sopenharmony_ci EXPORT_SYMBOL(strncpy) 84