浏览代码

wasm32 support (#192)

Daniel Mendler 6 年之前
父节点
当前提交
72f33a3bf9
共有 13 个文件被更改,包括 126 次插入8 次删除
  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
 
+ifeq ($(ARCH),wasm32)
+CC = clang-8
+USEGCC = 0
+CFLAGS_add += -fno-builtin -fno-strict-aliasing
+endif
+
 ifeq ($(USECLANG),1)
 USEGCC = 0
 CC = clang
@@ -118,6 +124,10 @@ SFLAGS_arch  += -m64
 LDFLAGS_arch += -m64
 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
 # we can conveniently get at them for targets that don't want the rest of
 # *FLAGS_add, such as the testing Makefile targets

+ 7 - 1
Makefile

@@ -49,7 +49,13 @@ endif
 .PHONY: all check test clean distclean \
 	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
 	test/test-double

+ 2 - 1
README.md

@@ -27,7 +27,8 @@ also supports arm, aarch64, ppc64le, and mips.
    Linux and Windows.
 3. Use `make USECLANG=1` to build with clang. This is the default on OS X, FreeBSD,
    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
    i686. GCC 4.8 is the minimum requirement for correct codegen on
    older 32-bit architectures.

+ 1 - 1
include/openlibm_math.h

@@ -25,7 +25,7 @@
     #define __WIN32__
 #endif
 
-#ifndef __arm__
+#if !defined(__arm__) && !defined(__wasm__)
 #define OLM_LONG_DOUBLE
 #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_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_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_fminf.c s_fpclassify.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_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_rint.c s_rintf.c s_round.c s_roundf.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 \
 	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)
 $(CUR_SRCS) += s_nan.c
 endif
 
+endif
+
 # Add in long double functions for x86, x64 and aarch64
 ifneq ($(filter $(ARCH),i387 amd64 aarch64),)
 # C99 long double functions

+ 4 - 0
src/cdefs-compat.h

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

+ 2 - 0
src/s_fdim.c

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

+ 2 - 0
src/s_scalbln.c

@@ -62,6 +62,7 @@ scalblnf (float x, long n)
 	return (scalbnf(x, in));
 }
 
+#ifdef OLM_LONG_DOUBLE
 OLM_DLLEXPORT long double
 scalblnl (long double x, long n)
 {
@@ -76,3 +77,4 @@ scalblnl (long double x, long 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)