1# Makefile fragment - requires GNU make 2# 3# Copyright (c) 2019-2024, Arm Limited. 4# SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception 5 6.SECONDEXPANSION: 7 8ifneq ($(OS),Linux) 9 ifeq ($(WANT_SIMD_EXCEPT),1) 10 $(error WANT_SIMD_EXCEPT is not supported outside Linux) 11 endif 12 ifneq ($(USE_MPFR),1) 13 $(warning WARNING: Double-precision ULP tests will not be usable without MPFR) 14 endif 15 ifeq ($(USE_GLIBC_ABI),1) 16 $(error Can only generate special GLIBC symbols on Linux - please disable USE_GLIBC_ABI) 17 endif 18endif 19 20ifneq ($(ARCH),aarch64) 21 ifeq ($(WANT_TRIGPI_TESTS),1) 22 $(error trigpi functions only supported on aarch64) 23 endif 24 ifeq ($(WANT_EXPERIMENTAL_MATH),1) 25 $(error Experimental math only supported on aarch64) 26 endif 27endif 28 29math-src-dir := $(srcdir)/math 30math-build-dir := build/math 31 32math-lib-srcs := $(wildcard $(math-src-dir)/*.[cS]) 33math-lib-srcs += $(wildcard $(math-src-dir)/$(ARCH)/*.[cS]) 34ifeq ($(OS),Linux) 35# Vector symbols only supported on Linux 36math-lib-srcs += $(wildcard $(math-src-dir)/$(ARCH)/*/*.[cS]) 37endif 38 39ifeq ($(WANT_EXPERIMENTAL_MATH), 1) 40ifeq ($(OS),Linux) 41# Vector symbols only supported on Linux 42math-lib-srcs += $(wildcard $(math-src-dir)/$(ARCH)/experimental/*/*.[cS]) 43else 44math-lib-srcs += $(wildcard $(math-src-dir)/$(ARCH)/experimental/*.[cS]) 45endif 46else 47# Scalar experimental symbols will have been added by wildcard, so remove them 48math-lib-srcs := $(filter-out $(math-src-dir)/aarch64/experimental/%, $(math-lib-srcs)) 49endif 50 51math-test-srcs := \ 52 $(math-src-dir)/test/mathtest.c \ 53 $(math-src-dir)/test/mathbench.c \ 54 $(math-src-dir)/test/ulp.c \ 55 56math-test-host-srcs := $(wildcard $(math-src-dir)/test/rtest/*.[cS]) 57 58math-includes := $(patsubst $(math-src-dir)/%,build/%,$(wildcard $(math-src-dir)/include/*.h)) 59 60math-libs := \ 61 build/lib/libmathlib.so \ 62 build/lib/libmathlib.a \ 63 64math-tools := \ 65 build/bin/mathtest \ 66 build/bin/mathbench \ 67 build/bin/mathbench_libc \ 68 build/bin/runulp.sh \ 69 build/bin/ulp \ 70 71math-host-tools := \ 72 build/bin/rtest \ 73 74math-lib-objs := $(patsubst $(math-src-dir)/%,$(math-build-dir)/%.o,$(basename $(math-lib-srcs))) 75math-test-objs := $(patsubst $(math-src-dir)/%,$(math-build-dir)/%.o,$(basename $(math-test-srcs))) 76math-host-objs := $(patsubst $(math-src-dir)/%,$(math-build-dir)/%.o,$(basename $(math-test-host-srcs))) 77math-target-objs := $(math-lib-objs) $(math-test-objs) 78math-objs := $(math-target-objs) $(math-target-objs:%.o=%.os) $(math-host-objs) 79 80math-files := \ 81 $(math-objs) \ 82 $(math-libs) \ 83 $(math-tools) \ 84 $(math-host-tools) \ 85 $(math-includes) 86 87all-math: $(math-libs) $(math-tools) $(math-includes) 88 89$(math-objs): $(math-includes) 90$(math-objs): CFLAGS_ALL += $(math-cflags) 91$(math-build-dir)/test/mathtest.o: CFLAGS_ALL += -fmath-errno 92$(math-host-objs): CC = $(HOST_CC) 93$(math-host-objs): CFLAGS_ALL = $(HOST_CFLAGS) 94 95# Add include path for experimental routines so they can share helpers with non-experimental 96$(math-build-dir)/aarch64/experimental/advsimd/%: CFLAGS_ALL += -I$(math-src-dir)/aarch64/advsimd 97$(math-build-dir)/aarch64/experimental/sve/%: CFLAGS_ALL += -I$(math-src-dir)/aarch64/sve 98 99$(math-objs): CFLAGS_ALL += -I$(math-src-dir) 100 101ulp-funcs-dir = build/test/ulp-funcs/ 102ulp-wrappers-dir = build/test/ulp-wrappers/ 103mathbench-funcs-dir = build/test/mathbench-funcs/ 104test-sig-dirs = $(ulp-funcs-dir) $(ulp-wrappers-dir) $(mathbench-funcs-dir) 105build/include/test $(test-sig-dirs) $(addsuffix /$(ARCH),$(test-sig-dirs)) $(addsuffix /aarch64/experimental,$(test-sig-dirs)) \ 106$(addsuffix /aarch64/experimental/advsimd,$(test-sig-dirs)) $(addsuffix /aarch64/experimental/sve,$(test-sig-dirs)) \ 107$(addsuffix /aarch64/advsimd,$(test-sig-dirs)) $(addsuffix /aarch64/sve,$(test-sig-dirs)): 108 mkdir -p $@ 109 110ulp-funcs = $(patsubst $(math-src-dir)/%,$(ulp-funcs-dir)/%,$(basename $(math-lib-srcs))) 111ulp-wrappers = $(patsubst $(math-src-dir)/%,$(ulp-wrappers-dir)/%,$(basename $(math-lib-srcs))) 112mathbench-funcs = $(patsubst $(math-src-dir)/%,$(mathbench-funcs-dir)/%,$(basename $(math-lib-srcs))) 113 114ifeq ($(WANT_SVE_TESTS), 0) 115 # Filter out anything with sve in the path 116 ulp-funcs := $(foreach a,$(ulp-funcs),$(if $(findstring sve,$a),,$a)) 117 ulp-wrappers := $(foreach a,$(ulp-wrappers),$(if $(findstring sve,$a),,$a)) 118 mathbench-funcs := $(foreach a,$(mathbench-funcs),$(if $(findstring sve,$a),,$a)) 119endif 120 121define emit_sig 122$1/aarch64/experimental/sve/%.i: EXTRA_INC = -I$(math-src-dir)/aarch64/sve 123$1/aarch64/experimental/advsimd/%.i: EXTRA_INC = -I$(math-src-dir)/aarch64/advsimd 124$1/%.i: $(math-src-dir)/%.c | $$$$(@D) 125 $(CC) $$< $(math-cflags) -I$(math-src-dir)/include -I$(math-src-dir) $$(EXTRA_INC) -D$2 -E -o $$@ 126$1/%: $1/%.i 127 { grep TEST_SIG $$< || true; } | cut -f 2- -d ' ' > $$@ 128endef 129 130$(eval $(call emit_sig,$(ulp-funcs-dir),EMIT_ULP_FUNCS)) 131$(eval $(call emit_sig,$(ulp-wrappers-dir),EMIT_ULP_WRAPPERS)) 132$(eval $(call emit_sig,$(mathbench-funcs-dir),EMIT_MATHBENCH_FUNCS)) 133 134ulp-funcs-gen = build/include/test/ulp_funcs_gen.h 135ulp-wrappers-gen = build/include/test/ulp_wrappers_gen.h 136mathbench-funcs-gen = build/include/test/mathbench_funcs_gen.h 137math-tools-autogen-headers = $(ulp-funcs-gen) $(ulp-wrappers-gen) $(mathbench-funcs-gen) 138 139$(ulp-funcs-gen): $(ulp-funcs) | $$(@D) 140$(ulp-wrappers-gen): $(ulp-wrappers) | $$(@D) 141$(mathbench-funcs-gen): $(mathbench-funcs) | $$(@D) 142 143$(math-tools-autogen-headers): | $$(@D) 144 cat $^ | sort -u > $@ 145 146$(math-build-dir)/test/mathbench.o: $(mathbench-funcs-gen) 147$(math-build-dir)/test/ulp.o: $(math-src-dir)/test/ulp.h $(ulp-funcs-gen) $(ulp-wrappers-gen) 148 149build/lib/libmathlib.so: $(math-lib-objs:%.o=%.os) 150 $(CC) $(CFLAGS_ALL) $(LDFLAGS) -shared -o $@ $^ 151 152build/lib/libmathlib.a: $(math-lib-objs) 153 rm -f $@ 154 $(AR) rc $@ $^ 155 $(RANLIB) $@ 156 157$(math-host-tools): HOST_LDLIBS += $(libm-libs) $(mpfr-libs) $(mpc-libs) 158$(math-tools): LDLIBS += $(math-ldlibs) $(libm-libs) 159 160ifneq ($(OS),Darwin) 161 $(math-tools): LDFLAGS += -static 162endif 163 164build/bin/rtest: $(math-host-objs) 165 $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ $^ $(HOST_LDLIBS) 166 167build/bin/mathtest: $(math-build-dir)/test/mathtest.o build/lib/libmathlib.a 168 $(CC) $(CFLAGS_ALL) $(LDFLAGS) -o $@ $^ $(libm-libs) 169 170build/bin/mathbench: $(math-build-dir)/test/mathbench.o build/lib/libmathlib.a 171 $(CC) $(CFLAGS_ALL) $(LDFLAGS) -o $@ $^ $(libm-libs) 172 173# This is not ideal, but allows custom symbols in mathbench to get resolved. 174build/bin/mathbench_libc: $(math-build-dir)/test/mathbench.o build/lib/libmathlib.a 175 $(CC) $(CFLAGS_ALL) $(LDFLAGS) -o $@ $< $(libm-libs) $(libc-libs) build/lib/libmathlib.a $(libm-libs) 176 177build/bin/ulp: $(math-build-dir)/test/ulp.o build/lib/libmathlib.a 178 $(CC) $(CFLAGS_ALL) $(LDFLAGS) -o $@ $^ $(LDLIBS) 179 180build/include/%.h: $(math-src-dir)/include/%.h 181 cp $< $@ 182 183build/bin/%.sh: $(math-src-dir)/test/%.sh 184 cp $< $@ 185 186math-tests := $(wildcard $(math-src-dir)/test/testcases/directed/*.tst) 187ifneq ($(WANT_EXP10_TESTS),1) 188math-tests := $(filter-out %exp10.tst, $(math-tests)) 189endif 190math-rtests := $(wildcard $(math-src-dir)/test/testcases/random/*.tst) 191 192check-math-test: $(math-tools) 193 cat $(math-tests) | $(EMULATOR) build/bin/mathtest $(math-testflags) 194 195check-math-rtest: $(math-host-tools) $(math-tools) 196 cat $(math-rtests) | build/bin/rtest | $(EMULATOR) build/bin/mathtest $(math-testflags) 197 198ulp-input-dir = $(math-build-dir)/test/inputs 199$(ulp-input-dir) $(ulp-input-dir)/$(ARCH) $(ulp-input-dir)/aarch64/sve $(ulp-input-dir)/aarch64/advsimd \ 200$(ulp-input-dir)/aarch64/experimental $(ulp-input-dir)/aarch64/experimental/advsimd $(ulp-input-dir)/aarch64/experimental/sve: 201 mkdir -p $@ 202 203math-lib-lims = $(patsubst $(math-src-dir)/%.c,$(ulp-input-dir)/%.ulp,$(math-lib-srcs)) 204math-lib-lims-nn = $(patsubst $(math-src-dir)/%.c,$(ulp-input-dir)/%.ulp_nn,$(math-lib-srcs)) 205math-lib-fenvs = $(patsubst $(math-src-dir)/%.c,$(ulp-input-dir)/%.fenv,$(math-lib-srcs)) 206math-lib-itvs = $(patsubst $(math-src-dir)/%.c,$(ulp-input-dir)/%.itv,$(math-lib-srcs)) 207math-lib-cvals = $(patsubst $(math-src-dir)/%.c,$(ulp-input-dir)/%.cval,$(math-lib-srcs)) 208 209ulp-inputs = $(math-lib-lims) $(math-lib-lims-nn) $(math-lib-fenvs) $(math-lib-itvs) $(math-lib-cvals) 210$(ulp-inputs): CFLAGS = -I$(math-src-dir)/test -I$(math-src-dir)/include -I$(math-src-dir) $(math-cflags)\ 211 -I$(math-src-dir)/aarch64/advsimd -I$(math-src-dir)/aarch64/sve 212 213$(ulp-input-dir)/%.ulp.i: $(math-src-dir)/%.c | $$(@D) 214 $(CC) $(CFLAGS) $< -E -o $@ 215 216$(ulp-input-dir)/%.ulp: $(ulp-input-dir)/%.ulp.i 217 { grep "TEST_ULP " $< || true; } > $@ 218 219$(ulp-input-dir)/%.ulp_nn.i: $(math-src-dir)/%.c | $$(@D) 220 $(CC) $(CFLAGS) $< -E -o $@ 221 222$(ulp-input-dir)/%.ulp_nn: $(ulp-input-dir)/%.ulp_nn.i 223 { grep "TEST_ULP_NONNEAREST " $< || true; } > $@ 224 225$(ulp-input-dir)/%.fenv.i: $(math-src-dir)/%.c | $$(@D) 226 $(CC) $(CFLAGS) $< -E -o $@ 227 228$(ulp-input-dir)/%.fenv: $(ulp-input-dir)/%.fenv.i 229 { grep "TEST_DISABLE_FENV " $< || true; } > $@ 230 231$(ulp-input-dir)/%.itv.i: $(math-src-dir)/%.c | $$(@D) 232 $(CC) $(CFLAGS) $< -E -o $@ 233 234$(ulp-input-dir)/%.itv: $(ulp-input-dir)/%.itv.i 235 { grep "TEST_INTERVAL " $< || true; } | sed "s/ TEST_INTERVAL/\nTEST_INTERVAL/g" > $@ 236 237$(ulp-input-dir)/%.cval.i: $(math-src-dir)/%.c | $$(@D) 238 $(CC) $(CFLAGS) $< -E -o $@ 239 240$(ulp-input-dir)/%.cval: $(ulp-input-dir)/%.cval.i 241 { grep "TEST_CONTROL_VALUE " $< || true; } > $@ 242 243ulp-lims = $(ulp-input-dir)/limits 244$(ulp-lims): $(math-lib-lims) 245 246ulp-lims-nn = $(ulp-input-dir)/limits_nn 247$(ulp-lims-nn): $(math-lib-lims-nn) 248 249fenv-exps := $(ulp-input-dir)/fenv 250$(fenv-exps): $(math-lib-fenvs) 251 252generic-itvs = $(ulp-input-dir)/itvs 253$(generic-itvs): $(filter-out $(ulp-input-dir)/$(ARCH)/%,$(math-lib-itvs)) 254 255arch-itvs = $(ulp-input-dir)/$(ARCH)/itvs 256$(arch-itvs): $(filter $(ulp-input-dir)/$(ARCH)/%,$(math-lib-itvs)) 257 258ulp-cvals := $(ulp-input-dir)/cvals 259$(ulp-cvals): $(math-lib-cvals) 260 261# Remove first word, which will be TEST directive 262$(ulp-lims) $(ulp-lims-nn) $(fenv-exps) $(arch-itvs) $(generic-itvs) $(ulp-cvals): | $$(@D) 263 sed "s/TEST_[^ ]* //g" $^ | sort -u > $@ 264 265check-math-ulp: $(ulp-lims) $(ulp-lims-nn) 266check-math-ulp: $(fenv-exps) $(ulp-cvals) 267check-math-ulp: $(generic-itvs) $(arch-itvs) 268check-math-ulp: $(math-tools) 269 ULPFLAGS="$(math-ulpflags)" \ 270 LIMITS=../../$(ulp-lims) \ 271 ARCH_ITVS=../../$(arch-itvs) \ 272 GEN_ITVS=../../$(generic-itvs) \ 273 DISABLE_FENV=../../$(fenv-exps) \ 274 CVALS=../../$(ulp-cvals) \ 275 FUNC=$(func) \ 276 WANT_EXPERIMENTAL_MATH=$(WANT_EXPERIMENTAL_MATH) \ 277 WANT_SVE_TESTS=$(WANT_SVE_TESTS) \ 278 USE_MPFR=$(USE_MPFR) \ 279 build/bin/runulp.sh $(EMULATOR) 280 281check-math: check-math-test check-math-rtest check-math-ulp 282 283install-math: \ 284 $(math-libs:build/lib/%=$(DESTDIR)$(libdir)/%) \ 285 $(math-includes:build/include/%=$(DESTDIR)$(includedir)/%) 286 287clean-math: 288 rm -f $(math-files) 289 290.PHONY: all-math check-math-test check-math-rtest check-math-ulp check-math install-math clean-math 291