diff --git a/Makefile b/Makefile index 850b4b5b..63dada9b 100644 --- a/Makefile +++ b/Makefile @@ -761,6 +761,7 @@ endif @cp -rp lib/musl/src/internal build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/malloc build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/mman build/release/tinygo/lib/musl/src + @cp -rp lib/musl/src/math build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/signal build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/stdio build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/string build/release/tinygo/lib/musl/src @@ -779,6 +780,7 @@ endif @cp -rp lib/picolibc/newlib/libc/string build/release/tinygo/lib/picolibc/newlib/libc @cp -rp lib/picolibc/newlib/libc/tinystdio build/release/tinygo/lib/picolibc/newlib/libc @cp -rp lib/picolibc/newlib/libm/common build/release/tinygo/lib/picolibc/newlib/libm + @cp -rp lib/picolibc/newlib/libm/math build/release/tinygo/lib/picolibc/newlib/libm @cp -rp lib/picolibc-stdio.c build/release/tinygo/lib @cp -rp lib/wasi-libc/sysroot build/release/tinygo/lib/wasi-libc/sysroot @cp -rp llvm-project/compiler-rt/lib/builtins build/release/tinygo/lib/compiler-rt-builtins diff --git a/builder/library.go b/builder/library.go index 0de71808..385f1610 100644 --- a/builder/library.go +++ b/builder/library.go @@ -156,7 +156,11 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ } } if strings.HasPrefix(target, "arm") || strings.HasPrefix(target, "thumb") { - args = append(args, "-fshort-enums", "-fomit-frame-pointer", "-mfloat-abi=soft", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables") + if strings.Split(target, "-")[2] == "linux" { + args = append(args, "-fno-unwind-tables", "-fno-asynchronous-unwind-tables") + } else { + args = append(args, "-fshort-enums", "-fomit-frame-pointer", "-mfloat-abi=soft", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables") + } } if strings.HasPrefix(target, "avr") { // AVR defaults to C float and double both being 32-bit. This deviates diff --git a/builder/mingw-w64.go b/builder/mingw-w64.go index 135cae94..27fefee0 100644 --- a/builder/mingw-w64.go +++ b/builder/mingw-w64.go @@ -78,7 +78,7 @@ func makeMinGWExtraLibs(tmpdir string) []*compileJob { // .in files need to be preprocessed by a preprocessor (-E) // first. defpath = outpath + ".def" - err := runCCompiler("-E", "-x", "c", "-Wp,-w", "-P", "-DDEF_X64", "-o", defpath, inpath, "-I"+goenv.Get("TINYGOROOT")+"/lib/mingw-w64/mingw-w64-crt/def-include/") + err := runCCompiler("-E", "-x", "c", "-Wp,-w", "-P", "-DDEF_X64", "-DDATA", "-o", defpath, inpath, "-I"+goenv.Get("TINYGOROOT")+"/lib/mingw-w64/mingw-w64-crt/def-include/") if err != nil { return err } diff --git a/builder/musl.go b/builder/musl.go index 8a3716f0..a1967e37 100644 --- a/builder/musl.go +++ b/builder/musl.go @@ -89,6 +89,7 @@ var Musl = Library{ "-Wno-shift-op-parentheses", "-Wno-ignored-attributes", "-Wno-string-plus-int", + "-Wno-ignored-pragmas", "-Qunused-arguments", // Select include dirs. Don't include standard library includes // (that would introduce host dependencies and other complications), @@ -117,6 +118,7 @@ var Musl = Library{ "legacy/*.c", "malloc/*.c", "mman/*.c", + "math/*.c", "signal/*.c", "stdio/*.c", "string/*.c", diff --git a/builder/picolibc.go b/builder/picolibc.go index f1b061ae..d9025a41 100644 --- a/builder/picolibc.go +++ b/builder/picolibc.go @@ -19,7 +19,7 @@ var Picolibc = Library{ return f.Close() }, cflags: func(target, headerPath string) []string { - picolibcDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/picolibc/newlib/libc") + newlibDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/picolibc/newlib") return []string{ "-Werror", "-Wall", @@ -27,219 +27,375 @@ var Picolibc = Library{ "-D_COMPILING_NEWLIB", "-DHAVE_ALIAS_ATTRIBUTE", "-DTINY_STDIO", + "-D_IEEE_LIBM", "-nostdlibinc", - "-isystem", picolibcDir + "/include", - "-I" + picolibcDir + "/tinystdio", + "-isystem", newlibDir + "/libc/include", + "-I" + newlibDir + "/libc/tinystdio", + "-I" + newlibDir + "/libm/common", "-I" + headerPath, } }, - sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/picolibc/newlib/libc") }, + sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/picolibc/newlib") }, librarySources: func(target string) []string { return picolibcSources }, } var picolibcSources = []string{ - "../../../picolibc-stdio.c", + "../../picolibc-stdio.c", - "tinystdio/asprintf.c", - "tinystdio/atod_engine.c", - "tinystdio/atod_ryu.c", - "tinystdio/atof_engine.c", - "tinystdio/atof_ryu.c", - //"tinystdio/atold_engine.c", // have_long_double and not long_double_equals_double - "tinystdio/clearerr.c", - "tinystdio/compare_exchange.c", - "tinystdio/dtoa_data.c", - "tinystdio/dtoa_engine.c", - "tinystdio/dtoa_ryu.c", - "tinystdio/ecvtbuf.c", - "tinystdio/ecvt.c", - "tinystdio/ecvt_data.c", - "tinystdio/ecvtfbuf.c", - "tinystdio/ecvtf.c", - "tinystdio/ecvtf_data.c", - "tinystdio/exchange.c", - //"tinystdio/fclose.c", // posix-io - "tinystdio/fcvtbuf.c", - "tinystdio/fcvt.c", - "tinystdio/fcvtfbuf.c", - "tinystdio/fcvtf.c", - "tinystdio/fdevopen.c", - //"tinystdio/fdopen.c", // posix-io - "tinystdio/feof.c", - "tinystdio/ferror.c", - "tinystdio/fflush.c", - "tinystdio/fgetc.c", - "tinystdio/fgets.c", - "tinystdio/fileno.c", - "tinystdio/filestrget.c", - "tinystdio/filestrputalloc.c", - "tinystdio/filestrput.c", - //"tinystdio/fopen.c", // posix-io - "tinystdio/fprintf.c", - "tinystdio/fputc.c", - "tinystdio/fputs.c", - "tinystdio/fread.c", - "tinystdio/fscanf.c", - "tinystdio/fseek.c", - "tinystdio/ftell.c", - "tinystdio/ftoa_data.c", - "tinystdio/ftoa_engine.c", - "tinystdio/ftoa_ryu.c", - "tinystdio/fwrite.c", - "tinystdio/gcvtbuf.c", - "tinystdio/gcvt.c", - "tinystdio/gcvtfbuf.c", - "tinystdio/gcvtf.c", - "tinystdio/getchar.c", - "tinystdio/gets.c", - "tinystdio/matchcaseprefix.c", - "tinystdio/perror.c", - //"tinystdio/posixiob.c", // posix-io - //"tinystdio/posixio.c", // posix-io - "tinystdio/printf.c", - "tinystdio/putchar.c", - "tinystdio/puts.c", - "tinystdio/ryu_divpow2.c", - "tinystdio/ryu_log10.c", - "tinystdio/ryu_log2pow5.c", - "tinystdio/ryu_pow5bits.c", - "tinystdio/ryu_table.c", - "tinystdio/ryu_umul128.c", - "tinystdio/scanf.c", - "tinystdio/setbuf.c", - "tinystdio/setvbuf.c", - //"tinystdio/sflags.c", // posix-io - "tinystdio/snprintf.c", - "tinystdio/snprintfd.c", - "tinystdio/snprintff.c", - "tinystdio/sprintf.c", - "tinystdio/sprintfd.c", - "tinystdio/sprintff.c", - "tinystdio/sscanf.c", - "tinystdio/strfromd.c", - "tinystdio/strfromf.c", - "tinystdio/strtod.c", - "tinystdio/strtod_l.c", - "tinystdio/strtof.c", - //"tinystdio/strtold.c", // have_long_double and not long_double_equals_double - //"tinystdio/strtold_l.c", // have_long_double and not long_double_equals_double - "tinystdio/ungetc.c", - "tinystdio/vasprintf.c", - "tinystdio/vfiprintf.c", - "tinystdio/vfiscanf.c", - "tinystdio/vfprintf.c", - "tinystdio/vfprintff.c", - "tinystdio/vfscanf.c", - "tinystdio/vfscanff.c", - "tinystdio/vprintf.c", - "tinystdio/vscanf.c", - "tinystdio/vsnprintf.c", - "tinystdio/vsprintf.c", - "tinystdio/vsscanf.c", + "libc/tinystdio/asprintf.c", + "libc/tinystdio/atod_engine.c", + "libc/tinystdio/atod_ryu.c", + "libc/tinystdio/atof_engine.c", + "libc/tinystdio/atof_ryu.c", + //"libc/tinystdio/atold_engine.c", // have_long_double and not long_double_equals_double + "libc/tinystdio/clearerr.c", + "libc/tinystdio/compare_exchange.c", + "libc/tinystdio/dtoa_data.c", + "libc/tinystdio/dtoa_engine.c", + "libc/tinystdio/dtoa_ryu.c", + "libc/tinystdio/ecvtbuf.c", + "libc/tinystdio/ecvt.c", + "libc/tinystdio/ecvt_data.c", + "libc/tinystdio/ecvtfbuf.c", + "libc/tinystdio/ecvtf.c", + "libc/tinystdio/ecvtf_data.c", + "libc/tinystdio/exchange.c", + //"libc/tinystdio/fclose.c", // posix-io + "libc/tinystdio/fcvtbuf.c", + "libc/tinystdio/fcvt.c", + "libc/tinystdio/fcvtfbuf.c", + "libc/tinystdio/fcvtf.c", + "libc/tinystdio/fdevopen.c", + //"libc/tinystdio/fdopen.c", // posix-io + "libc/tinystdio/feof.c", + "libc/tinystdio/ferror.c", + "libc/tinystdio/fflush.c", + "libc/tinystdio/fgetc.c", + "libc/tinystdio/fgets.c", + "libc/tinystdio/fileno.c", + "libc/tinystdio/filestrget.c", + "libc/tinystdio/filestrputalloc.c", + "libc/tinystdio/filestrput.c", + //"libc/tinystdio/fopen.c", // posix-io + "libc/tinystdio/fprintf.c", + "libc/tinystdio/fputc.c", + "libc/tinystdio/fputs.c", + "libc/tinystdio/fread.c", + "libc/tinystdio/fscanf.c", + "libc/tinystdio/fseek.c", + "libc/tinystdio/ftell.c", + "libc/tinystdio/ftoa_data.c", + "libc/tinystdio/ftoa_engine.c", + "libc/tinystdio/ftoa_ryu.c", + "libc/tinystdio/fwrite.c", + "libc/tinystdio/gcvtbuf.c", + "libc/tinystdio/gcvt.c", + "libc/tinystdio/gcvtfbuf.c", + "libc/tinystdio/gcvtf.c", + "libc/tinystdio/getchar.c", + "libc/tinystdio/gets.c", + "libc/tinystdio/matchcaseprefix.c", + "libc/tinystdio/perror.c", + //"libc/tinystdio/posixiob.c", // posix-io + //"libc/tinystdio/posixio.c", // posix-io + "libc/tinystdio/printf.c", + "libc/tinystdio/putchar.c", + "libc/tinystdio/puts.c", + "libc/tinystdio/ryu_divpow2.c", + "libc/tinystdio/ryu_log10.c", + "libc/tinystdio/ryu_log2pow5.c", + "libc/tinystdio/ryu_pow5bits.c", + "libc/tinystdio/ryu_table.c", + "libc/tinystdio/ryu_umul128.c", + "libc/tinystdio/scanf.c", + "libc/tinystdio/setbuf.c", + "libc/tinystdio/setvbuf.c", + //"libc/tinystdio/sflags.c", // posix-io + "libc/tinystdio/snprintf.c", + "libc/tinystdio/snprintfd.c", + "libc/tinystdio/snprintff.c", + "libc/tinystdio/sprintf.c", + "libc/tinystdio/sprintfd.c", + "libc/tinystdio/sprintff.c", + "libc/tinystdio/sscanf.c", + "libc/tinystdio/strfromd.c", + "libc/tinystdio/strfromf.c", + "libc/tinystdio/strtod.c", + "libc/tinystdio/strtod_l.c", + "libc/tinystdio/strtof.c", + //"libc/tinystdio/strtold.c", // have_long_double and not long_double_equals_double + //"libc/tinystdio/strtold_l.c", // have_long_double and not long_double_equals_double + "libc/tinystdio/ungetc.c", + "libc/tinystdio/vasprintf.c", + "libc/tinystdio/vfiprintf.c", + "libc/tinystdio/vfiscanf.c", + "libc/tinystdio/vfprintf.c", + "libc/tinystdio/vfprintff.c", + "libc/tinystdio/vfscanf.c", + "libc/tinystdio/vfscanff.c", + "libc/tinystdio/vprintf.c", + "libc/tinystdio/vscanf.c", + "libc/tinystdio/vsnprintf.c", + "libc/tinystdio/vsprintf.c", + "libc/tinystdio/vsscanf.c", - "string/bcmp.c", - "string/bcopy.c", - "string/bzero.c", - "string/explicit_bzero.c", - "string/ffsl.c", - "string/ffsll.c", - "string/fls.c", - "string/flsl.c", - "string/flsll.c", - "string/gnu_basename.c", - "string/index.c", - "string/memccpy.c", - "string/memchr.c", - "string/memcmp.c", - "string/memcpy.c", - "string/memmem.c", - "string/memmove.c", - "string/mempcpy.c", - "string/memrchr.c", - "string/memset.c", - "string/rawmemchr.c", - "string/rindex.c", - "string/stpcpy.c", - "string/stpncpy.c", - "string/strcasecmp.c", - "string/strcasecmp_l.c", - "string/strcasestr.c", - "string/strcat.c", - "string/strchr.c", - "string/strchrnul.c", - "string/strcmp.c", - "string/strcoll.c", - "string/strcoll_l.c", - "string/strcpy.c", - "string/strcspn.c", - "string/strdup.c", - "string/strerror.c", - "string/strerror_r.c", - "string/strlcat.c", - "string/strlcpy.c", - "string/strlen.c", - "string/strlwr.c", - "string/strncasecmp.c", - "string/strncasecmp_l.c", - "string/strncat.c", - "string/strncmp.c", - "string/strncpy.c", - "string/strndup.c", - "string/strnlen.c", - "string/strnstr.c", - "string/strpbrk.c", - "string/strrchr.c", - "string/strsep.c", - "string/strsignal.c", - "string/strspn.c", - "string/strstr.c", - "string/strtok.c", - "string/strtok_r.c", - "string/strupr.c", - "string/strverscmp.c", - "string/strxfrm.c", - "string/strxfrm_l.c", - "string/swab.c", - "string/timingsafe_bcmp.c", - "string/timingsafe_memcmp.c", - "string/u_strerr.c", - "string/wcpcpy.c", - "string/wcpncpy.c", - "string/wcscasecmp.c", - "string/wcscasecmp_l.c", - "string/wcscat.c", - "string/wcschr.c", - "string/wcscmp.c", - "string/wcscoll.c", - "string/wcscoll_l.c", - "string/wcscpy.c", - "string/wcscspn.c", - "string/wcsdup.c", - "string/wcslcat.c", - "string/wcslcpy.c", - "string/wcslen.c", - "string/wcsncasecmp.c", - "string/wcsncasecmp_l.c", - "string/wcsncat.c", - "string/wcsncmp.c", - "string/wcsncpy.c", - "string/wcsnlen.c", - "string/wcspbrk.c", - "string/wcsrchr.c", - "string/wcsspn.c", - "string/wcsstr.c", - "string/wcstok.c", - "string/wcswidth.c", - "string/wcsxfrm.c", - "string/wcsxfrm_l.c", - "string/wcwidth.c", - "string/wmemchr.c", - "string/wmemcmp.c", - "string/wmemcpy.c", - "string/wmemmove.c", - "string/wmempcpy.c", - "string/wmemset.c", - "string/xpg_strerror_r.c", + "libc/string/bcmp.c", + "libc/string/bcopy.c", + "libc/string/bzero.c", + "libc/string/explicit_bzero.c", + "libc/string/ffsl.c", + "libc/string/ffsll.c", + "libc/string/fls.c", + "libc/string/flsl.c", + "libc/string/flsll.c", + "libc/string/gnu_basename.c", + "libc/string/index.c", + "libc/string/memccpy.c", + "libc/string/memchr.c", + "libc/string/memcmp.c", + "libc/string/memcpy.c", + "libc/string/memmem.c", + "libc/string/memmove.c", + "libc/string/mempcpy.c", + "libc/string/memrchr.c", + "libc/string/memset.c", + "libc/string/rawmemchr.c", + "libc/string/rindex.c", + "libc/string/stpcpy.c", + "libc/string/stpncpy.c", + "libc/string/strcasecmp.c", + "libc/string/strcasecmp_l.c", + "libc/string/strcasestr.c", + "libc/string/strcat.c", + "libc/string/strchr.c", + "libc/string/strchrnul.c", + "libc/string/strcmp.c", + "libc/string/strcoll.c", + "libc/string/strcoll_l.c", + "libc/string/strcpy.c", + "libc/string/strcspn.c", + "libc/string/strdup.c", + "libc/string/strerror.c", + "libc/string/strerror_r.c", + "libc/string/strlcat.c", + "libc/string/strlcpy.c", + "libc/string/strlen.c", + "libc/string/strlwr.c", + "libc/string/strncasecmp.c", + "libc/string/strncasecmp_l.c", + "libc/string/strncat.c", + "libc/string/strncmp.c", + "libc/string/strncpy.c", + "libc/string/strndup.c", + "libc/string/strnlen.c", + "libc/string/strnstr.c", + "libc/string/strpbrk.c", + "libc/string/strrchr.c", + "libc/string/strsep.c", + "libc/string/strsignal.c", + "libc/string/strspn.c", + "libc/string/strstr.c", + "libc/string/strtok.c", + "libc/string/strtok_r.c", + "libc/string/strupr.c", + "libc/string/strverscmp.c", + "libc/string/strxfrm.c", + "libc/string/strxfrm_l.c", + "libc/string/swab.c", + "libc/string/timingsafe_bcmp.c", + "libc/string/timingsafe_memcmp.c", + "libc/string/u_strerr.c", + "libc/string/wcpcpy.c", + "libc/string/wcpncpy.c", + "libc/string/wcscasecmp.c", + "libc/string/wcscasecmp_l.c", + "libc/string/wcscat.c", + "libc/string/wcschr.c", + "libc/string/wcscmp.c", + "libc/string/wcscoll.c", + "libc/string/wcscoll_l.c", + "libc/string/wcscpy.c", + "libc/string/wcscspn.c", + "libc/string/wcsdup.c", + "libc/string/wcslcat.c", + "libc/string/wcslcpy.c", + "libc/string/wcslen.c", + "libc/string/wcsncasecmp.c", + "libc/string/wcsncasecmp_l.c", + "libc/string/wcsncat.c", + "libc/string/wcsncmp.c", + "libc/string/wcsncpy.c", + "libc/string/wcsnlen.c", + "libc/string/wcspbrk.c", + "libc/string/wcsrchr.c", + "libc/string/wcsspn.c", + "libc/string/wcsstr.c", + "libc/string/wcstok.c", + "libc/string/wcswidth.c", + "libc/string/wcsxfrm.c", + "libc/string/wcsxfrm_l.c", + "libc/string/wcwidth.c", + "libc/string/wmemchr.c", + "libc/string/wmemcmp.c", + "libc/string/wmemcpy.c", + "libc/string/wmemmove.c", + "libc/string/wmempcpy.c", + "libc/string/wmemset.c", + "libc/string/xpg_strerror_r.c", + + "libm/common/sf_finite.c", + "libm/common/sf_copysign.c", + "libm/common/sf_modf.c", + "libm/common/sf_scalbn.c", + "libm/common/sf_cbrt.c", + "libm/common/sf_exp10.c", + "libm/common/sf_expm1.c", + "libm/common/sf_ilogb.c", + "libm/common/sf_infinity.c", + "libm/common/sf_isinf.c", + "libm/common/sf_isinff.c", + "libm/common/sf_isnan.c", + "libm/common/sf_isnanf.c", + "libm/common/sf_issignaling.c", + "libm/common/sf_log1p.c", + "libm/common/sf_nan.c", + "libm/common/sf_nextafter.c", + "libm/common/sf_pow10.c", + "libm/common/sf_rint.c", + "libm/common/sf_logb.c", + "libm/common/sf_fdim.c", + "libm/common/sf_fma.c", + "libm/common/sf_fmax.c", + "libm/common/sf_fmin.c", + "libm/common/sf_fpclassify.c", + "libm/common/sf_lrint.c", + "libm/common/sf_llrint.c", + "libm/common/sf_lround.c", + "libm/common/sf_llround.c", + "libm/common/sf_nearbyint.c", + "libm/common/sf_remquo.c", + "libm/common/sf_round.c", + "libm/common/sf_scalbln.c", + "libm/common/sf_trunc.c", + "libm/common/sf_exp.c", + "libm/common/sf_exp2.c", + "libm/common/sf_exp2_data.c", + "libm/common/sf_log.c", + "libm/common/sf_log_data.c", + "libm/common/sf_log2.c", + "libm/common/sf_log2_data.c", + "libm/common/sf_pow_log2_data.c", + "libm/common/sf_pow.c", + + "libm/common/s_finite.c", + "libm/common/s_copysign.c", + "libm/common/s_modf.c", + "libm/common/s_scalbn.c", + "libm/common/s_cbrt.c", + "libm/common/s_exp10.c", + "libm/common/s_expm1.c", + "libm/common/s_ilogb.c", + "libm/common/s_infinity.c", + "libm/common/s_isinf.c", + "libm/common/s_isinfd.c", + "libm/common/s_isnan.c", + "libm/common/s_isnand.c", + "libm/common/s_issignaling.c", + "libm/common/s_log1p.c", + "libm/common/s_nan.c", + "libm/common/s_nextafter.c", + "libm/common/s_pow10.c", + "libm/common/s_rint.c", + "libm/common/s_logb.c", + "libm/common/s_log2.c", + "libm/common/s_fdim.c", + "libm/common/s_fma.c", + "libm/common/s_fmax.c", + "libm/common/s_fmin.c", + "libm/common/s_fpclassify.c", + "libm/common/s_lrint.c", + "libm/common/s_llrint.c", + "libm/common/s_lround.c", + "libm/common/s_llround.c", + "libm/common/s_nearbyint.c", + "libm/common/s_remquo.c", + "libm/common/s_round.c", + "libm/common/s_scalbln.c", + "libm/common/s_signbit.c", + "libm/common/s_trunc.c", + + "libm/math/e_acos.c", + "libm/math/e_acosh.c", + "libm/math/e_asin.c", + "libm/math/e_atan2.c", + "libm/math/e_atanh.c", + "libm/math/e_cosh.c", + "libm/math/e_exp.c", + "libm/math/ef_acos.c", + "libm/math/ef_acosh.c", + "libm/math/ef_asin.c", + "libm/math/ef_atan2.c", + "libm/math/ef_atanh.c", + "libm/math/ef_cosh.c", + "libm/math/ef_exp.c", + "libm/math/ef_fmod.c", + "libm/math/ef_hypot.c", + "libm/math/ef_j0.c", + "libm/math/ef_j1.c", + "libm/math/ef_jn.c", + "libm/math/ef_lgamma.c", + "libm/math/ef_log10.c", + "libm/math/ef_log.c", + "libm/math/e_fmod.c", + "libm/math/ef_pow.c", + "libm/math/ef_remainder.c", + "libm/math/ef_rem_pio2.c", + "libm/math/ef_scalb.c", + "libm/math/ef_sinh.c", + "libm/math/ef_sqrt.c", + "libm/math/ef_tgamma.c", + "libm/math/e_hypot.c", + "libm/math/e_j0.c", + "libm/math/e_j1.c", + "libm/math/e_jn.c", + "libm/math/e_lgamma.c", + "libm/math/e_log10.c", + "libm/math/e_log.c", + "libm/math/e_pow.c", + "libm/math/e_remainder.c", + "libm/math/e_rem_pio2.c", + "libm/math/erf_lgamma.c", + "libm/math/er_lgamma.c", + "libm/math/e_scalb.c", + "libm/math/e_sinh.c", + "libm/math/e_sqrt.c", + "libm/math/e_tgamma.c", + "libm/math/s_asinh.c", + "libm/math/s_atan.c", + "libm/math/s_ceil.c", + "libm/math/s_cos.c", + "libm/math/s_erf.c", + "libm/math/s_fabs.c", + "libm/math/sf_asinh.c", + "libm/math/sf_atan.c", + "libm/math/sf_ceil.c", + "libm/math/sf_cos.c", + "libm/math/sf_erf.c", + "libm/math/sf_fabs.c", + "libm/math/sf_floor.c", + "libm/math/sf_frexp.c", + "libm/math/sf_ldexp.c", + "libm/math/s_floor.c", + "libm/math/s_frexp.c", + "libm/math/sf_signif.c", + "libm/math/sf_sin.c", + "libm/math/sf_tan.c", + "libm/math/sf_tanh.c", + "libm/math/s_ldexp.c", + "libm/math/s_signif.c", + "libm/math/s_sin.c", + "libm/math/s_tan.c", + "libm/math/s_tanh.c", } diff --git a/compiler/compiler.go b/compiler/compiler.go index 58a07c31..021755e8 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -1657,10 +1657,7 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error) name := fn.RelString(nil) switch { case name == "math.Ceil" || name == "math.Floor" || name == "math.Sqrt" || name == "math.Trunc": - result, ok := b.createMathOp(instr) - if ok { - return result, nil - } + return b.createMathOp(instr), nil case name == "device.Asm" || name == "device/arm.Asm" || name == "device/arm64.Asm" || name == "device/avr.Asm" || name == "device/riscv.Asm": return b.createInlineAsm(instr.Args) case name == "device.AsmFull" || name == "device/arm.AsmFull" || name == "device/arm64.AsmFull" || name == "device/avr.AsmFull" || name == "device/riscv.AsmFull": diff --git a/compiler/intrinsics.go b/compiler/intrinsics.go index eb07ccb9..71b3e8a2 100644 --- a/compiler/intrinsics.go +++ b/compiler/intrinsics.go @@ -88,49 +88,25 @@ var mathToLLVMMapping = map[string]string{ "math.Trunc": "llvm.trunc.f64", } -// createMathOp tries to lower the given call as a LLVM math intrinsic, if -// possible. It returns the call result if possible, and a boolean whether it -// succeeded. If it doesn't succeed, the architecture doesn't support the given -// intrinsic. -func (b *builder) createMathOp(call *ssa.CallCommon) (llvm.Value, bool) { - // Check whether this intrinsic is supported on the given GOARCH. - // If it is unsupported, this can have two reasons: - // - // 1. LLVM can expand the intrinsic inline (using float instructions), but - // the result doesn't pass the tests of the math package. - // 2. LLVM cannot expand the intrinsic inline, will therefore lower it as a - // libm function call, but the libm function call also fails the math - // package tests. - // - // Whatever the implementation, it must pass the tests in the math package - // so unfortunately only the below intrinsic+architecture combinations are - // supported. - name := call.StaticCallee().RelString(nil) - switch name { - case "math.Ceil", "math.Floor", "math.Trunc": - if b.GOARCH != "wasm" && b.GOARCH != "arm64" { - return llvm.Value{}, false - } - case "math.Sqrt": - if b.GOARCH != "wasm" && b.GOARCH != "amd64" && b.GOARCH != "386" { - return llvm.Value{}, false - } - default: - return llvm.Value{}, false // only the above functions are supported. +// createMathOp lowers the given call as a LLVM math intrinsic. It returns the +// resulting value. +func (b *builder) createMathOp(call *ssa.CallCommon) llvm.Value { + llvmName := mathToLLVMMapping[call.StaticCallee().RelString(nil)] + if llvmName == "" { + panic("unreachable: unknown math operation") // sanity check } - - llvmFn := b.mod.NamedFunction(mathToLLVMMapping[name]) + llvmFn := b.mod.NamedFunction(llvmName) if llvmFn.IsNil() { // The intrinsic doesn't exist yet, so declare it. // At the moment, all supported intrinsics have the form "double // foo(double %x)" so we can hardcode the signature here. llvmType := llvm.FunctionType(b.ctx.DoubleType(), []llvm.Type{b.ctx.DoubleType()}, false) - llvmFn = llvm.AddFunction(b.mod, mathToLLVMMapping[name], llvmType) + llvmFn = llvm.AddFunction(b.mod, llvmName, llvmType) } // Create a call to the intrinsic. args := make([]llvm.Value, len(call.Args)) for i, arg := range call.Args { args[i] = b.getValue(arg) } - return b.CreateCall(llvmFn, args, ""), true + return b.CreateCall(llvmFn, args, "") } diff --git a/compiler/testdata/intrinsics-cortex-m-qemu.ll b/compiler/testdata/intrinsics-cortex-m-qemu.ll index 9e4ec621..de29b2aa 100644 --- a/compiler/testdata/intrinsics-cortex-m-qemu.ll +++ b/compiler/testdata/intrinsics-cortex-m-qemu.ll @@ -14,21 +14,23 @@ entry: ; Function Attrs: nounwind define hidden double @main.mySqrt(double %x, i8* %context) unnamed_addr #1 { entry: - %0 = call double @math.Sqrt(double %x, i8* undef) #2 + %0 = call double @llvm.sqrt.f64(double %x) ret double %0 } -declare double @math.Sqrt(double, i8*) #0 +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare double @llvm.sqrt.f64(double) #2 ; Function Attrs: nounwind define hidden double @main.myTrunc(double %x, i8* %context) unnamed_addr #1 { entry: - %0 = call double @math.Trunc(double %x, i8* undef) #2 + %0 = call double @llvm.trunc.f64(double %x) ret double %0 } -declare double @math.Trunc(double, i8*) #0 +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare double @llvm.trunc.f64(double) #2 attributes #0 = { "target-features"="+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" } attributes #1 = { nounwind "target-features"="+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" } -attributes #2 = { nounwind } +attributes #2 = { nofree nosync nounwind readnone speculatable willreturn }