aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile20
-rw-r--r--c_emulator/riscv_prelude.h1
-rw-r--r--c_emulator/riscv_sail.h2
-rw-r--r--c_emulator/riscv_softfloat.c169
-rw-r--r--c_emulator/riscv_softfloat.h17
-rw-r--r--model/riscv_softfloat_interface.sail119
6 files changed, 291 insertions, 37 deletions
diff --git a/Makefile b/Makefile
index 6dd562b..621c47c 100644
--- a/Makefile
+++ b/Makefile
@@ -106,15 +106,21 @@ BBV_DIR?=../bbv
C_WARNINGS ?=
#-Wall -Wextra -Wno-unused-label -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-unused-function
-C_INCS = $(addprefix c_emulator/,riscv_prelude.h riscv_platform_impl.h riscv_platform.h)
-C_SRCS = $(addprefix c_emulator/,riscv_prelude.c riscv_platform_impl.c riscv_platform.c riscv_sim.c)
+C_INCS = $(addprefix c_emulator/,riscv_prelude.h riscv_platform_impl.h riscv_platform.h riscv_softfloat.h)
+C_SRCS = $(addprefix c_emulator/,riscv_prelude.c riscv_platform_impl.c riscv_platform.c riscv_softfloat.c riscv_sim.c)
# portability for MacPorts/MacOS
C_SYS_INCLUDES = -I /opt/local/include
C_SYS_LIBDIRS = -L /opt/local/lib
-C_FLAGS = $(C_SYS_INCLUDES) -I $(SAIL_LIB_DIR) -I c_emulator
-C_LIBS = $(C_SYS_LIBDIRS) -lgmp -lz
+SOFTFLOAT_DIR = c_emulator/SoftFloat-3e
+SOFTFLOAT_INCDIR = $(SOFTFLOAT_DIR)/source/include
+SOFTFLOAT_LIBDIR = $(SOFTFLOAT_DIR)/build/Linux-x86_64-GCC
+SOFTFLOAT_FLAGS = -I $(SOFTFLOAT_INCDIR)
+SOFTFLOAT_LIBS = $(SOFTFLOAT_LIBDIR)/softfloat.a
+
+C_FLAGS = $(C_SYS_INCLUDES) -I $(SAIL_LIB_DIR) -I c_emulator $(SOFTFLOAT_FLAGS)
+C_LIBS = $(C_SYS_LIBDIRS) -lgmp -lz $(SOFTFLOAT_LIBS)
# The C simulator can be built to be linked against Spike for tandem-verification.
# This needs the C bindings to Spike from https://github.com/SRI-CSL/l3riscv
@@ -213,7 +219,10 @@ generated_definitions/c/riscv_model_$(ARCH).c: $(SAIL_SRCS) model/main.sail Make
mkdir -p generated_definitions/c
$(SAIL) $(SAIL_FLAGS) -O -Oconstant_fold -memo_z3 -c -c_include riscv_prelude.h -c_include riscv_platform.h -c_no_main $(SAIL_SRCS) model/main.sail -o $(basename $@)
-c_emulator/riscv_sim_$(ARCH): generated_definitions/c/riscv_model_$(ARCH).c $(C_INCS) $(C_SRCS) Makefile
+$(SOFTFLOAT_LIBS):
+ make -C $(SOFTFLOAT_LIBDIR)
+
+c_emulator/riscv_sim_$(ARCH): generated_definitions/c/riscv_model_$(ARCH).c $(C_INCS) $(C_SRCS) $(SOFTFLOAT_LIBS) Makefile
gcc -g $(C_WARNINGS) $(C_FLAGS) $< $(C_SRCS) $(SAIL_LIB_DIR)/*.c $(C_LIBS) -o $@
generated_definitions/c/riscv_rvfi_model.c: $(SAIL_RVFI_SRCS) model/main.sail Makefile
@@ -374,6 +383,7 @@ clean:
-rm -rf generated_definitions/ocaml/* generated_definitions/c/* generated_definitions/latex/*
-rm -rf generated_definitions/lem/* generated_definitions/isabelle/* generated_definitions/hol4/* generated_definitions/coq/*
-rm -rf generated_definitions/for-rmem/*
+ -make -C $(SOFTFLOAT_LIBDIR) clean
-rm -f c_emulator/riscv_sim_RV32 c_emulator/riscv_sim_RV64 c_emulator/riscv_rvfi
-rm -rf ocaml_emulator/_sbuild ocaml_emulator/_build ocaml_emulator/riscv_ocaml_sim_RV32 ocaml_emulator/riscv_ocaml_sim_RV64 ocaml_emulator/tracecmp
-rm -f *.gcno *.gcda
diff --git a/c_emulator/riscv_prelude.h b/c_emulator/riscv_prelude.h
index da292fe..9ac33aa 100644
--- a/c_emulator/riscv_prelude.h
+++ b/c_emulator/riscv_prelude.h
@@ -1,6 +1,7 @@
#pragma once
#include "sail.h"
#include "rts.h"
+#include "riscv_softfloat.h"
unit print_string(sail_string prefix, sail_string msg);
diff --git a/c_emulator/riscv_sail.h b/c_emulator/riscv_sail.h
index f177c57..67555c0 100644
--- a/c_emulator/riscv_sail.h
+++ b/c_emulator/riscv_sail.h
@@ -49,6 +49,8 @@ extern mach_bits zmstatus;
extern mach_bits zmepc, zmtval;
extern mach_bits zsepc, zstval;
+extern mach_bits zfloat_result, zfloat_fflags;
+
struct zMcause {mach_bits zMcause_chunk_0;};
struct zMcause zmcause, zscause;
diff --git a/c_emulator/riscv_softfloat.c b/c_emulator/riscv_softfloat.c
new file mode 100644
index 0000000..a926d42
--- /dev/null
+++ b/c_emulator/riscv_softfloat.c
@@ -0,0 +1,169 @@
+#include "sail.h"
+#include "rts.h"
+#include "riscv_sail.h"
+#include "riscv_softfloat.h"
+#include "softfloat.h"
+
+#define SOFTFLOAT_PRELUDE(rm) \
+ softfloat_exceptionFlags = 0; \
+ softfloat_roundingMode = (uint_fast8_t) rm
+
+#define SOFTFLOAT_POSTLUDE(res) \
+ zfloat_result = res.v; \
+ zfloat_fflags = (mach_bits) softfloat_exceptionFlags
+
+unit softfloat_f32add(mach_bits rm, mach_bits v1, mach_bits v2) {
+ SOFTFLOAT_PRELUDE(rm);
+
+ float32_t a, b, res;
+ a.v = v1;
+ b.v = v2;
+ res = f32_add(a, b);
+
+ SOFTFLOAT_POSTLUDE(res);
+
+ return UNIT;
+}
+
+unit softfloat_f32sub(mach_bits rm, mach_bits v1, mach_bits v2) {
+ SOFTFLOAT_PRELUDE(rm);
+
+ float32_t a, b, res;
+ a.v = v1;
+ b.v = v2;
+ res = f32_sub(a, b);
+
+ SOFTFLOAT_POSTLUDE(res);
+
+ return UNIT;
+}
+
+unit softfloat_f32mul(mach_bits rm, mach_bits v1, mach_bits v2) {
+ SOFTFLOAT_PRELUDE(rm);
+
+ float32_t a, b, res;
+ a.v = v1;
+ b.v = v2;
+ res = f32_mul(a, b);
+
+ SOFTFLOAT_POSTLUDE(res);
+
+ return UNIT;
+}
+
+unit softfloat_f32div(mach_bits rm, mach_bits v1, mach_bits v2) {
+ SOFTFLOAT_PRELUDE(rm);
+
+ float32_t a, b, res;
+ a.v = v1;
+ b.v = v2;
+ res = f32_div(a, b);
+
+ SOFTFLOAT_POSTLUDE(res);
+
+ return UNIT;
+}
+
+unit softfloat_f64add(mach_bits rm, mach_bits v1, mach_bits v2) {
+ SOFTFLOAT_PRELUDE(rm);
+
+ float64_t a, b, res;
+ a.v = v1;
+ b.v = v2;
+ res = f64_add(a, b);
+
+ SOFTFLOAT_POSTLUDE(res);
+
+ return UNIT;
+}
+
+unit softfloat_f64sub(mach_bits rm, mach_bits v1, mach_bits v2) {
+ SOFTFLOAT_PRELUDE(rm);
+
+ float64_t a, b, res;
+ a.v = v1;
+ b.v = v2;
+ res = f64_sub(a, b);
+
+ SOFTFLOAT_POSTLUDE(res);
+
+ return UNIT;
+}
+
+unit softfloat_f64mul(mach_bits rm, mach_bits v1, mach_bits v2) {
+ SOFTFLOAT_PRELUDE(rm);
+
+ float64_t a, b, res;
+ a.v = v1;
+ b.v = v2;
+ res = f64_mul(a, b);
+
+ SOFTFLOAT_POSTLUDE(res);
+
+ return UNIT;
+}
+
+unit softfloat_f64div(mach_bits rm, mach_bits v1, mach_bits v2) {
+ SOFTFLOAT_PRELUDE(rm);
+
+ float64_t a, b, res;
+ a.v = v1;
+ b.v = v2;
+ res = f64_div(a, b);
+
+ SOFTFLOAT_POSTLUDE(res);
+
+ return UNIT;
+}
+
+unit softfloat_f32muladd(mach_bits rm, mach_bits v1, mach_bits v2, mach_bits v3) {
+ SOFTFLOAT_PRELUDE(rm);
+
+ float32_t a, b, c, res;
+ a.v = v1;
+ b.v = v2;
+ c.v = v3;
+ res = f32_mulAdd(a, b, c);
+
+ SOFTFLOAT_POSTLUDE(res);
+
+ return UNIT;
+}
+
+unit softfloat_f64muladd(mach_bits rm, mach_bits v1, mach_bits v2, mach_bits v3) {
+ SOFTFLOAT_PRELUDE(rm);
+
+ float64_t a, b, c, res;
+ a.v = v1;
+ b.v = v2;
+ c.v = v3;
+ res = f64_mulAdd(a, b, c);
+
+ SOFTFLOAT_POSTLUDE(res);
+
+ return UNIT;
+}
+
+unit softfloat_f32sqrt(mach_bits rm, mach_bits v) {
+ SOFTFLOAT_PRELUDE(rm);
+
+ float32_t a, res;
+ a.v = v;
+ res = f32_sqrt(a);
+
+ SOFTFLOAT_POSTLUDE(res);
+
+ return UNIT;
+}
+
+unit softfloat_f64sqrt(mach_bits rm, mach_bits v) {
+ SOFTFLOAT_PRELUDE(rm);
+
+ float64_t a, res;
+ a.v = v;
+ res = f64_sqrt(a);
+
+ SOFTFLOAT_POSTLUDE(res);
+
+ return UNIT;
+}
diff --git a/c_emulator/riscv_softfloat.h b/c_emulator/riscv_softfloat.h
new file mode 100644
index 0000000..eb68ce6
--- /dev/null
+++ b/c_emulator/riscv_softfloat.h
@@ -0,0 +1,17 @@
+#pragma once
+
+unit softfloat_f32add(mach_bits rm, mach_bits v1, mach_bits v2);
+unit softfloat_f32sub(mach_bits rm, mach_bits v1, mach_bits v2);
+unit softfloat_f32mul(mach_bits rm, mach_bits v1, mach_bits v2);
+unit softfloat_f32div(mach_bits rm, mach_bits v1, mach_bits v2);
+
+unit softfloat_f64add(mach_bits rm, mach_bits v1, mach_bits v2);
+unit softfloat_f64sub(mach_bits rm, mach_bits v1, mach_bits v2);
+unit softfloat_f64mul(mach_bits rm, mach_bits v1, mach_bits v2);
+unit softfloat_f64div(mach_bits rm, mach_bits v1, mach_bits v2);
+
+unit softfloat_f32muladd(mach_bits rm, mach_bits v1, mach_bits v2, mach_bits v3);
+unit softfloat_f64muladd(mach_bits rm, mach_bits v1, mach_bits v2, mach_bits v3);
+
+unit softfloat_f32sqrt(mach_bits rm, mach_bits v);
+unit softfloat_f64sqrt(mach_bits rm, mach_bits v);
diff --git a/model/riscv_softfloat_interface.sail b/model/riscv_softfloat_interface.sail
index 8c017dd..0a055cb 100644
--- a/model/riscv_softfloat_interface.sail
+++ b/model/riscv_softfloat_interface.sail
@@ -28,50 +28,105 @@ type bits_WU = bits(32) /* Unsigned integer */
type bits_L = bits(64) /* Signed integer */
type bits_LU = bits(64) /* Unsigned integer */
+/* ***************************************************************** */
+/* Internal registers to pass results across the softfloat interface
+ * to avoid return types involving structures.
+ */
+register float_result : bits(64)
+register float_fflags : bits(64)
+
/* **************************************************************** */
/* ADD/SUB/MUL/DIV */
-val riscv_f32Add : (bits_rm, bits_S, bits_S) -> (bits_fflags, bits_S)
-function riscv_f32Add (rm, v1, v2) = (0b_00000, 0x_0000_0000)
-
-val riscv_f32Sub : (bits_rm, bits_S, bits_S) -> (bits_fflags, bits_S)
-function riscv_f32Sub (rm, v1, v2) = (0b_00000, 0x_0000_0000)
-
-val riscv_f32Mul : (bits_rm, bits_S, bits_S) -> (bits_fflags, bits_S)
-function riscv_f32Mul (rm, v1, v2) = (0b_00000, 0x_0000_0000)
-
-val riscv_f32Div : (bits_rm, bits_S, bits_S) -> (bits_fflags, bits_S)
-function riscv_f32Div (rm, v1, v2) = (0b_00000, 0x_0000_0000)
-
-val riscv_f64Add : (bits_rm, bits_D, bits_D) -> (bits_fflags, bits_D)
-function riscv_f64Add (rm, v1, v2) = (0b_00000, 0x_0000_0000_0000_0000)
-
-val riscv_f64Sub : (bits_rm, bits_D, bits_D) -> (bits_fflags, bits_D)
-function riscv_f64Sub (rm, v1, v2) = (0b_00000, 0x_0000_0000_0000_0000)
-
-val riscv_f64Mul : (bits_rm, bits_D, bits_D) -> (bits_fflags, bits_D)
-function riscv_f64Mul (rm, v1, v2) = (0b_00000, 0x_0000_0000_0000_0000)
-
-val riscv_f64Div : (bits_rm, bits_D, bits_D) -> (bits_fflags, bits_D)
-function riscv_f64Div (rm, v1, v2) = (0b_00000, 0x_0000_0000_0000_0000)
+val extern_f32Add = {c: "softfloat_f32add"} : (bits_rm, bits_S, bits_S) -> unit
+val riscv_f32Add : (bits_rm, bits_S, bits_S) -> (bits_fflags, bits_S) effect {rreg}
+function riscv_f32Add (rm, v1, v2) = {
+ extern_f32Add(rm, v1, v2);
+ (float_fflags[4 .. 0], float_result[31 .. 0])
+}
+
+val extern_f32Sub = {c: "softfloat_f32sub"} : (bits_rm, bits_S, bits_S) -> unit
+val riscv_f32Sub : (bits_rm, bits_S, bits_S) -> (bits_fflags, bits_S) effect {rreg}
+function riscv_f32Sub (rm, v1, v2) = {
+ extern_f32Sub(rm, v1, v2);
+ (float_fflags[4 .. 0], float_result[31 .. 0])
+}
+
+val extern_f32Mul = {c: "softfloat_f32mul"} : (bits_rm, bits_S, bits_S) -> unit
+val riscv_f32Mul : (bits_rm, bits_S, bits_S) -> (bits_fflags, bits_S) effect {rreg}
+function riscv_f32Mul (rm, v1, v2) = {
+ extern_f32Mul(rm, v1, v2);
+ (float_fflags[4 .. 0], float_result[31 .. 0])
+}
+
+val extern_f32Div = {c: "softfloat_f32div"} : (bits_rm, bits_S, bits_S) -> unit
+val riscv_f32Div : (bits_rm, bits_S, bits_S) -> (bits_fflags, bits_S) effect {rreg}
+function riscv_f32Div (rm, v1, v2) = {
+ extern_f32Div(rm, v1, v2);
+ (float_fflags[4 .. 0], float_result[31 .. 0])
+}
+
+val extern_f64Add = {c: "softfloat_f64add"} : (bits_rm, bits_D, bits_D) -> unit
+val riscv_f64Add : (bits_rm, bits_D, bits_D) -> (bits_fflags, bits_D) effect {rreg}
+function riscv_f64Add (rm, v1, v2) = {
+ extern_f64Add(rm, v1, v2);
+ (float_fflags[4 .. 0], float_result)
+}
+
+val extern_f64Sub = {c: "softfloat_f64sub"} : (bits_rm, bits_D, bits_D) -> unit
+val riscv_f64Sub : (bits_rm, bits_D, bits_D) -> (bits_fflags, bits_D) effect {rreg}
+function riscv_f64Sub (rm, v1, v2) = {
+ extern_f64Sub(rm, v1, v2);
+ (float_fflags[4 .. 0], float_result)
+}
+
+val extern_f64Mul = {c: "softfloat_f64mul"} : (bits_rm, bits_D, bits_D) -> unit
+val riscv_f64Mul : (bits_rm, bits_D, bits_D) -> (bits_fflags, bits_D) effect {rreg}
+function riscv_f64Mul (rm, v1, v2) = {
+ extern_f64Mul(rm, v1, v2);
+ (float_fflags[4 .. 0], float_result)
+}
+
+val extern_f64Div = {c: "softfloat_f64div"} : (bits_rm, bits_D, bits_D) -> unit
+val riscv_f64Div : (bits_rm, bits_D, bits_D) -> (bits_fflags, bits_D) effect {rreg}
+function riscv_f64Div (rm, v1, v2) = {
+ extern_f64Div(rm, v1, v2);
+ (float_fflags[4 .. 0], float_result)
+}
/* **************************************************************** */
/* MULTIPLY-ADD */
-val riscv_f32MulAdd : (bits_rm, bits_S, bits_S, bits_S) -> (bits_fflags, bits_S)
-function riscv_f32MulAdd (rm, v1, v2, v3) = (0b_00000, 0x_0000_0000)
+val extern_f32MulAdd = {c: "softfloat_f32muladd"} : (bits_rm, bits_S, bits_S, bits_S) -> unit
+val riscv_f32MulAdd : (bits_rm, bits_S, bits_S, bits_S) -> (bits_fflags, bits_S) effect {rreg}
+function riscv_f32MulAdd (rm, v1, v2, v3) = {
+ extern_f32MulAdd(rm, v1, v2, v3);
+ (float_fflags[4 .. 0], float_result[31 .. 0])
+}
-val riscv_f64MulAdd : (bits_rm, bits_D, bits_D, bits_D) -> (bits_fflags, bits_D)
-function riscv_f64MulAdd (rm, v1, v2, v3) = (0b_00000, 0x_0000_0000_0000_0000)
+val extern_f64MulAdd = {c: "softfloat_f64muladd"} : (bits_rm, bits_D, bits_D, bits_D) -> unit
+val riscv_f64MulAdd : (bits_rm, bits_D, bits_D, bits_D) -> (bits_fflags, bits_D) effect {rreg}
+function riscv_f64MulAdd (rm, v1, v2, v3) = {
+ extern_f64MulAdd(rm, v1, v2, v3);
+ (float_fflags[4 .. 0], float_result)
+}
/* **************************************************************** */
/* SQUARE ROOT */
-val riscv_f32Sqrt : (bits_rm, bits_S) -> (bits_fflags, bits_S)
-function riscv_f32Sqrt (rm, v) = (0b_00000, 0x_0000_0000)
-
-val riscv_f64Sqrt : (bits_rm, bits_D) -> (bits_fflags, bits_D)
-function riscv_f64Sqrt (rm, v) = (0b_00000, 0x_0000_0000_0000_0000)
+val extern_f32Sqrt = {c: "softfloat_f32sqrt"} : (bits_rm, bits_S) -> unit
+val riscv_f32Sqrt : (bits_rm, bits_S) -> (bits_fflags, bits_S) effect {rreg}
+function riscv_f32Sqrt (rm, v) = {
+ extern_f32Sqrt(rm, v);
+ (float_fflags[4 .. 0], float_result[31 .. 0])
+}
+
+val extern_f64Sqrt = {c: "softfloat_f64sqrt"} : (bits_rm, bits_D) -> unit
+val riscv_f64Sqrt : (bits_rm, bits_D) -> (bits_fflags, bits_D) effect {rreg}
+function riscv_f64Sqrt (rm, v) = {
+ extern_f64Sqrt(rm, v);
+ (float_fflags[4 .. 0], float_result)
+}
/* **************************************************************** */
/* CONVERSIONS */