xref: /freebsd/contrib/arm-optimized-routines/math/Dir.mk (revision dd21556857e8d40f66bf5ad54754d9d52669ebf7)
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