compiler: use the LLVM builtins everywhere
This gives some more optimization opportunities to LLVM, because it understands these intrinsics. For example, it might convert llvm.sqrt.f64 to llvm.sqrt.f32 if possible.
Этот коммит содержится в:
родитель
ef912a132d
коммит
b8a6a1f62b
8 изменённых файлов: 387 добавлений и 248 удалений
2
Makefile
2
Makefile
|
@ -761,6 +761,7 @@ endif
|
||||||
@cp -rp lib/musl/src/internal build/release/tinygo/lib/musl/src
|
@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/malloc build/release/tinygo/lib/musl/src
|
||||||
@cp -rp lib/musl/src/mman 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/signal build/release/tinygo/lib/musl/src
|
||||||
@cp -rp lib/musl/src/stdio 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
|
@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/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/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/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/picolibc-stdio.c build/release/tinygo/lib
|
||||||
@cp -rp lib/wasi-libc/sysroot build/release/tinygo/lib/wasi-libc/sysroot
|
@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
|
@cp -rp llvm-project/compiler-rt/lib/builtins build/release/tinygo/lib/compiler-rt-builtins
|
||||||
|
|
|
@ -156,8 +156,12 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(target, "arm") || strings.HasPrefix(target, "thumb") {
|
if strings.HasPrefix(target, "arm") || strings.HasPrefix(target, "thumb") {
|
||||||
|
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")
|
args = append(args, "-fshort-enums", "-fomit-frame-pointer", "-mfloat-abi=soft", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if strings.HasPrefix(target, "avr") {
|
if strings.HasPrefix(target, "avr") {
|
||||||
// AVR defaults to C float and double both being 32-bit. This deviates
|
// AVR defaults to C float and double both being 32-bit. This deviates
|
||||||
// from what most code (and certainly compiler-rt) expects. So we need
|
// from what most code (and certainly compiler-rt) expects. So we need
|
||||||
|
|
|
@ -78,7 +78,7 @@ func makeMinGWExtraLibs(tmpdir string) []*compileJob {
|
||||||
// .in files need to be preprocessed by a preprocessor (-E)
|
// .in files need to be preprocessed by a preprocessor (-E)
|
||||||
// first.
|
// first.
|
||||||
defpath = outpath + ".def"
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,6 +89,7 @@ var Musl = Library{
|
||||||
"-Wno-shift-op-parentheses",
|
"-Wno-shift-op-parentheses",
|
||||||
"-Wno-ignored-attributes",
|
"-Wno-ignored-attributes",
|
||||||
"-Wno-string-plus-int",
|
"-Wno-string-plus-int",
|
||||||
|
"-Wno-ignored-pragmas",
|
||||||
"-Qunused-arguments",
|
"-Qunused-arguments",
|
||||||
// Select include dirs. Don't include standard library includes
|
// Select include dirs. Don't include standard library includes
|
||||||
// (that would introduce host dependencies and other complications),
|
// (that would introduce host dependencies and other complications),
|
||||||
|
@ -117,6 +118,7 @@ var Musl = Library{
|
||||||
"legacy/*.c",
|
"legacy/*.c",
|
||||||
"malloc/*.c",
|
"malloc/*.c",
|
||||||
"mman/*.c",
|
"mman/*.c",
|
||||||
|
"math/*.c",
|
||||||
"signal/*.c",
|
"signal/*.c",
|
||||||
"stdio/*.c",
|
"stdio/*.c",
|
||||||
"string/*.c",
|
"string/*.c",
|
||||||
|
|
|
@ -19,7 +19,7 @@ var Picolibc = Library{
|
||||||
return f.Close()
|
return f.Close()
|
||||||
},
|
},
|
||||||
cflags: func(target, headerPath string) []string {
|
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{
|
return []string{
|
||||||
"-Werror",
|
"-Werror",
|
||||||
"-Wall",
|
"-Wall",
|
||||||
|
@ -27,219 +27,375 @@ var Picolibc = Library{
|
||||||
"-D_COMPILING_NEWLIB",
|
"-D_COMPILING_NEWLIB",
|
||||||
"-DHAVE_ALIAS_ATTRIBUTE",
|
"-DHAVE_ALIAS_ATTRIBUTE",
|
||||||
"-DTINY_STDIO",
|
"-DTINY_STDIO",
|
||||||
|
"-D_IEEE_LIBM",
|
||||||
"-nostdlibinc",
|
"-nostdlibinc",
|
||||||
"-isystem", picolibcDir + "/include",
|
"-isystem", newlibDir + "/libc/include",
|
||||||
"-I" + picolibcDir + "/tinystdio",
|
"-I" + newlibDir + "/libc/tinystdio",
|
||||||
|
"-I" + newlibDir + "/libm/common",
|
||||||
"-I" + headerPath,
|
"-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 {
|
librarySources: func(target string) []string {
|
||||||
return picolibcSources
|
return picolibcSources
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var picolibcSources = []string{
|
var picolibcSources = []string{
|
||||||
"../../../picolibc-stdio.c",
|
"../../picolibc-stdio.c",
|
||||||
|
|
||||||
"tinystdio/asprintf.c",
|
"libc/tinystdio/asprintf.c",
|
||||||
"tinystdio/atod_engine.c",
|
"libc/tinystdio/atod_engine.c",
|
||||||
"tinystdio/atod_ryu.c",
|
"libc/tinystdio/atod_ryu.c",
|
||||||
"tinystdio/atof_engine.c",
|
"libc/tinystdio/atof_engine.c",
|
||||||
"tinystdio/atof_ryu.c",
|
"libc/tinystdio/atof_ryu.c",
|
||||||
//"tinystdio/atold_engine.c", // have_long_double and not long_double_equals_double
|
//"libc/tinystdio/atold_engine.c", // have_long_double and not long_double_equals_double
|
||||||
"tinystdio/clearerr.c",
|
"libc/tinystdio/clearerr.c",
|
||||||
"tinystdio/compare_exchange.c",
|
"libc/tinystdio/compare_exchange.c",
|
||||||
"tinystdio/dtoa_data.c",
|
"libc/tinystdio/dtoa_data.c",
|
||||||
"tinystdio/dtoa_engine.c",
|
"libc/tinystdio/dtoa_engine.c",
|
||||||
"tinystdio/dtoa_ryu.c",
|
"libc/tinystdio/dtoa_ryu.c",
|
||||||
"tinystdio/ecvtbuf.c",
|
"libc/tinystdio/ecvtbuf.c",
|
||||||
"tinystdio/ecvt.c",
|
"libc/tinystdio/ecvt.c",
|
||||||
"tinystdio/ecvt_data.c",
|
"libc/tinystdio/ecvt_data.c",
|
||||||
"tinystdio/ecvtfbuf.c",
|
"libc/tinystdio/ecvtfbuf.c",
|
||||||
"tinystdio/ecvtf.c",
|
"libc/tinystdio/ecvtf.c",
|
||||||
"tinystdio/ecvtf_data.c",
|
"libc/tinystdio/ecvtf_data.c",
|
||||||
"tinystdio/exchange.c",
|
"libc/tinystdio/exchange.c",
|
||||||
//"tinystdio/fclose.c", // posix-io
|
//"libc/tinystdio/fclose.c", // posix-io
|
||||||
"tinystdio/fcvtbuf.c",
|
"libc/tinystdio/fcvtbuf.c",
|
||||||
"tinystdio/fcvt.c",
|
"libc/tinystdio/fcvt.c",
|
||||||
"tinystdio/fcvtfbuf.c",
|
"libc/tinystdio/fcvtfbuf.c",
|
||||||
"tinystdio/fcvtf.c",
|
"libc/tinystdio/fcvtf.c",
|
||||||
"tinystdio/fdevopen.c",
|
"libc/tinystdio/fdevopen.c",
|
||||||
//"tinystdio/fdopen.c", // posix-io
|
//"libc/tinystdio/fdopen.c", // posix-io
|
||||||
"tinystdio/feof.c",
|
"libc/tinystdio/feof.c",
|
||||||
"tinystdio/ferror.c",
|
"libc/tinystdio/ferror.c",
|
||||||
"tinystdio/fflush.c",
|
"libc/tinystdio/fflush.c",
|
||||||
"tinystdio/fgetc.c",
|
"libc/tinystdio/fgetc.c",
|
||||||
"tinystdio/fgets.c",
|
"libc/tinystdio/fgets.c",
|
||||||
"tinystdio/fileno.c",
|
"libc/tinystdio/fileno.c",
|
||||||
"tinystdio/filestrget.c",
|
"libc/tinystdio/filestrget.c",
|
||||||
"tinystdio/filestrputalloc.c",
|
"libc/tinystdio/filestrputalloc.c",
|
||||||
"tinystdio/filestrput.c",
|
"libc/tinystdio/filestrput.c",
|
||||||
//"tinystdio/fopen.c", // posix-io
|
//"libc/tinystdio/fopen.c", // posix-io
|
||||||
"tinystdio/fprintf.c",
|
"libc/tinystdio/fprintf.c",
|
||||||
"tinystdio/fputc.c",
|
"libc/tinystdio/fputc.c",
|
||||||
"tinystdio/fputs.c",
|
"libc/tinystdio/fputs.c",
|
||||||
"tinystdio/fread.c",
|
"libc/tinystdio/fread.c",
|
||||||
"tinystdio/fscanf.c",
|
"libc/tinystdio/fscanf.c",
|
||||||
"tinystdio/fseek.c",
|
"libc/tinystdio/fseek.c",
|
||||||
"tinystdio/ftell.c",
|
"libc/tinystdio/ftell.c",
|
||||||
"tinystdio/ftoa_data.c",
|
"libc/tinystdio/ftoa_data.c",
|
||||||
"tinystdio/ftoa_engine.c",
|
"libc/tinystdio/ftoa_engine.c",
|
||||||
"tinystdio/ftoa_ryu.c",
|
"libc/tinystdio/ftoa_ryu.c",
|
||||||
"tinystdio/fwrite.c",
|
"libc/tinystdio/fwrite.c",
|
||||||
"tinystdio/gcvtbuf.c",
|
"libc/tinystdio/gcvtbuf.c",
|
||||||
"tinystdio/gcvt.c",
|
"libc/tinystdio/gcvt.c",
|
||||||
"tinystdio/gcvtfbuf.c",
|
"libc/tinystdio/gcvtfbuf.c",
|
||||||
"tinystdio/gcvtf.c",
|
"libc/tinystdio/gcvtf.c",
|
||||||
"tinystdio/getchar.c",
|
"libc/tinystdio/getchar.c",
|
||||||
"tinystdio/gets.c",
|
"libc/tinystdio/gets.c",
|
||||||
"tinystdio/matchcaseprefix.c",
|
"libc/tinystdio/matchcaseprefix.c",
|
||||||
"tinystdio/perror.c",
|
"libc/tinystdio/perror.c",
|
||||||
//"tinystdio/posixiob.c", // posix-io
|
//"libc/tinystdio/posixiob.c", // posix-io
|
||||||
//"tinystdio/posixio.c", // posix-io
|
//"libc/tinystdio/posixio.c", // posix-io
|
||||||
"tinystdio/printf.c",
|
"libc/tinystdio/printf.c",
|
||||||
"tinystdio/putchar.c",
|
"libc/tinystdio/putchar.c",
|
||||||
"tinystdio/puts.c",
|
"libc/tinystdio/puts.c",
|
||||||
"tinystdio/ryu_divpow2.c",
|
"libc/tinystdio/ryu_divpow2.c",
|
||||||
"tinystdio/ryu_log10.c",
|
"libc/tinystdio/ryu_log10.c",
|
||||||
"tinystdio/ryu_log2pow5.c",
|
"libc/tinystdio/ryu_log2pow5.c",
|
||||||
"tinystdio/ryu_pow5bits.c",
|
"libc/tinystdio/ryu_pow5bits.c",
|
||||||
"tinystdio/ryu_table.c",
|
"libc/tinystdio/ryu_table.c",
|
||||||
"tinystdio/ryu_umul128.c",
|
"libc/tinystdio/ryu_umul128.c",
|
||||||
"tinystdio/scanf.c",
|
"libc/tinystdio/scanf.c",
|
||||||
"tinystdio/setbuf.c",
|
"libc/tinystdio/setbuf.c",
|
||||||
"tinystdio/setvbuf.c",
|
"libc/tinystdio/setvbuf.c",
|
||||||
//"tinystdio/sflags.c", // posix-io
|
//"libc/tinystdio/sflags.c", // posix-io
|
||||||
"tinystdio/snprintf.c",
|
"libc/tinystdio/snprintf.c",
|
||||||
"tinystdio/snprintfd.c",
|
"libc/tinystdio/snprintfd.c",
|
||||||
"tinystdio/snprintff.c",
|
"libc/tinystdio/snprintff.c",
|
||||||
"tinystdio/sprintf.c",
|
"libc/tinystdio/sprintf.c",
|
||||||
"tinystdio/sprintfd.c",
|
"libc/tinystdio/sprintfd.c",
|
||||||
"tinystdio/sprintff.c",
|
"libc/tinystdio/sprintff.c",
|
||||||
"tinystdio/sscanf.c",
|
"libc/tinystdio/sscanf.c",
|
||||||
"tinystdio/strfromd.c",
|
"libc/tinystdio/strfromd.c",
|
||||||
"tinystdio/strfromf.c",
|
"libc/tinystdio/strfromf.c",
|
||||||
"tinystdio/strtod.c",
|
"libc/tinystdio/strtod.c",
|
||||||
"tinystdio/strtod_l.c",
|
"libc/tinystdio/strtod_l.c",
|
||||||
"tinystdio/strtof.c",
|
"libc/tinystdio/strtof.c",
|
||||||
//"tinystdio/strtold.c", // have_long_double and not long_double_equals_double
|
//"libc/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
|
//"libc/tinystdio/strtold_l.c", // have_long_double and not long_double_equals_double
|
||||||
"tinystdio/ungetc.c",
|
"libc/tinystdio/ungetc.c",
|
||||||
"tinystdio/vasprintf.c",
|
"libc/tinystdio/vasprintf.c",
|
||||||
"tinystdio/vfiprintf.c",
|
"libc/tinystdio/vfiprintf.c",
|
||||||
"tinystdio/vfiscanf.c",
|
"libc/tinystdio/vfiscanf.c",
|
||||||
"tinystdio/vfprintf.c",
|
"libc/tinystdio/vfprintf.c",
|
||||||
"tinystdio/vfprintff.c",
|
"libc/tinystdio/vfprintff.c",
|
||||||
"tinystdio/vfscanf.c",
|
"libc/tinystdio/vfscanf.c",
|
||||||
"tinystdio/vfscanff.c",
|
"libc/tinystdio/vfscanff.c",
|
||||||
"tinystdio/vprintf.c",
|
"libc/tinystdio/vprintf.c",
|
||||||
"tinystdio/vscanf.c",
|
"libc/tinystdio/vscanf.c",
|
||||||
"tinystdio/vsnprintf.c",
|
"libc/tinystdio/vsnprintf.c",
|
||||||
"tinystdio/vsprintf.c",
|
"libc/tinystdio/vsprintf.c",
|
||||||
"tinystdio/vsscanf.c",
|
"libc/tinystdio/vsscanf.c",
|
||||||
|
|
||||||
"string/bcmp.c",
|
"libc/string/bcmp.c",
|
||||||
"string/bcopy.c",
|
"libc/string/bcopy.c",
|
||||||
"string/bzero.c",
|
"libc/string/bzero.c",
|
||||||
"string/explicit_bzero.c",
|
"libc/string/explicit_bzero.c",
|
||||||
"string/ffsl.c",
|
"libc/string/ffsl.c",
|
||||||
"string/ffsll.c",
|
"libc/string/ffsll.c",
|
||||||
"string/fls.c",
|
"libc/string/fls.c",
|
||||||
"string/flsl.c",
|
"libc/string/flsl.c",
|
||||||
"string/flsll.c",
|
"libc/string/flsll.c",
|
||||||
"string/gnu_basename.c",
|
"libc/string/gnu_basename.c",
|
||||||
"string/index.c",
|
"libc/string/index.c",
|
||||||
"string/memccpy.c",
|
"libc/string/memccpy.c",
|
||||||
"string/memchr.c",
|
"libc/string/memchr.c",
|
||||||
"string/memcmp.c",
|
"libc/string/memcmp.c",
|
||||||
"string/memcpy.c",
|
"libc/string/memcpy.c",
|
||||||
"string/memmem.c",
|
"libc/string/memmem.c",
|
||||||
"string/memmove.c",
|
"libc/string/memmove.c",
|
||||||
"string/mempcpy.c",
|
"libc/string/mempcpy.c",
|
||||||
"string/memrchr.c",
|
"libc/string/memrchr.c",
|
||||||
"string/memset.c",
|
"libc/string/memset.c",
|
||||||
"string/rawmemchr.c",
|
"libc/string/rawmemchr.c",
|
||||||
"string/rindex.c",
|
"libc/string/rindex.c",
|
||||||
"string/stpcpy.c",
|
"libc/string/stpcpy.c",
|
||||||
"string/stpncpy.c",
|
"libc/string/stpncpy.c",
|
||||||
"string/strcasecmp.c",
|
"libc/string/strcasecmp.c",
|
||||||
"string/strcasecmp_l.c",
|
"libc/string/strcasecmp_l.c",
|
||||||
"string/strcasestr.c",
|
"libc/string/strcasestr.c",
|
||||||
"string/strcat.c",
|
"libc/string/strcat.c",
|
||||||
"string/strchr.c",
|
"libc/string/strchr.c",
|
||||||
"string/strchrnul.c",
|
"libc/string/strchrnul.c",
|
||||||
"string/strcmp.c",
|
"libc/string/strcmp.c",
|
||||||
"string/strcoll.c",
|
"libc/string/strcoll.c",
|
||||||
"string/strcoll_l.c",
|
"libc/string/strcoll_l.c",
|
||||||
"string/strcpy.c",
|
"libc/string/strcpy.c",
|
||||||
"string/strcspn.c",
|
"libc/string/strcspn.c",
|
||||||
"string/strdup.c",
|
"libc/string/strdup.c",
|
||||||
"string/strerror.c",
|
"libc/string/strerror.c",
|
||||||
"string/strerror_r.c",
|
"libc/string/strerror_r.c",
|
||||||
"string/strlcat.c",
|
"libc/string/strlcat.c",
|
||||||
"string/strlcpy.c",
|
"libc/string/strlcpy.c",
|
||||||
"string/strlen.c",
|
"libc/string/strlen.c",
|
||||||
"string/strlwr.c",
|
"libc/string/strlwr.c",
|
||||||
"string/strncasecmp.c",
|
"libc/string/strncasecmp.c",
|
||||||
"string/strncasecmp_l.c",
|
"libc/string/strncasecmp_l.c",
|
||||||
"string/strncat.c",
|
"libc/string/strncat.c",
|
||||||
"string/strncmp.c",
|
"libc/string/strncmp.c",
|
||||||
"string/strncpy.c",
|
"libc/string/strncpy.c",
|
||||||
"string/strndup.c",
|
"libc/string/strndup.c",
|
||||||
"string/strnlen.c",
|
"libc/string/strnlen.c",
|
||||||
"string/strnstr.c",
|
"libc/string/strnstr.c",
|
||||||
"string/strpbrk.c",
|
"libc/string/strpbrk.c",
|
||||||
"string/strrchr.c",
|
"libc/string/strrchr.c",
|
||||||
"string/strsep.c",
|
"libc/string/strsep.c",
|
||||||
"string/strsignal.c",
|
"libc/string/strsignal.c",
|
||||||
"string/strspn.c",
|
"libc/string/strspn.c",
|
||||||
"string/strstr.c",
|
"libc/string/strstr.c",
|
||||||
"string/strtok.c",
|
"libc/string/strtok.c",
|
||||||
"string/strtok_r.c",
|
"libc/string/strtok_r.c",
|
||||||
"string/strupr.c",
|
"libc/string/strupr.c",
|
||||||
"string/strverscmp.c",
|
"libc/string/strverscmp.c",
|
||||||
"string/strxfrm.c",
|
"libc/string/strxfrm.c",
|
||||||
"string/strxfrm_l.c",
|
"libc/string/strxfrm_l.c",
|
||||||
"string/swab.c",
|
"libc/string/swab.c",
|
||||||
"string/timingsafe_bcmp.c",
|
"libc/string/timingsafe_bcmp.c",
|
||||||
"string/timingsafe_memcmp.c",
|
"libc/string/timingsafe_memcmp.c",
|
||||||
"string/u_strerr.c",
|
"libc/string/u_strerr.c",
|
||||||
"string/wcpcpy.c",
|
"libc/string/wcpcpy.c",
|
||||||
"string/wcpncpy.c",
|
"libc/string/wcpncpy.c",
|
||||||
"string/wcscasecmp.c",
|
"libc/string/wcscasecmp.c",
|
||||||
"string/wcscasecmp_l.c",
|
"libc/string/wcscasecmp_l.c",
|
||||||
"string/wcscat.c",
|
"libc/string/wcscat.c",
|
||||||
"string/wcschr.c",
|
"libc/string/wcschr.c",
|
||||||
"string/wcscmp.c",
|
"libc/string/wcscmp.c",
|
||||||
"string/wcscoll.c",
|
"libc/string/wcscoll.c",
|
||||||
"string/wcscoll_l.c",
|
"libc/string/wcscoll_l.c",
|
||||||
"string/wcscpy.c",
|
"libc/string/wcscpy.c",
|
||||||
"string/wcscspn.c",
|
"libc/string/wcscspn.c",
|
||||||
"string/wcsdup.c",
|
"libc/string/wcsdup.c",
|
||||||
"string/wcslcat.c",
|
"libc/string/wcslcat.c",
|
||||||
"string/wcslcpy.c",
|
"libc/string/wcslcpy.c",
|
||||||
"string/wcslen.c",
|
"libc/string/wcslen.c",
|
||||||
"string/wcsncasecmp.c",
|
"libc/string/wcsncasecmp.c",
|
||||||
"string/wcsncasecmp_l.c",
|
"libc/string/wcsncasecmp_l.c",
|
||||||
"string/wcsncat.c",
|
"libc/string/wcsncat.c",
|
||||||
"string/wcsncmp.c",
|
"libc/string/wcsncmp.c",
|
||||||
"string/wcsncpy.c",
|
"libc/string/wcsncpy.c",
|
||||||
"string/wcsnlen.c",
|
"libc/string/wcsnlen.c",
|
||||||
"string/wcspbrk.c",
|
"libc/string/wcspbrk.c",
|
||||||
"string/wcsrchr.c",
|
"libc/string/wcsrchr.c",
|
||||||
"string/wcsspn.c",
|
"libc/string/wcsspn.c",
|
||||||
"string/wcsstr.c",
|
"libc/string/wcsstr.c",
|
||||||
"string/wcstok.c",
|
"libc/string/wcstok.c",
|
||||||
"string/wcswidth.c",
|
"libc/string/wcswidth.c",
|
||||||
"string/wcsxfrm.c",
|
"libc/string/wcsxfrm.c",
|
||||||
"string/wcsxfrm_l.c",
|
"libc/string/wcsxfrm_l.c",
|
||||||
"string/wcwidth.c",
|
"libc/string/wcwidth.c",
|
||||||
"string/wmemchr.c",
|
"libc/string/wmemchr.c",
|
||||||
"string/wmemcmp.c",
|
"libc/string/wmemcmp.c",
|
||||||
"string/wmemcpy.c",
|
"libc/string/wmemcpy.c",
|
||||||
"string/wmemmove.c",
|
"libc/string/wmemmove.c",
|
||||||
"string/wmempcpy.c",
|
"libc/string/wmempcpy.c",
|
||||||
"string/wmemset.c",
|
"libc/string/wmemset.c",
|
||||||
"string/xpg_strerror_r.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",
|
||||||
}
|
}
|
||||||
|
|
|
@ -1657,10 +1657,7 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
|
||||||
name := fn.RelString(nil)
|
name := fn.RelString(nil)
|
||||||
switch {
|
switch {
|
||||||
case name == "math.Ceil" || name == "math.Floor" || name == "math.Sqrt" || name == "math.Trunc":
|
case name == "math.Ceil" || name == "math.Floor" || name == "math.Sqrt" || name == "math.Trunc":
|
||||||
result, ok := b.createMathOp(instr)
|
return b.createMathOp(instr), nil
|
||||||
if ok {
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
case name == "device.Asm" || name == "device/arm.Asm" || name == "device/arm64.Asm" || name == "device/avr.Asm" || name == "device/riscv.Asm":
|
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)
|
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":
|
case name == "device.AsmFull" || name == "device/arm.AsmFull" || name == "device/arm64.AsmFull" || name == "device/avr.AsmFull" || name == "device/riscv.AsmFull":
|
||||||
|
|
|
@ -88,49 +88,25 @@ var mathToLLVMMapping = map[string]string{
|
||||||
"math.Trunc": "llvm.trunc.f64",
|
"math.Trunc": "llvm.trunc.f64",
|
||||||
}
|
}
|
||||||
|
|
||||||
// createMathOp tries to lower the given call as a LLVM math intrinsic, if
|
// createMathOp lowers the given call as a LLVM math intrinsic. It returns the
|
||||||
// possible. It returns the call result if possible, and a boolean whether it
|
// resulting value.
|
||||||
// succeeded. If it doesn't succeed, the architecture doesn't support the given
|
func (b *builder) createMathOp(call *ssa.CallCommon) llvm.Value {
|
||||||
// intrinsic.
|
llvmName := mathToLLVMMapping[call.StaticCallee().RelString(nil)]
|
||||||
func (b *builder) createMathOp(call *ssa.CallCommon) (llvm.Value, bool) {
|
if llvmName == "" {
|
||||||
// Check whether this intrinsic is supported on the given GOARCH.
|
panic("unreachable: unknown math operation") // sanity check
|
||||||
// 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":
|
llvmFn := b.mod.NamedFunction(llvmName)
|
||||||
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.
|
|
||||||
}
|
|
||||||
|
|
||||||
llvmFn := b.mod.NamedFunction(mathToLLVMMapping[name])
|
|
||||||
if llvmFn.IsNil() {
|
if llvmFn.IsNil() {
|
||||||
// The intrinsic doesn't exist yet, so declare it.
|
// The intrinsic doesn't exist yet, so declare it.
|
||||||
// At the moment, all supported intrinsics have the form "double
|
// At the moment, all supported intrinsics have the form "double
|
||||||
// foo(double %x)" so we can hardcode the signature here.
|
// foo(double %x)" so we can hardcode the signature here.
|
||||||
llvmType := llvm.FunctionType(b.ctx.DoubleType(), []llvm.Type{b.ctx.DoubleType()}, false)
|
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.
|
// Create a call to the intrinsic.
|
||||||
args := make([]llvm.Value, len(call.Args))
|
args := make([]llvm.Value, len(call.Args))
|
||||||
for i, arg := range call.Args {
|
for i, arg := range call.Args {
|
||||||
args[i] = b.getValue(arg)
|
args[i] = b.getValue(arg)
|
||||||
}
|
}
|
||||||
return b.CreateCall(llvmFn, args, ""), true
|
return b.CreateCall(llvmFn, args, "")
|
||||||
}
|
}
|
||||||
|
|
12
compiler/testdata/intrinsics-cortex-m-qemu.ll
предоставленный
12
compiler/testdata/intrinsics-cortex-m-qemu.ll
предоставленный
|
@ -14,21 +14,23 @@ entry:
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden double @main.mySqrt(double %x, i8* %context) unnamed_addr #1 {
|
define hidden double @main.mySqrt(double %x, i8* %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
%0 = call double @math.Sqrt(double %x, i8* undef) #2
|
%0 = call double @llvm.sqrt.f64(double %x)
|
||||||
ret double %0
|
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
|
; Function Attrs: nounwind
|
||||||
define hidden double @main.myTrunc(double %x, i8* %context) unnamed_addr #1 {
|
define hidden double @main.myTrunc(double %x, i8* %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
%0 = call double @math.Trunc(double %x, i8* undef) #2
|
%0 = call double @llvm.trunc.f64(double %x)
|
||||||
ret double %0
|
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 #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 #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 }
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче