1/* strncpy - copy at most n characters from a string from source to
2   destination.  For IBM S390
3   This file is part of the GNU C Library.
4   Copyright (C) 2000-2022 Free Software Foundation, Inc.
5
6   The GNU C Library is free software; you can redistribute it and/or
7   modify it under the terms of the GNU Lesser General Public
8   License as published by the Free Software Foundation; either
9   version 2.1 of the License, or (at your option) any later version.
10
11   The GNU C Library is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   Lesser General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with the GNU C Library; if not, see
18   <https://www.gnu.org/licenses/>.  */
19
20/*
21 * R2 = address of destination (dst)
22 * R3 = address of source (src)
23 * R4 = max of bytes to copy
24 */
25
26#include <ifunc-strncpy.h>
27#include "sysdep.h"
28#include "asm-syntax.h"
29
30#if HAVE_STRNCPY_Z900_G5
31ENTRY(STRNCPY_Z900_G5)
32	.text
33	st    %r2,24(%r15)          # save dst pointer
34	slr   %r2,%r3               # %r3 points to src, %r2+%r3 to dst
35	lhi   %r1,3
36	nr    %r1,%r4               # last 2 bits of # bytes
37	srl   %r4,2
38	ltr   %r4,%r4               # less than 4 bytes to copy ?
39	jz    .L1
40	bras  %r5,.L0               # enter loop & load address of a 0
41	.long 0
42.L0:    icm   %r0,8,0(%r3)          # first byte
43	jz    .L3
44	icm   %r0,4,1(%r3)          # second byte
45	jz    .L4
46	icm   %r0,2,2(%r3)          # third byte
47	jz    .L5
48	icm   %r0,1,3(%r3)          # fourth byte
49	jz    .L6
50	st    %r0,0(%r2,%r3)        # store all four to dest.
51	la    %r3,4(%r3)
52	brct  %r4,.L0
53.L1:    ltr   %r1,%r1
54	jz    .Lexit
55.L2:    icm   %r0,1,0(%r3)
56	stc   %r0,0(%r2,%r3)
57	la    %r3,1(%r3)
58	jz    .L7
59	brct  %r1,.L2
60	j     .Lexit
61.L3:    icm   %r0,4,0(%r5)
62.L4:    icm   %r0,2,0(%r5)
63.L5:    icm   %r0,1,0(%r5)
64.L6:    st    %r0,0(%r2,%r3)
65	la    %r3,4(%r3)
66	ahi   %r4,-1
67	j     .L8
68.L7:    ahi   %r1,-1
69.L8:    sll   %r4,2
70	alr   %r4,%r1
71	alr   %r2,%r3               # start of dst area to be zeroed
72	lr    %r3,%r4
73	slr   %r4,%r4
74	slr   %r5,%r5
75.L9:    mvcle %r2,%r4,0             # pad dst with zeroes
76	jo    .L9
77.Lexit: l     %r2,24(%r15)          # return dst pointer
78	br    %r14
79END(STRNCPY_Z900_G5)
80
81# if ! HAVE_STRNCPY_IFUNC
82strong_alias (STRNCPY_Z900_G5, strncpy)
83# endif
84
85# if defined SHARED && IS_IN (libc)
86strong_alias (STRNCPY_Z900_G5, __GI_strncpy)
87# endif
88#endif
89