Browse Source

wasm32 support (#192)

Daniel Mendler 6 years ago
parent
commit
72f33a3bf9
13 changed files with 126 additions and 8 deletions
  1. 10 0
      Make.inc
  2. 7 1
      Makefile
  3. 2 1
      README.md
  4. 1 1
      include/openlibm_math.h
  5. 12 5
      src/Make.files
  6. 4 0
      src/cdefs-compat.h
  7. 2 0
      src/s_fdim.c
  8. 2 0
      src/s_scalbln.c
  9. 0 0
      wasm32/Make.files
  10. 1 0
      wasm32/assert.h
  11. 33 0
      wasm32/float.h
  12. 9 0
      wasm32/limits.h
  13. 43 0
      wasm32/stdint.h

+ 10 - 0
Make.inc

@@ -31,6 +31,12 @@ endif
 
 
 AR = $(TOOLPREFIX)ar
 AR = $(TOOLPREFIX)ar
 
 
+ifeq ($(ARCH),wasm32)
+CC = clang-8
+USEGCC = 0
+CFLAGS_add += -fno-builtin -fno-strict-aliasing
+endif
+
 ifeq ($(USECLANG),1)
 ifeq ($(USECLANG),1)
 USEGCC = 0
 USEGCC = 0
 CC = clang
 CC = clang
@@ -118,6 +124,10 @@ SFLAGS_arch  += -m64
 LDFLAGS_arch += -m64
 LDFLAGS_arch += -m64
 endif
 endif
 
 
+ifeq ($(ARCH),wasm32)
+CFLAGS_arch += -ffreestanding -nostdlib -nostdinc --target=wasm32-unknown-unknown
+endif
+
 # Add our "arch"-related FLAGS in.  We separate arch-related flags out so that
 # Add our "arch"-related FLAGS in.  We separate arch-related flags out so that
 # we can conveniently get at them for targets that don't want the rest of
 # we can conveniently get at them for targets that don't want the rest of
 # *FLAGS_add, such as the testing Makefile targets
 # *FLAGS_add, such as the testing Makefile targets

+ 7 - 1
Makefile

@@ -49,7 +49,13 @@ endif
 .PHONY: all check test clean distclean \
 .PHONY: all check test clean distclean \
 	install install-static install-shared install-pkgconfig install-headers
 	install install-static install-shared install-pkgconfig install-headers
 
 
-all: libopenlibm.a libopenlibm.$(OLM_MAJOR_MINOR_SHLIB_EXT)
+
+OLM_LIBS := libopenlibm.a
+ifneq ($(ARCH), wasm32)
+OLM_LIBS += libopenlibm.$(OLM_MAJOR_MINOR_SHLIB_EXT)
+endif
+
+all : $(OLM_LIBS)
 
 
 check test: test/test-double test/test-float
 check test: test/test-double test/test-float
 	test/test-double
 	test/test-double

+ 2 - 1
README.md

@@ -27,7 +27,8 @@ also supports arm, aarch64, ppc64le, and mips.
    Linux and Windows.
    Linux and Windows.
 3. Use `make USECLANG=1` to build with clang. This is the default on OS X, FreeBSD,
 3. Use `make USECLANG=1` to build with clang. This is the default on OS X, FreeBSD,
    and OpenBSD.
    and OpenBSD.
-4. Architectures are auto-detected. Use `make ARCH=i386` to force a
+4. Use `make ARCH=wasm32` to build the wasm32 library with clang. Requires clang-8.
+5. Architectures are auto-detected. Use `make ARCH=i386` to force a
    build for i386. Other supported architectures are i486, i586, and
    build for i386. Other supported architectures are i486, i586, and
    i686. GCC 4.8 is the minimum requirement for correct codegen on
    i686. GCC 4.8 is the minimum requirement for correct codegen on
    older 32-bit architectures.
    older 32-bit architectures.

+ 1 - 1
include/openlibm_math.h

@@ -25,7 +25,7 @@
     #define __WIN32__
     #define __WIN32__
 #endif
 #endif
 
 
-#ifndef __arm__
+#if !defined(__arm__) && !defined(__wasm__)
 #define OLM_LONG_DOUBLE
 #define OLM_LONG_DOUBLE
 #endif
 #endif
 
 

+ 12 - 5
src/Make.files

@@ -15,15 +15,14 @@ $(CUR_SRCS) = common.c \
 	s_copysign.c s_copysignf.c s_cos.c s_cosf.c \
 	s_copysign.c s_copysignf.c s_cos.c s_cosf.c \
 	s_csqrt.c s_csqrtf.c s_erf.c s_erff.c \
 	s_csqrt.c s_csqrtf.c s_erf.c s_erff.c \
 	s_exp2.c s_exp2f.c s_expm1.c s_expm1f.c s_fabs.c s_fabsf.c s_fdim.c \
 	s_exp2.c s_exp2f.c s_expm1.c s_expm1f.c s_fabs.c s_fabsf.c s_fdim.c \
-	s_floor.c s_floorf.c s_fma.c s_fmaf.c \
+	s_floor.c s_floorf.c \
 	s_fmax.c s_fmaxf.c s_fmin.c \
 	s_fmax.c s_fmaxf.c s_fmin.c \
 	s_fminf.c s_fpclassify.c \
 	s_fminf.c s_fpclassify.c \
 	s_frexp.c s_frexpf.c s_ilogb.c s_ilogbf.c \
 	s_frexp.c s_frexpf.c s_ilogb.c s_ilogbf.c \
 	s_isinf.c s_isfinite.c s_isnormal.c s_isnan.c \
 	s_isinf.c s_isfinite.c s_isnormal.c s_isnan.c \
-	s_llrint.c s_llrintf.c s_llround.c s_llroundf.c  \
-	s_log1p.c s_log1pf.c s_logb.c s_logbf.c s_lrint.c s_lrintf.c \
-	s_lround.c s_lroundf.c s_modf.c s_modff.c \
-	s_nearbyint.c s_nextafter.c s_nextafterf.c \
+	s_log1p.c s_log1pf.c s_logb.c s_logbf.c \
+	s_modf.c s_modff.c \
+	s_nextafter.c s_nextafterf.c \
 	s_nexttowardf.c s_remquo.c s_remquof.c \
 	s_nexttowardf.c s_remquo.c s_remquof.c \
 	s_rint.c s_rintf.c s_round.c s_roundf.c \
 	s_rint.c s_rintf.c s_round.c s_roundf.c \
 	s_scalbln.c s_scalbn.c s_scalbnf.c s_signbit.c \
 	s_scalbln.c s_scalbn.c s_scalbnf.c s_signbit.c \
@@ -32,10 +31,18 @@ $(CUR_SRCS) = common.c \
 	s_trunc.c s_truncf.c s_cpow.c  s_cpowf.c \
 	s_trunc.c s_truncf.c s_cpow.c  s_cpowf.c \
 	w_cabs.c w_cabsf.c
 	w_cabs.c w_cabsf.c
 
 
+ifneq ($(ARCH), wasm32)
+
+$(CUR_SRCS) += \
+        s_fma.c s_fmaf.c s_lrint.c s_lrintf.c s_lround.c s_lroundf.c \
+	s_llrint.c s_llrintf.c s_llround.c s_llroundf.c s_nearbyint.c
+
 ifneq ($(OS), WINNT)
 ifneq ($(OS), WINNT)
 $(CUR_SRCS) += s_nan.c
 $(CUR_SRCS) += s_nan.c
 endif
 endif
 
 
+endif
+
 # Add in long double functions for x86, x64 and aarch64
 # Add in long double functions for x86, x64 and aarch64
 ifneq ($(filter $(ARCH),i387 amd64 aarch64),)
 ifneq ($(filter $(ARCH),i387 amd64 aarch64),)
 # C99 long double functions
 # C99 long double functions

+ 4 - 0
src/cdefs-compat.h

@@ -21,6 +21,10 @@
 #endif /* __APPLE__ */
 #endif /* __APPLE__ */
 #endif /* __strong_reference */
 #endif /* __strong_reference */
 
 
+#ifdef __wasm__
+#  define __weak_reference(sym,alias) __strong_reference(sym,alias)
+#endif
+
 #ifndef __weak_reference
 #ifndef __weak_reference
 #ifdef __ELF__
 #ifdef __ELF__
 #ifdef __STDC__
 #ifdef __STDC__

+ 2 - 0
src/s_fdim.c

@@ -43,4 +43,6 @@ fn(type x, type y)			\
 
 
 DECL(double, fdim)
 DECL(double, fdim)
 DECL(float, fdimf)
 DECL(float, fdimf)
+#ifdef OLM_LONG_DOUBLE
 DECL(long double, fdiml)
 DECL(long double, fdiml)
+#endif

+ 2 - 0
src/s_scalbln.c

@@ -62,6 +62,7 @@ scalblnf (float x, long n)
 	return (scalbnf(x, in));
 	return (scalbnf(x, in));
 }
 }
 
 
+#ifdef OLM_LONG_DOUBLE
 OLM_DLLEXPORT long double
 OLM_DLLEXPORT long double
 scalblnl (long double x, long n)
 scalblnl (long double x, long n)
 {
 {
@@ -76,3 +77,4 @@ scalblnl (long double x, long n)
 	}
 	}
 	return (scalbnl(x, (int)n));
 	return (scalbnl(x, (int)n));
 }
 }
+#endif

+ 0 - 0
wasm32/Make.files


+ 1 - 0
wasm32/assert.h

@@ -0,0 +1 @@
+#define assert(x) ((void)0)

+ 33 - 0
wasm32/float.h

@@ -0,0 +1,33 @@
+#pragma once
+
+#define FLT_RADIX 2
+
+#define FLT_TRUE_MIN 1.40129846432481707092e-45F
+#define FLT_MIN 1.17549435082228750797e-38F
+#define FLT_MAX 3.40282346638528859812e+38F
+#define FLT_EPSILON 1.1920928955078125e-07F
+
+#define FLT_MANT_DIG 24
+#define FLT_MIN_EXP (-125)
+#define FLT_MAX_EXP 128
+#define FLT_HAS_SUBNORM 1
+
+#define FLT_DIG 6
+#define FLT_DECIMAL_DIG 9
+#define FLT_MIN_10_EXP (-37)
+#define FLT_MAX_10_EXP 38
+
+#define DBL_TRUE_MIN 4.94065645841246544177e-324
+#define DBL_MIN 2.22507385850720138309e-308
+#define DBL_MAX 1.79769313486231570815e+308
+#define DBL_EPSILON 2.22044604925031308085e-16
+
+#define DBL_MANT_DIG 53
+#define DBL_MIN_EXP (-1021)
+#define DBL_MAX_EXP 1024
+#define DBL_HAS_SUBNORM 1
+
+#define DBL_DIG 15
+#define DBL_DECIMAL_DIG 17
+#define DBL_MIN_10_EXP (-307)
+#define DBL_MAX_10_EXP 308

+ 9 - 0
wasm32/limits.h

@@ -0,0 +1,9 @@
+#include <stdint.h>
+
+#define INT_MIN INT32_MIN
+#define INT_MAX INT32_MAX
+#define LONG_MIN INT32_MIN
+#define LONG_MAX INT32_MAX
+#define LLONG_MIN INT64_MIN
+#define LLONG_MAX INT64_MAX
+

+ 43 - 0
wasm32/stdint.h

@@ -0,0 +1,43 @@
+#pragma once
+
+typedef unsigned char      uint8_t;
+typedef unsigned short	   uint16_t;
+typedef unsigned int       uint32_t;
+typedef unsigned long long uint64_t;
+
+typedef char               int8_t;
+typedef short	           int16_t;
+typedef int                int32_t;
+typedef long long          int64_t;
+
+typedef unsigned int       uintptr_t;
+typedef int                intptr_t;
+
+_Static_assert(sizeof (uint8_t)  == 1, "invalid size");
+_Static_assert(sizeof (uint16_t) == 2, "invalid size");
+_Static_assert(sizeof (uint32_t) == 4, "invalid size");
+_Static_assert(sizeof (uint64_t) == 8, "invalid size");
+
+_Static_assert(sizeof (int8_t)  == 1, "invalid size");
+_Static_assert(sizeof (int16_t) == 2, "invalid size");
+_Static_assert(sizeof (int32_t) == 4, "invalid size");
+_Static_assert(sizeof (int64_t) == 8, "invalid size");
+
+_Static_assert(sizeof (uintptr_t) == sizeof (intptr_t), "invalid size");
+_Static_assert(sizeof (uintptr_t) == sizeof (void*), "invalid size");
+_Static_assert(sizeof (uintptr_t) == 4, "invalid size");
+
+#define UINT8_MAX  0xFF
+#define UINT16_MAX 0xFFFF
+#define UINT32_MAX 0xFFFFFFFFUL
+#define UINT64_MAX 0xFFFFFFFFFFFFFFFFULL
+
+#define INT8_MAX   0x7F
+#define INT16_MAX  0x7FFF
+#define INT32_MAX  0x7FFFFFFF
+#define INT64_MAX  0x7FFFFFFFFFFFFFFF
+
+#define INT8_MIN   (-0x80)
+#define INT16_MIN  (-0x8000)
+#define INT32_MIN  (-0x80000000L)
+#define INT64_MIN  (-0x8000000000000000LL)