Skip to content

Commit 7d40baf

Browse files
iii-ifneddy
authored andcommitted
s390x: vectorize crc32
Use vector extensions when compiling for s390x and binutils knows about them. At runtime, check whether kernel supports vector extensions (it has to be not just the CPU, but also the kernel) and choose between the regular and the vectorized implementations.
1 parent 5a82f71 commit 7d40baf

File tree

8 files changed

+492
-76
lines changed

8 files changed

+492
-76
lines changed

CMakeLists.txt

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ option(ZLIB_BUILD_MINIZIP "Enable building libminizip contrib library" OFF)
2626
option(ZLIB_INSTALL "Enable installation of zlib" ON)
2727
option(ZLIB_PREFIX "prefix for all types and library functions, see zconf.h.in"
2828
OFF)
29+
option(CRC32VX "Enable building S390-CRC32VX implementation" ON)
2930
mark_as_advanced(ZLIB_PREFIX)
3031

3132
if(WIN32)
@@ -120,6 +121,56 @@ set(ZLIB_PC ${zlib_BINARY_DIR}/zlib.pc)
120121
configure_file(${zlib_SOURCE_DIR}/zlib.pc.cmakein ${ZLIB_PC} @ONLY)
121122
configure_file(${zlib_BINARY_DIR}/zconf.h.cmakein ${zlib_BINARY_DIR}/zconf.h)
122123

124+
#
125+
# Check for IBM S390X extensions
126+
#
127+
if(CRC32VX)
128+
129+
# preset the compiler specific flags
130+
if (CMAKE_C_COMPILER_ID STREQUAL "Clang")
131+
set(VGFMAFLAG "-fzvector")
132+
else()
133+
set(VGFMAFLAG "-mzarch")
134+
endif()
135+
136+
set(S390X_VX_TEST
137+
"#ifndef __s390x__ \n\
138+
#error \n\
139+
#endif \n\
140+
#include <vecintrin.h> \n\
141+
int main(void) { \
142+
unsigned long long a __attribute__((vector_size(16))) = { 0 }; \
143+
unsigned long long b __attribute__((vector_size(16))) = { 0 }; \
144+
unsigned char c __attribute__((vector_size(16))) = { 0 }; \
145+
c = vec_gfmsum_accum_128(a, b, c); \
146+
return c[0]; \
147+
}")
148+
149+
# cflags already contains a valid march
150+
set(CMAKE_REQUIRED_FLAGS "${VGFMAFLAG}")
151+
check_c_source_compiles("${S390X_VX_TEST}" HAS_S390X_VX_SUPPORT)
152+
set(CMAKE_REQUIRED_FLAGS)
153+
154+
# or set march for our compile units
155+
if(NOT HAS_S390X_VX_SUPPORT)
156+
set(CMAKE_REQUIRED_FLAGS "${VGFMAFLAG} -march=z13")
157+
check_c_source_compiles("${S390X_VX_TEST}" HAS_Z13_S390X_VX_SUPPORT)
158+
set(CMAKE_REQUIRED_FLAGS )
159+
list(APPEND VGFMAFLAG "-march=z13")
160+
endif()
161+
162+
# prepare compiling for s390x
163+
if(HAS_S390X_VX_SUPPORT OR HAS_Z13_S390X_VX_SUPPORT)
164+
set(S390X_SRCS
165+
contrib/s390x/s390x-functable.c
166+
contrib/s390x/crc32-vx.c)
167+
set_source_files_properties(
168+
contrib/s390x/crc32-vx.c
169+
PROPERTIES COMPILE_OPTIONS "${VGFMAFLAG}")
170+
add_definitions(-DHAVE_S390X_VX)
171+
endif()
172+
endif()
173+
123174
# ============================================================================
124175
# zlib
125176
# ============================================================================
@@ -152,7 +203,8 @@ set(ZLIB_SRCS
152203
inffast.c
153204
trees.c
154205
uncompr.c
155-
zutil.c)
206+
zutil.c
207+
${S390X_SRCS})
156208

157209
if(WIN32)
158210
set(zlib_static_suffix "s")

Makefile.in

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ LDFLAGS=
2727
TEST_LIBS=-L. libz.a
2828
LDSHARED=$(CC)
2929
CPP=$(CC) -E
30+
VGFMAFLAG=
3031

3132
STATICLIB=libz.a
3233
SHAREDLIB=libz.so
@@ -164,6 +165,12 @@ adler32.o: $(SRCDIR)adler32.c
164165
crc32.o: $(SRCDIR)crc32.c
165166
$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)crc32.c
166167

168+
crc32-vx.o: $(SRCDIR)contrib/s390x/crc32-vx.c
169+
$(CC) $(CFLAGS) $(VGFMAFLAG) $(ZINC) -c -o $@ $(SRCDIR)contrib/s390x/crc32-vx.c
170+
171+
s390x-functable.o: $(SRCDIR)contrib/s390x/s390x-functable.c
172+
$(CC) $(CFLAGS) $(VGFMAFLAG) $(ZINC) -c -o $@ $(SRCDIR)contrib/s390x/s390x-functable.c
173+
167174
deflate.o: $(SRCDIR)deflate.c
168175
$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)deflate.c
169176

@@ -214,6 +221,16 @@ crc32.lo: $(SRCDIR)crc32.c
214221
$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/crc32.o $(SRCDIR)crc32.c
215222
-@mv objs/crc32.o $@
216223

224+
crc32-vx.lo: $(SRCDIR)contrib/s390x/crc32-vx.c
225+
-@mkdir objs 2>/dev/null || test -d objs
226+
$(CC) $(SFLAGS) $(VGFMAFLAG) $(ZINC) -DPIC -c -o objs/crc32-vx.o $(SRCDIR)contrib/s390x/crc32-vx.c
227+
-@mv objs/crc32-vx.o $@
228+
229+
s390x-functable.lo: $(SRCDIR)contrib/s390x/s390x-functable.c
230+
-@mkdir objs 2>/dev/null || test -d objs
231+
$(CC) $(SFLAGS) $(VGFMAFLAG) $(ZINC) -DPIC -c -o objs/s390x-functable.o $(SRCDIR)contrib/s390x/s390x-functable.c
232+
-@mv objs/s390x-functable.o $@
233+
217234
deflate.lo: $(SRCDIR)deflate.c
218235
-@mkdir objs 2>/dev/null || test -d objs
219236
$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/deflate.o $(SRCDIR)deflate.c

configure

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,55 @@ EOF
870870
fi
871871
fi
872872

873+
# check for ibm s390x build
874+
HAVE_S390X=0
875+
876+
# preset the compiler specific flags
877+
if test $clang -eq 1; then
878+
VGFMAFLAG=-fzvector
879+
else
880+
VGFMAFLAG=-mzarch
881+
fi
882+
883+
cat > $test.c <<EOF
884+
#ifndef __s390x__
885+
#error
886+
#endif
887+
#include <vecintrin.h>
888+
int main(void) {
889+
unsigned long long a __attribute__((vector_size(16))) = { 0 };
890+
unsigned long long b __attribute__((vector_size(16))) = { 0 };
891+
unsigned char c __attribute__((vector_size(16))) = { 0 };
892+
c = vec_gfmsum_accum_128(a, b, c);
893+
return c[0];
894+
}
895+
EOF
896+
897+
# cflags already contains a valid march
898+
if try $CC -c $CFLAGS $VGFMAFLAG $test.c; then
899+
echo "Checking for s390x build ... Yes." | tee -a configure.log
900+
HAVE_S390X=1
901+
# or set march for our compile units
902+
elif try $CC -c $CFLAGS $VGFMAFLAG -march=z13 $test.c; then
903+
echo "Checking for s390x build (march=z13) ... Yes." | tee -a configure.log
904+
HAVE_S390X=1
905+
VGFMAFLAG="$VGFMAFLAG -march=z13"
906+
# else we are not on s390x
907+
else
908+
echo "Checking for s390x build ... No." | tee -a configure.log
909+
fi
910+
911+
# prepare compiling for s390x
912+
if test $HAVE_S390X -eq 1; then
913+
CFLAGS="$CFLAGS -DHAVE_S390X_VX"
914+
SFLAGS="$SFLAGS -DHAVE_S390X_VX"
915+
OBJC="$OBJC crc32-vx.o s390x-functable.o"
916+
PIC_OBJC="$PIC_OBJC crc32-vx.lo s390x-functable.lo"
917+
else
918+
# this is not a s390x build
919+
VGFMAFLAG=""
920+
fi
921+
873922
# show the results in the log
874923
echo >> configure.log
875924
echo ALL = $ALL >> configure.log
@@ -901,6 +950,8 @@ echo mandir = $mandir >> configure.log
901950
echo prefix = $prefix >> configure.log
902951
echo sharedlibdir = $sharedlibdir >> configure.log
903952
echo uname = $uname >> configure.log
953+
echo HAVE_S390X = $HAVE_S390X >> configure.log
954+
echo VGFMAFLAG = $VGFMAFLAG >> configure.log
904955

905956
# update Makefile with the configure results
906957
sed < ${SRCDIR}Makefile.in "
@@ -912,6 +963,7 @@ sed < ${SRCDIR}Makefile.in "
912963
/^LDFLAGS *=/s#=.*#=$LDFLAGS#
913964
/^LDSHARED *=/s#=.*#=$LDSHARED#
914965
/^CPP *=/s#=.*#=$CPP#
966+
/^VGFMAFLAG *=/s#=.*#=$VGFMAFLAG#
915967
/^STATICLIB *=/s#=.*#=$STATICLIB#
916968
/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
917969
/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#

contrib/functable/functable.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#ifndef Z_FUNCTABLE_H__
2+
#define Z_FUNCTABLE_H__
3+
4+
#include "../../zutil.h"
5+
#include "../../zonce.h"
6+
7+
unsigned long ZLIB_INTERNAL s390_crc32_vx(unsigned long crc, const unsigned char FAR *buf,
8+
z_size_t len);
9+
10+
struct zfunctable_s {
11+
unsigned long hwcap;
12+
unsigned long (*crc32_z)(unsigned long crc, const unsigned char FAR *buf,
13+
z_size_t len);
14+
/* int (*deflate)(z_streamp strm, int flush); */
15+
/* int (*inflate)(z_streamp strm, int flush); */
16+
};
17+
18+
extern struct zfunctable_s ZLIB_INTERNAL arch_functable;
19+
extern once_t ZLIB_INTERNAL arch_functable_init_done;
20+
/* to be implemented by architecture specific code */
21+
void ZLIB_INTERNAL arch_functable_init(void);
22+
23+
#endif

0 commit comments

Comments
 (0)