From 98442e019d745f1d61983c071decfa3ebc1ff0cf Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Aug 2014 16:09:13 +0200 Subject: Added emscripten (emcc) support to build system and some build fixes --- Makefile | 29 ++++++++++++++++++++++++++++- frontends/ast/ast.cc | 4 ++++ frontends/ast/dpicall.cc | 14 +++++++++++++- kernel/celltypes.h | 4 ++-- kernel/compatibility.cc | 2 +- kernel/driver.cc | 10 ++++++++-- kernel/rtlil.cc | 4 ++++ kernel/rtlil.h | 5 ++--- kernel/yosys.cc | 25 +++++++++++++++++++++++-- passes/cmds/plugin.cc | 9 ++++++++- passes/cmds/show.cc | 9 ++++++++- 11 files changed, 101 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 8d7f2f8dd..ca595d9cd 100644 --- a/Makefile +++ b/Makefile @@ -2,11 +2,14 @@ CONFIG := clang # CONFIG := gcc # CONFIG := gcc-4.6 +# CONFIG := emcc # features (the more the better) ENABLE_TCL := 1 ENABLE_QT4 := 1 ENABLE_ABC := 1 +ENABLE_PLUGINS := 1 +ENABLE_READLINE := 1 ENABLE_VERIFIC := 0 # other configuration flags @@ -27,7 +30,7 @@ all: top-all CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -MD -DYOSYS_SRC='"$(shell pwd)"' -D_YOSYS_ -fPIC -I${DESTDIR}/include LDFLAGS = -L${DESTDIR}/lib -LDLIBS = -lstdc++ -lreadline -lm -lffi -ldl +LDLIBS = -lstdc++ -lm QMAKE = qmake-qt4 SED = sed @@ -72,6 +75,22 @@ CXX = gcc-4.6 CXXFLAGS += -std=gnu++0x -Os endif +ifeq ($(CONFIG),emcc) +CXX = emcc +CXXFLAGS += -std=c++11 -Os -Wno-warn-absolute-paths +CXXFLAGS := $(filter-out -ggdb,$(CXXFLAGS)) +endif + +ifeq ($(ENABLE_READLINE),1) +CXXFLAGS += -DYOSYS_ENABLE_READLINE +LDLIBS += -lreadline +endif + +ifeq ($(ENABLE_PLUGINS),1) +CXXFLAGS += -DYOSYS_ENABLE_PLUGINS +LDLIBS += -lffi -ldl +endif + ifeq ($(ENABLE_TCL),1) TCL_VERSION ?= tcl8.5 TCL_INCLUDE ?= /usr/include/$(TCL_VERSION) @@ -290,6 +309,14 @@ config-gcc: clean config-gcc-4.6: clean echo 'CONFIG := gcc-4.6' > Makefile.conf +config-emcc: clean + echo 'CONFIG := emcc' > Makefile.conf + echo 'ENABLE_TCL := 0' >> Makefile.conf + echo 'ENABLE_QT4 := 0' >> Makefile.conf + echo 'ENABLE_ABC := 0' >> Makefile.conf + echo 'ENABLE_PLUGINS := 0' >> Makefile.conf + echo 'ENABLE_READLINE := 0' >> Makefile.conf + config-gprof: clean echo 'CONFIG := gcc' > Makefile.conf echo 'ENABLE_GPROF := 1' >> Makefile.conf diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 2fc8f9835..1e43875ae 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -844,7 +844,11 @@ RTLIL::Const AstNode::realAsConst(int width) { double v = round(realvalue); RTLIL::Const result; +#ifdef EMSCRIPTEN + if (!isfinite(v)) { +#else if (!std::isfinite(v)) { +#endif result.bits = std::vector(width, RTLIL::State::Sx); } else { bool is_negative = v < 0; diff --git a/frontends/ast/dpicall.cc b/frontends/ast/dpicall.cc index b79bd59eb..2eb104fa0 100644 --- a/frontends/ast/dpicall.cc +++ b/frontends/ast/dpicall.cc @@ -17,9 +17,12 @@ * */ +#include "ast.h" + +#ifdef YOSYS_ENABLE_PLUGINS + #include #include -#include "ast.h" typedef void (*ffi_fptr) (); @@ -126,3 +129,12 @@ AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname, return newNode; } +#else /* YOSYS_ENABLE_PLUGINS */ + +AST::AstNode *AST::dpi_call(const std::string&, const std::string &fname, const std::vector&, const std::vector&) +{ + log_error("Can't call DPI function `%s': this version of yosys is built without plugin support\n", fname.c_str()); +} + +#endif /* YOSYS_ENABLE_PLUGINS */ + diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 8c2e9a48e..515da25ce 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -108,7 +108,7 @@ struct CellTypes for (auto type : std::vector({"$mux", "$pmux"})) setup_type(type, {"\\A", "\\B", "\\S"}, {"\\Y"}, true); - setup_type("$assert", {"\\A", "\\EN"}, {}, true); + setup_type("$assert", {"\\A", "\\EN"}, std::set(), true); } void setup_internals_mem() @@ -121,7 +121,7 @@ struct CellTypes setup_type("$dlatchsr", {"\\EN", "\\SET", "\\CLR", "\\D"}, {"\\Q"}); setup_type("$memrd", {"\\CLK", "\\ADDR"}, {"\\DATA"}); - setup_type("$memwr", {"\\CLK", "\\EN", "\\ADDR", "\\DATA"}, {}); + setup_type("$memwr", {"\\CLK", "\\EN", "\\ADDR", "\\DATA"}, std::set()); setup_type("$mem", {"\\RD_CLK", "\\RD_ADDR", "\\WR_CLK", "\\WR_EN", "\\WR_ADDR", "\\WR_DATA"}, {"\\RD_DATA"}); setup_type("$fsm", {"\\CLK", "\\ARST", "\\CTRL_IN"}, {"\\CTRL_OUT"}); diff --git a/kernel/compatibility.cc b/kernel/compatibility.cc index 2ef023eb3..4c4cbd6de 100644 --- a/kernel/compatibility.cc +++ b/kernel/compatibility.cc @@ -26,7 +26,7 @@ #include #include -#if !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L) +#if !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L || defined(EMSCRIPTEN)) typedef struct memstream { off_t pos; diff --git a/kernel/driver.cc b/kernel/driver.cc index 6bd60d7b5..e778e1389 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -20,8 +20,10 @@ #include "kernel/yosys.h" #include "libs/sha1/sha1.h" -#include -#include +#ifdef YOSYS_ENABLE_READLINE +# include +# include +#endif #include #include @@ -46,6 +48,7 @@ int main(int argc, char **argv) bool print_stats = true; bool call_abort = false; +#ifdef YOSYS_ENABLE_READLINE int history_offset = 0; std::string history_file; if (getenv("HOME") != NULL) { @@ -53,6 +56,7 @@ int main(int argc, char **argv) read_history(history_file.c_str()); history_offset = where_history(); } +#endif int opt; while ((opt = getopt(argc, argv, "AQTVSm:f:Hh:b:o:p:l:qv:ts:c:")) != -1) @@ -329,6 +333,7 @@ int main(int argc, char **argv) if (call_abort) abort(); +#ifdef YOSYS_ENABLE_READLINE if (!history_file.empty()) { if (history_offset > 0) { history_truncate_file(history_file.c_str(), 100); @@ -341,6 +346,7 @@ int main(int argc, char **argv) HIST_ENTRY **hist_list = history_list(); if (hist_list != NULL) free(hist_list); +#endif yosys_shutdown(); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 24cce6b8b..22bff7bdb 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1605,6 +1605,10 @@ RTLIL::Memory::Memory() size = 0; } +RTLIL::Cell::Cell() : module(nullptr) +{ +} + bool RTLIL::Cell::hasPort(RTLIL::IdString portname) const { return connections_.count(portname) != 0; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 8b3306f6f..ebfe4ca29 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -77,7 +77,7 @@ namespace RTLIL // the global id string cache struct char_ptr_cmp { - bool operator()(const char *a, const char *b) { + bool operator()(const char *a, const char *b) const { for (int i = 0; a[i] || b[i]; i++) if (a[i] != b[i]) return a[i] < b[i]; @@ -815,8 +815,7 @@ struct RTLIL::Cell protected: // use module->addCell() and module->remove() to create or destroy cells friend struct RTLIL::Module; - Cell() : module(nullptr) { }; - ~Cell() { }; + Cell(); public: // do not simply copy cells diff --git a/kernel/yosys.cc b/kernel/yosys.cc index ce2487314..7b8173b6a 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -19,12 +19,15 @@ #include "kernel/yosys.h" -#include -#include +#ifdef YOSYS_ENABLE_READLINE +# include +# include +#endif #include #include #include +#include YOSYS_NAMESPACE_BEGIN @@ -232,6 +235,11 @@ std::string proc_self_dirname () buflen--; return std::string(path, buflen); } +#elif defined(EMSCRIPTEN) +std::string proc_self_dirname () +{ + return "/"; +} #else #error Dont know how to determine process executable base path! #endif @@ -416,6 +424,7 @@ void run_backend(std::string filename, std::string command, RTLIL::Design *desig Backend::backend_call(design, NULL, filename, command); } +#ifdef YOSYS_ENABLE_READLINE static char *readline_cmd_generator(const char *text, int state) { static std::map::iterator it; @@ -493,6 +502,7 @@ static char **readline_completion(const char *text, int start, int) return rl_completion_matches(text, readline_obj_generator); return NULL; } +#endif void shell(RTLIL::Design *design) { @@ -501,16 +511,25 @@ void shell(RTLIL::Design *design) recursion_counter++; log_cmd_error_throw = true; +#ifdef YOSYS_ENABLE_READLINE rl_readline_name = "yosys"; rl_attempted_completion_function = readline_completion; rl_basic_word_break_characters = " \t\n"; +#endif char *command = NULL; +#ifdef YOSYS_ENABLE_READLINE while ((command = readline(create_prompt(design, recursion_counter))) != NULL) +#else + char command_buffer[4096]; + while ((command = fgets(command_buffer, 4096, stdin)) != NULL) +#endif { if (command[strspn(command, " \t\r\n")] == 0) continue; +#ifdef YOSYS_ENABLE_READLINE add_history(command); +#endif char *p = command + strspn(command, " \t\r\n"); if (!strncmp(p, "exit", 4)) { @@ -576,6 +595,7 @@ struct ShellPass : public Pass { } } ShellPass; +#ifdef YOSYS_ENABLE_READLINE struct HistoryPass : public Pass { HistoryPass() : Pass("history", "show last interactive commands") { } virtual void help() { @@ -593,6 +613,7 @@ struct HistoryPass : public Pass { log("%s\n", (*list)->line); } } HistoryPass; +#endif struct ScriptPass : public Pass { ScriptPass() : Pass("script", "execute commands from script file") { } diff --git a/passes/cmds/plugin.cc b/passes/cmds/plugin.cc index c73684f1b..4e8234d16 100644 --- a/passes/cmds/plugin.cc +++ b/passes/cmds/plugin.cc @@ -18,7 +18,10 @@ */ #include "kernel/yosys.h" -#include + +#ifdef YOSYS_ENABLE_PLUGINS +# include +#endif YOSYS_NAMESPACE_BEGIN @@ -27,6 +30,7 @@ std::map loaded_plugin_aliases; void load_plugin(std::string filename, std::vector aliases) { +#ifdef YOSYS_ENABLE_PLUGINS if (filename.find('/') == std::string::npos) filename = "./" + filename; @@ -40,6 +44,9 @@ void load_plugin(std::string filename, std::vector aliases) for (auto &alias : aliases) loaded_plugin_aliases[alias] = filename; +#else + log_error("This version of yosys is built without plugin support.\n"); +#endif } struct PluginPass : public Pass { diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 4f6b811bc..fc6e972ee 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -22,7 +22,10 @@ #include "kernel/log.h" #include #include -#include + +#ifdef YOSYS_ENABLE_READLINE +# include +#endif using RTLIL::id2cstr; @@ -770,6 +773,7 @@ struct ShowPass : public Pass { } if (flag_pause) { + #ifdef YOSYS_ENABLE_READLINE char *input = NULL; while ((input = readline("Press ENTER to continue (or type 'shell' to open a shell)> ")) != NULL) { if (input[strspn(input, " \t\r\n")] == 0) @@ -780,6 +784,9 @@ struct ShowPass : public Pass { break; } } + #else + log_cmd_error("This version of yosys is built without readline support => 'show -pause' is not available.\n"); + #endif } log_pop(); -- cgit v1.2.3