Skip to content

Commit

Permalink
sw/math: Extend and refactor to proper library (#60)
Browse files Browse the repository at this point in the history
* sw/math: Refactor to proper library

The previous header-only library style led to conflicts on certain
defines (for instance `N`) defined in both math library sources and
application sources.

* sw/math: Add `exp`, `sqrt`, `log` and `ceil` functions

* sw/math: Add safe FP <--> INT conversions

* ci: Properly initialize Bender dependencies

* sw/math: Implement safe `tanh` function
  • Loading branch information
colluca authored Nov 8, 2023
1 parent 252ee2c commit 11366d5
Show file tree
Hide file tree
Showing 49 changed files with 1,692 additions and 46 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ jobs:
submodules: 'recursive'
- name: Build Software
run: |
bender vendor init
make -C target/snitch_cluster sw
- name: Build Hardware
run: |
Expand All @@ -61,6 +62,7 @@ jobs:
submodules: 'recursive'
- name: Build Software
run: |
bender vendor init
make -C target/snitch_cluster SELECT_RUNTIME=banshee sw
- name: Run Tests
env:
Expand Down
2 changes: 1 addition & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ variables:
VERILATOR: verilator-4.110
QUESTA: questa-2022.3
LLVM_BINROOT: /usr/pack/riscv-1.0-kgf/pulp-llvm-0.12.0/bin
CLANG: /usr/pack/riscv-1.0-kgf/pulp-llvm-0.12.0/bin/clang
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER: /usr/pack/gcc-9.2.0-af/linux-x64/bin/gcc
LLVM_SYS_120_PREFIX: /usr/pack/llvm-12.0.1-af
CMAKE: cmake-3.18.1
Expand All @@ -22,6 +21,7 @@ before_script:
- $PYTHON -m venv .venv
- source .venv/bin/activate
- pip install -r python-requirements.txt
- $BENDER vendor init

##############
# Build docs #
Expand Down
29 changes: 28 additions & 1 deletion Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,40 @@ vendor_package:
- "Makefile"
- ".gitignore"
- "README"
- "src/math/tanh.c"
- "src/math/ceil.c"
- "src/math/ceilf.c"
- "src/math/ceill.c"
- "src/math/expm1.c"
- "src/math/expf.c"
- "src/math/exp2f_data.c"
- "src/math/exp2f_data.h"
- "src/math/log2.c"
- "src/math/log2_data.c"
- "src/math/log2_data.h"
- "src/math/log2f.c"
- "src/math/log2f_data.c"
- "src/math/log2f_data.h"
- "src/math/__math_divzero.c"
- "src/math/__math_invalid.c"
- "src/math/__math_invalidf.c"
- "src/math/__math_invalidl.c"
- "src/math/__math_oflow.c"
- "src/math/__math_oflowf.c"
- "src/math/__math_uflow.c"
- "src/math/__math_uflowf.c"
- "src/math/__math_xflow.c"
- "src/math/__math_xflowf.c"
- "src/math/sqrt.c"
- "src/math/sqrtf.c"
- "src/math/sqrt_data.c"
- "src/math/sqrt_data.h"
- "src/math/tanh.c"
- "src/internal/libm.h"
- "src/include/features.h"
- "include/endian.h"
- "include/math.h"
- "include/features.h"
- "include/float.h"
- "include/alltypes.h.in"
- "arch/riscv64/bits/alltypes.h.in"
- "arch/riscv64/bits/float.h"
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

REGGEN = $(shell bender path register_interface)/vendor/lowrisc_opentitan/util/regtool.py
BENDER ?= bender
REGGEN = $(shell $(BENDER) path register_interface)/vendor/lowrisc_opentitan/util/regtool.py

GENERATED_DOCS_DIR = docs/generated
GENERATED_DOC_SRCS = $(GENERATED_DOCS_DIR)/peripherals.md
Expand Down
2 changes: 1 addition & 1 deletion hw/mem_interface/util/compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ set -e

[ ! -z "$VSIM" ] || VSIM=vsim

bender script vsim -t test \
$BENDER script vsim -t test \
--vlog-arg="-svinputport=compat" \
--vlog-arg="-override_timescale 1ns/1ps" \
--vlog-arg="-suppress 2583" \
Expand Down
2 changes: 1 addition & 1 deletion hw/reqrsp_interface/util/compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ set -e

[ ! -z "$VSIM" ] || VSIM=vsim

bender script vsim -t test \
$(BENDER) script vsim -t test \
--vlog-arg="-svinputport=compat" \
--vlog-arg="-override_timescale 1ns/1ps" \
--vlog-arg="-suppress 2583" \
Expand Down
2 changes: 1 addition & 1 deletion hw/snitch_cluster/util/compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ set -e

[ ! -z "$VSIM" ] || VSIM=vsim

bender script vsim -t test \
$BENDER script vsim -t test \
--vlog-arg="-svinputport=compat" \
--vlog-arg="-override_timescale 1ns/1ps" \
--vlog-arg="-suppress 2583" \
Expand Down
2 changes: 1 addition & 1 deletion hw/snitch_icache/util/compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ set -e

[ ! -z "$VSIM" ] || VSIM=vsim

bender script vsim -t test \
$BENDER script vsim -t test \
--vlog-arg="-svinputport=compat" \
--vlog-arg="-override_timescale 1ns/1ps" \
--vlog-arg="-suppress 2583" \
Expand Down
2 changes: 1 addition & 1 deletion hw/snitch_ssr/util/compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ set -e

[ ! -z "$VSIM" ] || VSIM=vsim

bender script vsim -t test \
$(BENDER) script vsim -t test \
--vlog-arg="-svinputport=compat" \
--vlog-arg="-override_timescale 1ns/1ps" \
--vlog-arg="-suppress 2583" \
Expand Down
2 changes: 1 addition & 1 deletion hw/tcdm_interface/util/compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ set -e

[ ! -z "$VSIM" ] || VSIM=vsim

bender script vsim -t test \
$BENDER script vsim -t test \
--vlog-arg="-svinputport=compat" \
--vlog-arg="-override_timescale 1ns/1ps" \
--vlog-arg="-suppress 2583" \
Expand Down
125 changes: 125 additions & 0 deletions sw/deps/patches/musl/0002-sw-math-Refactor-to-proper-library.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
From 91c1b48e44629a80bdc1832111707c051ab0b3b2 Mon Sep 17 00:00:00 2001
From: Luca Colagrande <[email protected]>
Date: Mon, 23 Oct 2023 14:30:18 +0200
Subject: [PATCH] sw/math: Refactor to proper library

The previous header-only library style led to conflicts on certain
defines (for instance `N`) defined in both math library sources and
application sources.
---
Makefile | 77 +++++++++++++++++++++++++++++++++++++++++++++++---
include/math.h | 3 --
2 files changed, 73 insertions(+), 7 deletions(-)

diff --git a/Makefile b/Makefile
index 1327953..a6f7a1a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,17 +1,86 @@
-BITS_DIR = include/bits
+# Copyright 2023 ETH Zurich and University of Bologna.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+#
+# Luca Colagrande <[email protected]>
+# Viviane Potocnik, ETH Zurich <[email protected]>
+
+# Usage of absolute paths is required to externally include
+# this Makefile from multiple different locations
+MK_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
+
+###############
+# Directories #
+###############
+
+BUILDDIR ?= $(abspath build)
+SRC_DIR = $(MK_DIR)/src/math
+BITS_DIR = $(MK_DIR)/include/bits
+
+###################
+# Build variables #
+###################
+
+INCDIRS += $(MK_DIR)/arch/riscv64/
+INCDIRS += $(MK_DIR)/arch/generic
+INCDIRS += $(MK_DIR)/src/include
+INCDIRS += $(MK_DIR)/src/internal
+INCDIRS += $(MK_DIR)/include/bits
+INCDIRS += $(MK_DIR)/include
+
+SRCS = $(abspath $(wildcard $(SRC_DIR)/*.c))
+
+###########
+# Outputs #
+###########
+
ALLTYPES_H = $(BITS_DIR)/alltypes.h

+OBJS = $(addprefix $(BUILDDIR)/,$(addsuffix .o,$(basename $(notdir $(SRCS)))))
+DEPS = $(addprefix $(BUILDDIR)/,$(addsuffix .d,$(basename $(notdir $(SRCS)))))
+LIB = $(BUILDDIR)/libmath.a
+DUMP = $(BUILDDIR)/libmath.dump
+ALL_OUTPUTS = $(LIB) $(DUMP)

-.PHONY: all clean
+#########
+# Rules #
+#########

-all: $(ALLTYPES_H)
+.PHONY: all
+all: $(ALL_OUTPUTS)

+.PHONY: clean
clean:
rm -rf $(BITS_DIR)
rm -f $(ALLTYPES_H)
+ rm -rf $(BUILDDIR)

$(BITS_DIR):
mkdir -p $@

$(ALLTYPES_H): | $(BITS_DIR)
- sed -f tools/mkalltypes.sed arch/riscv64/bits/alltypes.h.in include/alltypes.h.in > $@
+ sed -f $(MK_DIR)/tools/mkalltypes.sed $(MK_DIR)/arch/riscv64/bits/alltypes.h.in $(MK_DIR)/include/alltypes.h.in > $@
+
+$(DEPS): $(ALLTYPES_H)
+
+$(BUILDDIR):
+ mkdir -p $@
+
+$(BUILDDIR)/%.o: $(SRC_DIR)/%.S | $(BUILDDIR)
+ $(RISCV_CC) $(RISCV_CFLAGS) -c $< -o $@
+
+$(BUILDDIR)/%.o: $(SRC_DIR)/%.c | $(BUILDDIR)
+ $(RISCV_CC) $(RISCV_CFLAGS) -c $< -o $@
+
+$(BUILDDIR)/%.d: $(SRC_DIR)/%.c | $(BUILDDIR)
+ $(RISCV_CC) $(RISCV_CFLAGS) -MM -MT '$(@:.d=.o)' $< > $@
+
+$(LIB): $(OBJS) | $(BUILDDIR)
+ $(RISCV_AR) $(RISCV_ARFLAGS) $@ $^
+
+$(DUMP): $(LIB) | $(BUILDDIR)
+ $(RISCV_OBJDUMP) -D $< > $@
+
+ifneq ($(MAKECMDGOALS),clean)
+-include $(DEPS)
+endif
diff --git a/include/math.h b/include/math.h
index 6dad71c..14f28ec 100644
--- a/include/math.h
+++ b/include/math.h
@@ -435,9 +435,6 @@ float pow10f(float);
long double pow10l(long double);
#endif

-#include "../src/math/expm1.c"
-#include "../src/math/tanh.c"
-
#ifdef __cplusplus
}
#endif
--
2.28.0

Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
From eb96f4d7454a07498f571eb1ed18aa1db2413551 Mon Sep 17 00:00:00 2001
From: Luca Colagrande <[email protected]>
Date: Mon, 23 Oct 2023 16:45:17 +0200
Subject: [PATCH] `sw/math`: Add safe FP <--> INT conversions

---
src/internal/libm.h | 51 +++++++++++++++++++++++++++++++++++++++++----
1 file changed, 47 insertions(+), 4 deletions(-)

diff --git a/src/internal/libm.h b/src/internal/libm.h
index 72ad17d..60b9866 100644
--- a/src/internal/libm.h
+++ b/src/internal/libm.h
@@ -96,6 +96,47 @@ static int32_t converttoint(double_t);
#define predict_false(x) (x)
#endif

+/* FPU fence to synchronize the FPU and integer core in Snitch. */
+inline void snrt_fpu_fence() {
+ unsigned tmp;
+ __asm__ volatile(
+ "fmv.x.w %0, fa0\n"
+ "mv %0, %0\n"
+ : "+r"(tmp)::"memory");
+}
+
+/* Synch-secure double to uint64 conversion functions. */
+static inline uint64_t asuint64(double f) {
+ uint64_t result;
+ snrt_fpu_fence();
+ result = *(uint64_t *)&f;
+ return result;
+}
+
+/* Synch-secure float to uint conversion functions. */
+static inline uint64_t asuint(float f) {
+ uint32_t result;
+ snrt_fpu_fence();
+ result = *(uint32_t *)&f;
+ return result;
+}
+
+/* Synch-secure uint64 to double conversion functions. */
+static inline double asdouble(uint64_t i) {
+ double result;
+ snrt_fpu_fence();
+ result = *(double *)&i;
+ return result;
+}
+
+/* Synch-secure uint to float conversion functions. */
+static inline float asfloat(uint32_t i) {
+ float result;
+ snrt_fpu_fence();
+ result = *(float *)&i;
+ return result;
+}
+
/* Evaluate an expression as the specified type. With standard excess
precision handling a type cast or assignment is enough (with
-ffloat-store an assignment is required, in old compilers argument
@@ -187,10 +228,12 @@ static inline void fp_force_evall(long double x)
} \
} while(0)

-#define asuint(f) ((union{float _f; uint32_t _i;}){f})._i
-#define asfloat(i) ((union{uint32_t _i; float _f;}){i})._f
-#define asuint64(f) ((union{double _f; uint64_t _i;}){f})._i
-#define asdouble(i) ((union{uint64_t _i; double _f;}){i})._f
+// Unsafe in Snitch due to the decoupled FPU and integer
+// arithmetic units. Use at your own risk.
+#define asuint_unsafe(f) ((union{float _f; uint32_t _i;}){f})._i
+#define asfloat_unsafe(i) ((union{uint32_t _i; float _f;}){i})._f
+#define asuint64_unsafe(f) ((union{double _f; uint64_t _i;}){f})._i
+#define asdouble_unsafe(i) ((union{uint64_t _i; double _f;}){i})._f

#define EXTRACT_WORDS(hi,lo,d) \
do { \
--
2.28.0

Loading

0 comments on commit 11366d5

Please sign in to comment.