1/* memcmp - compare two memory blocks.  31/64 bit S/390 version.
2   Copyright (C) 2012-2021 Free Software Foundation, Inc.
3   This file is part of the GNU C Library.
4
5   The GNU C Library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9
10   The GNU C Library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14
15   You should have received a copy of the GNU Lesser General Public
16   License along with the GNU C Library; if not, see
17   <https://www.gnu.org/licenses/>.  */
18
19
20#include <sysdep.h>
21#include "asm-syntax.h"
22#include <ifunc-memcmp.h>
23
24/* INPUT PARAMETERS
25     %r2 = address of first memory area
26     %r3 = address of second memory area
27     %r4 = number of bytes to compare.  */
28
29       .text
30
31#if HAVE_MEMCMP_Z900_G5
32# if defined __s390x__
33#  define LTGR	ltgr
34#  define AGHI	aghi
35#  define BRCTG	brctg
36# else
37#  define LTGR	ltr
38#  define AGHI	ahi
39#  define BRCTG	brct
40# endif /* ! defined __s390x__  */
41ENTRY(MEMCMP_Z900_G5)
42# if defined __s390x__
43	.machine "z900"
44# else
45	.machine "g5"
46	basr    %r5,0
47.L_Z900_G5_16:
48#  define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_16
49# endif /* ! defined __s390x__  */
50	LTGR    %r4,%r4
51	je      .L_Z900_G5_4
52	AGHI    %r4,-1
53# if defined __s390x__
54	srlg    %r1,%r4,8
55	larl    %r5,.L_Z900_G5_15
56#  define Z900_G5_EX_D 0
57# else
58	lr	%r1,%r4
59	srl	%r1,8
60# endif /* ! defined __s390x__  */
61	LTGR    %r1,%r1
62	jne     .L_Z900_G5_12
63.L_Z900_G5_3:
64	ex      %r4,Z900_G5_EX_D(%r5)
65.L_Z900_G5_4:
66	ipm     %r2
67# if defined __s390x__
68	sllg    %r2,%r2,34
69	srag    %r2,%r2,62
70# else
71	sll     %r2,2
72	sra     %r2,30
73# endif /* ! defined __s390x__  */
74	br      %r14
75.L_Z900_G5_12:
76	clc     0(256,%r3),0(%r2)
77	jne     .L_Z900_G5_4
78	la      %r3,256(%r3)
79	la      %r2,256(%r2)
80	BRCTG   %r1,.L_Z900_G5_12
81	j       .L_Z900_G5_3
82.L_Z900_G5_15:
83	clc     0(1,%r3),0(%r2)
84END(MEMCMP_Z900_G5)
85# undef LTGR
86# undef AGHI
87# undef BRCTG
88#endif /* HAVE_MEMCMP_Z900_G5  */
89
90#if HAVE_MEMCMP_Z10
91ENTRY(MEMCMP_Z10)
92	.machine "z10"
93	.machinemode "zarch_nohighgprs"
94# if !defined __s390x__
95	llgfr	%r4,%r4
96# endif /* !defined __s390x__  */
97	ltgr    %r4,%r4
98	je      .L_Z10_4
99	aghi    %r4,-1
100	srlg    %r1,%r4,8
101	cgijlh  %r1,0,.L_Z10_12
102.L_Z10_3:
103	exrl    %r4,.L_Z10_15
104.L_Z10_4:
105	ipm     %r2
106	sllg    %r2,%r2,34
107	srag    %r2,%r2,62
108	br      %r14
109.L_Z10_12:
110	pfd     1,512(%r3)
111	pfd     1,512(%r2)
112	clc     0(256,%r3),0(%r2)
113	jne     .L_Z10_4
114	la      %r3,256(%r3)
115	la      %r2,256(%r2)
116	brctg   %r1,.L_Z10_12
117	j       .L_Z10_3
118.L_Z10_15:
119	clc     0(1,%r3),0(%r2)
120END(MEMCMP_Z10)
121#endif /* HAVE_MEMCMP_Z10  */
122
123#if HAVE_MEMCMP_Z196
124ENTRY(MEMCMP_Z196)
125	.machine "z196"
126	.machinemode "zarch_nohighgprs"
127# if !defined __s390x__
128	llgfr	%r4,%r4
129# endif /* !defined __s390x__  */
130	ltgr    %r4,%r4
131	je      .L_Z196_4
132	aghi    %r4,-1
133	srlg    %r1,%r4,8
134	ltgr    %r1,%r1
135	jne     .L_Z196_2
136.L_Z196_3:
137	exrl    %r4,.L_Z196_14
138.L_Z196_4:
139	ipm     %r2
140	sllg    %r2,%r2,34
141	srag    %r2,%r2,62
142	br      %r14
143.L_Z196_17:
144	la      %r3,256(%r3)
145	la      %r2,256(%r2)
146	aghi    %r1,-1
147	je      .L_Z196_3
148.L_Z196_2:
149	pfd     1,512(%r3)
150	pfd     1,512(%r2)
151	clc     0(256,%r3),0(%r2)
152	je      .L_Z196_17
153	ipm     %r2
154	sllg    %r2,%r2,34
155	srag    %r2,%r2,62
156	br      %r14
157.L_Z196_14:
158	clc     0(1,%r3),0(%r2)
159END(MEMCMP_Z196)
160#endif /* HAVE_MEMCMP_Z196  */
161
162#if ! HAVE_MEMCMP_IFUNC
163/* If we don't use ifunc, define an alias for memcmp here.
164   Otherwise see sysdeps/s390/memcmp.c.  */
165strong_alias (MEMCMP_DEFAULT, memcmp)
166weak_alias (memcmp, bcmp)
167strong_alias (memcmp, __memcmpeq)
168libc_hidden_def (__memcmpeq)
169#endif
170
171#if defined SHARED && IS_IN (libc)
172/* Defines the internal symbols.
173   Compare to libc_hidden_builtin_def (memcmp) in string/memcmp.c.  */
174strong_alias (MEMCMP_DEFAULT, __GI_memcmp)
175#endif
176