18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * arch/alpha/lib/strncpy.S 48c2ecf20Sopenharmony_ci * Contributed by Richard Henderson (rth@tamu.edu) 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copy no more than COUNT bytes of the null-terminated string from 78c2ecf20Sopenharmony_ci * SRC to DST. If SRC does not cover all of COUNT, the balance is 88c2ecf20Sopenharmony_ci * zeroed. 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * Or, rather, if the kernel cared about that weird ANSI quirk. This 118c2ecf20Sopenharmony_ci * version has cropped that bit o' nastiness as well as assuming that 128c2ecf20Sopenharmony_ci * __stxncpy is in range of a branch. 138c2ecf20Sopenharmony_ci */ 148c2ecf20Sopenharmony_ci#include <asm/export.h> 158c2ecf20Sopenharmony_ci .set noat 168c2ecf20Sopenharmony_ci .set noreorder 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci .text 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci .align 4 218c2ecf20Sopenharmony_ci .globl strncpy 228c2ecf20Sopenharmony_ci .ent strncpy 238c2ecf20Sopenharmony_cistrncpy: 248c2ecf20Sopenharmony_ci .frame $30, 0, $26 258c2ecf20Sopenharmony_ci .prologue 0 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci mov $16, $0 # set return value now 288c2ecf20Sopenharmony_ci beq $18, $zerolen 298c2ecf20Sopenharmony_ci unop 308c2ecf20Sopenharmony_ci bsr $23, __stxncpy # do the work of the copy 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci unop 338c2ecf20Sopenharmony_ci bne $18, $multiword # do we have full words left? 348c2ecf20Sopenharmony_ci subq $24, 1, $3 # nope 358c2ecf20Sopenharmony_ci subq $27, 1, $4 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci or $3, $24, $3 # clear the bits between the last 388c2ecf20Sopenharmony_ci or $4, $27, $4 # written byte and the last byte in COUNT 398c2ecf20Sopenharmony_ci andnot $3, $4, $4 408c2ecf20Sopenharmony_ci zap $1, $4, $1 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci stq_u $1, 0($16) 438c2ecf20Sopenharmony_ci ret 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci .align 4 468c2ecf20Sopenharmony_ci$multiword: 478c2ecf20Sopenharmony_ci subq $27, 1, $2 # clear the final bits in the prev word 488c2ecf20Sopenharmony_ci or $2, $27, $2 498c2ecf20Sopenharmony_ci zapnot $1, $2, $1 508c2ecf20Sopenharmony_ci subq $18, 1, $18 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci stq_u $1, 0($16) 538c2ecf20Sopenharmony_ci addq $16, 8, $16 548c2ecf20Sopenharmony_ci unop 558c2ecf20Sopenharmony_ci beq $18, 1f 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci nop 588c2ecf20Sopenharmony_ci unop 598c2ecf20Sopenharmony_ci nop 608c2ecf20Sopenharmony_ci blbc $18, 0f 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci stq_u $31, 0($16) # zero one word 638c2ecf20Sopenharmony_ci subq $18, 1, $18 648c2ecf20Sopenharmony_ci addq $16, 8, $16 658c2ecf20Sopenharmony_ci beq $18, 1f 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci0: stq_u $31, 0($16) # zero two words 688c2ecf20Sopenharmony_ci subq $18, 2, $18 698c2ecf20Sopenharmony_ci stq_u $31, 8($16) 708c2ecf20Sopenharmony_ci addq $16, 16, $16 718c2ecf20Sopenharmony_ci bne $18, 0b 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci1: ldq_u $1, 0($16) # clear the leading bits in the final word 748c2ecf20Sopenharmony_ci subq $24, 1, $2 758c2ecf20Sopenharmony_ci or $2, $24, $2 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci zap $1, $2, $1 788c2ecf20Sopenharmony_ci stq_u $1, 0($16) 798c2ecf20Sopenharmony_ci$zerolen: 808c2ecf20Sopenharmony_ci ret 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci .end strncpy 838c2ecf20Sopenharmony_ci EXPORT_SYMBOL(strncpy) 84