1# Makefile fragment - requires GNU make
2#
3# Copyright (c) 2019-2023, Arm Limited.
4# SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception
5
6PLM := $(srcdir)/pl/math
7AOR := $(srcdir)/math
8B := build/pl/math
9
10math-lib-srcs := $(wildcard $(PLM)/*.[cS])
11math-test-srcs := \
12	$(AOR)/test/mathtest.c \
13	$(AOR)/test/mathbench.c \
14	$(AOR)/test/ulp.c \
15
16math-test-host-srcs := $(wildcard $(AOR)/test/rtest/*.[cS])
17
18math-includes := $(patsubst $(PLM)/%,build/pl/%,$(wildcard $(PLM)/include/*.h))
19math-test-includes := $(patsubst $(PLM)/%,build/pl/include/%,$(wildcard $(PLM)/test/*.h))
20
21math-libs := \
22	build/pl/lib/libmathlib.so \
23	build/pl/lib/libmathlib.a \
24
25math-tools := \
26	build/pl/bin/mathtest \
27	build/pl/bin/mathbench \
28	build/pl/bin/mathbench_libc \
29	build/pl/bin/runulp.sh \
30	build/pl/bin/ulp \
31
32math-host-tools := \
33	build/pl/bin/rtest \
34
35math-lib-objs := $(patsubst $(PLM)/%,$(B)/%.o,$(basename $(math-lib-srcs)))
36math-test-objs := $(patsubst $(AOR)/%,$(B)/%.o,$(basename $(math-test-srcs)))
37math-host-objs := $(patsubst $(AOR)/%,$(B)/%.o,$(basename $(math-test-host-srcs)))
38math-target-objs := $(math-lib-objs) $(math-test-objs)
39math-objs := $(math-target-objs) $(math-target-objs:%.o=%.os) $(math-host-objs)
40
41pl/math-files := \
42	$(math-objs) \
43	$(math-libs) \
44	$(math-tools) \
45	$(math-host-tools) \
46	$(math-includes) \
47	$(math-test-includes) \
48
49all-pl/math: $(math-libs) $(math-tools) $(math-includes) $(math-test-includes)
50
51$(math-objs): $(math-includes) $(math-test-includes)
52$(math-objs): CFLAGS_PL += $(math-cflags)
53$(B)/test/mathtest.o: CFLAGS_PL += -fmath-errno
54$(math-host-objs): CC = $(HOST_CC)
55$(math-host-objs): CFLAGS_PL = $(HOST_CFLAGS)
56
57build/pl/include/test/ulp_funcs_gen.h: $(math-lib-srcs)
58	# Replace PL_SIG
59	cat $^ | grep PL_SIG | $(CC) -xc - -o - -E "-DPL_SIG(v, t, a, f, ...)=_Z##v##t##a(f)" -P > $@
60
61build/pl/include/test/mathbench_funcs_gen.h: $(math-lib-srcs)
62	# Replace PL_SIG macros with mathbench func entries
63	cat $^ | grep PL_SIG | $(CC) -xc - -o - -E "-DPL_SIG(v, t, a, f, ...)=_Z##v##t##a(f, ##__VA_ARGS__)" -P > $@
64
65build/pl/include/test/ulp_wrappers_gen.h: $(math-lib-srcs)
66	# Replace PL_SIG macros with ULP wrapper declarations
67	cat $^ | grep PL_SIG | $(CC) -xc - -o - -E "-DPL_SIG(v, t, a, f, ...)=Z##v##N##t##a##_WRAP(f)" -P > $@
68
69$(B)/test/ulp.o: $(AOR)/test/ulp.h build/pl/include/test/ulp_funcs_gen.h build/pl/include/test/ulp_wrappers_gen.h
70$(B)/test/ulp.o: CFLAGS_PL += -I build/pl/include/test
71
72$(B)/test/mathbench.o: build/pl/include/test/mathbench_funcs_gen.h
73$(B)/test/mathbench.o: CFLAGS_PL += -I build/pl/include/test
74
75build/pl/lib/libmathlib.so: $(math-lib-objs:%.o=%.os)
76	$(CC) $(CFLAGS_PL) $(LDFLAGS) -shared -o $@ $^
77
78build/pl/lib/libmathlib.a: $(math-lib-objs)
79	rm -f $@
80	$(AR) rc $@ $^
81	$(RANLIB) $@
82
83$(math-host-tools): HOST_LDLIBS += -lm -lmpfr -lmpc
84$(math-tools): LDLIBS += $(math-ldlibs) -lm
85
86# Some targets to build pl/math/test from math/test sources
87build/pl/math/test/%.o: $(srcdir)/math/test/%.S
88	$(CC) $(CFLAGS_PL) -c -o $@ $<
89
90build/pl/math/test/%.o: $(srcdir)/math/test/%.c
91	$(CC) $(CFLAGS_PL) -c -o $@ $<
92
93build/pl/math/test/%.os: $(srcdir)/math/test/%.S
94	$(CC) $(CFLAGS_PL) -c -o $@ $<
95
96build/pl/math/test/%.os: $(srcdir)/math/test/%.c
97	$(CC) $(CFLAGS_PL) -c -o $@ $<
98
99# Some targets to build pl/ sources using appropriate flags
100build/pl/%.o: $(srcdir)/pl/%.S
101	$(CC) $(CFLAGS_PL) -c -o $@ $<
102
103build/pl/%.o: $(srcdir)/pl/%.c
104	$(CC) $(CFLAGS_PL) -c -o $@ $<
105
106build/pl/%.os: $(srcdir)/pl/%.S
107	$(CC) $(CFLAGS_PL) -c -o $@ $<
108
109build/pl/%.os: $(srcdir)/pl/%.c
110	$(CC) $(CFLAGS_PL) -c -o $@ $<
111
112build/pl/bin/rtest: $(math-host-objs)
113	$(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ $^ $(HOST_LDLIBS)
114
115build/pl/bin/mathtest: $(B)/test/mathtest.o build/pl/lib/libmathlib.a
116	$(CC) $(CFLAGS_PL) $(LDFLAGS) -static -o $@ $^ $(LDLIBS)
117
118build/pl/bin/mathbench: $(B)/test/mathbench.o build/pl/lib/libmathlib.a
119	$(CC) $(CFLAGS_PL) $(LDFLAGS) -static -o $@ $^ $(LDLIBS)
120
121# This is not ideal, but allows custom symbols in mathbench to get resolved.
122build/pl/bin/mathbench_libc: $(B)/test/mathbench.o build/pl/lib/libmathlib.a
123	$(CC) $(CFLAGS_PL) $(LDFLAGS) -static -o $@ $< $(LDLIBS) -lc build/pl/lib/libmathlib.a -lm
124
125build/pl/bin/ulp: $(B)/test/ulp.o build/pl/lib/libmathlib.a
126	$(CC) $(CFLAGS_PL) $(LDFLAGS) -static -o $@ $^ $(LDLIBS)
127
128build/pl/include/%.h: $(PLM)/include/%.h
129	cp $< $@
130
131build/pl/include/test/%.h: $(PLM)/test/%.h
132	cp $< $@
133
134build/pl/bin/%.sh: $(PLM)/test/%.sh
135	cp $< $@
136
137pl-math-tests := $(wildcard $(PLM)/test/testcases/directed/*.tst)
138pl-math-rtests := $(wildcard $(PLM)/test/testcases/random/*.tst)
139
140check-pl/math-test: $(math-tools)
141	cat $(pl-math-tests) | $(EMULATOR) build/pl/bin/mathtest $(math-testflags)
142
143check-pl/math-rtest: $(math-host-tools) $(math-tools)
144	cat $(pl-math-rtests) | build/pl/bin/rtest | $(EMULATOR) build/pl/bin/mathtest $(math-testflags)
145
146ulp-input-dir=$(B)/test/inputs
147
148math-lib-lims = $(patsubst $(PLM)/%,$(ulp-input-dir)/%.ulp,$(basename $(math-lib-srcs)))
149math-lib-aliases = $(patsubst $(PLM)/%,$(ulp-input-dir)/%.alias,$(basename $(math-lib-srcs)))
150math-lib-fenvs = $(patsubst $(PLM)/%,$(ulp-input-dir)/%.fenv,$(basename $(math-lib-srcs)))
151math-lib-itvs = $(patsubst $(PLM)/%,$(ulp-input-dir)/%.itv,$(basename $(math-lib-srcs)))
152
153ulp-inputs = $(math-lib-lims) $(math-lib-aliases) $(math-lib-fenvs) $(math-lib-itvs)
154
155$(ulp-inputs): CFLAGS_PL += -I$(PLM) -I$(PLM)/include $(math-cflags)
156
157$(ulp-input-dir)/%.ulp: $(PLM)/%.c
158	mkdir -p $(@D)
159	$(CC) -I$(PLM)/test $(CFLAGS_PL) $< -o - -E | { grep -o "PL_TEST_ULP [^ ]* [^ ]*" || true; } > $@
160
161$(ulp-input-dir)/%.alias: $(PLM)/%.c
162	mkdir -p $(@D)
163	$(CC) -I$(PLM)/test $(CFLAGS_PL) $< -o - -E | { grep "PL_TEST_ALIAS" || true; } | sed "s/_x / /g"> $@
164
165$(ulp-input-dir)/%.fenv: $(PLM)/%.c
166	mkdir -p $(@D)
167	$(CC) -I$(PLM)/test $(CFLAGS_PL) $< -o - -E | { grep -o "PL_TEST_EXPECT_FENV_ENABLED [^ ]*" || true; } > $@
168
169$(ulp-input-dir)/%.itv: $(PLM)/%.c
170	mkdir -p $(dir $@)
171	$(CC) -I$(PLM)/test $(CFLAGS_PL) $< -o - -E | { grep "PL_TEST_INTERVAL " || true; } | sed "s/ PL_TEST_INTERVAL/\nPL_TEST_INTERVAL/g" > $@
172
173ulp-lims := $(ulp-input-dir)/limits
174$(ulp-lims): $(math-lib-lims)
175	cat $^ | sed "s/PL_TEST_ULP //g;s/^ *//g" > $@
176
177ulp-aliases := $(ulp-input-dir)/aliases
178$(ulp-aliases): $(math-lib-aliases)
179	cat $^ | sed "s/PL_TEST_ALIAS //g;s/^ *//g" > $@
180
181fenv-exps := $(ulp-input-dir)/fenv
182$(fenv-exps): $(math-lib-fenvs)
183	cat $^ | sed "s/PL_TEST_EXPECT_FENV_ENABLED //g;s/^ *//g" > $@
184
185ulp-itvs-noalias := $(ulp-input-dir)/itvs_noalias
186$(ulp-itvs-noalias): $(math-lib-itvs)
187	cat $^ > $@
188
189rename-aliases := $(ulp-input-dir)/rename_alias.sed
190$(rename-aliases): $(ulp-aliases)
191	# Build sed script for replacing aliases from generated alias file
192	cat $< |  awk '{ print "s/ " $$1 " / " $$2 " /g" }' > $@
193
194ulp-itvs-alias := $(ulp-input-dir)/itvs_alias
195$(ulp-itvs-alias): $(ulp-itvs-noalias) $(rename-aliases)
196	cat $< | sed  -f $(rename-aliases) > $@
197
198ulp-itvs := $(ulp-input-dir)/intervals
199$(ulp-itvs): $(ulp-itvs-alias) $(ulp-itvs-noalias)
200	cat $^ | sort -u | sed "s/PL_TEST_INTERVAL //g" > $@
201
202check-pl/math-ulp: $(math-tools) $(ulp-lims) $(ulp-aliases) $(fenv-exps) $(ulp-itvs)
203	WANT_SVE_MATH=$(WANT_SVE_MATH) \
204	ULPFLAGS="$(math-ulpflags)" \
205	LIMITS=../../../$(ulp-lims) \
206	ALIASES=../../../$(ulp-aliases) \
207	INTERVALS=../../../$(ulp-itvs) \
208	FENV=../../../$(fenv-exps) \
209	build/pl/bin/runulp.sh $(EMULATOR)
210
211check-pl/math: check-pl/math-test check-pl/math-rtest check-pl/math-ulp
212
213$(DESTDIR)$(libdir)/pl/%.so: build/pl/lib/%.so
214	$(INSTALL) -D $< $@
215
216$(DESTDIR)$(libdir)/pl/%: build/pl/lib/%
217	$(INSTALL) -m 644 -D $< $@
218
219$(DESTDIR)$(includedir)/pl/%: build/pl/include/%
220	$(INSTALL) -m 644 -D $< $@
221
222install-pl/math: \
223 $(math-libs:build/pl/lib/%=$(DESTDIR)$(libdir)/pl/%) \
224 $(math-includes:build/pl/include/%=$(DESTDIR)$(includedir)/pl/%)
225
226clean-pl/math:
227	rm -f $(pl/math-files)
228
229.PHONY: all-pl/math check-pl/math-test check-pl/math-rtest check-pl/math-ulp check-pl/math install-pl/math clean-pl/math
230