diff --git a/CMakeLists.txt b/CMakeLists.txt index 2939c8b..7a2b934 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,6 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") # By default JIT is OFF option(LLVM_JIT "Controls whether LLVM JIT compilation will be enabled, default is OFF" OFF) option(OMR_JIT "Controls whether NanoJIT compilation will be enabled, default is OFF" OFF) -option(MIR_JIT "Controls whether MIR JIT compilation will be enabled, default is OFF" OFF) option(STATIC_BUILD "Build static version of Ravi, default is OFF" OFF) option(COMPUTED_GOTO "Controls whether the interpreter switch will use computed gotos on gcc/clang, default is ON" ON) option(ASM_VM "Controls whether to use the new VM (not ready yet! so don't turn on)" OFF) @@ -28,6 +27,10 @@ if (LLVM_JIT OR OMR_JIT OR MIR_JIT) set(ASM_VM OFF) endif () +if (NOT WIN32 AND NOT LLVM_JIT AND NOT OMR_JIT AND NOT ASM_VM) + set(MIR_JIT ON) +endif () + if (MIR_JIT) if (MSVC OR WIN32) message(FATAL_ERROR "MIR_JIT is not supported when using MSVC and/or WIN32") @@ -37,7 +40,7 @@ if (MIR_JIT) endif() set(LLVM_JIT OFF) set(OMR_JIT OFF) - set(STATIC_BUILD ON) + set(STATIC_BUILD OFF) endif() if (ASM_VM) @@ -80,10 +83,7 @@ if (OMR_JIT) endif () if (MIR_JIT) - add_subdirectory(mir) - include_directories(mir) - include_directories(mir/c2mir) - set(MIRJIT_LIBRARIES c2mir) + include (cmake/mir.cmake) add_definitions(-DUSE_MIRJIT) message(STATUS "MIRJIT enabled") endif () @@ -127,20 +127,20 @@ elseif ((CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang endif () # set(SANITIZER_FLAGS "-fsanitize=address") set(LUA_COMPAT_FLAGS "-DLUA_COMPAT_5_2 -DLUA_COMPAT_5_1") - set(CMAKE_C_FLAGS "-std=c99 -DNDEBUG -O2 -fomit-frame-pointer -Wall -Wextra -Winline ${LUA_COMPAT_FLAGS} ${OS_FLAGS}") - set(CMAKE_C_FLAGS_DEBUG "${SANITIZER_FLAGS} -UNDEBUG -fno-omit-frame-pointer -std=c99 -O0 -g3 -Wall -Wextra ${LUA_COMPAT_FLAGS} ${OS_FLAGS}") - set(CMAKE_C_FLAGS_RELEASE "-std=c99 -DNDEBUG -O2 -fomit-frame-pointer -Wall -Wextra -Winline ${LUA_COMPAT_FLAGS} ${OS_FLAGS}") - set(CMAKE_C_FLAGS_RELWITHDEBINFO "${SANITIZER_FLAGS} -DNDEBUG -std=c99 -O2 -g3 -Wall -Wextra ${LUA_COMPAT_FLAGS} ${OS_FLAGS}") + set(CMAKE_C_FLAGS "-std=gnu11 -DNDEBUG -O2 -fomit-frame-pointer -Wall -Winline ${LUA_COMPAT_FLAGS} ${OS_FLAGS}") + set(CMAKE_C_FLAGS_DEBUG "${SANITIZER_FLAGS} -UNDEBUG -fno-omit-frame-pointer -std=gnu11 -O0 -g3 -Wall ${LUA_COMPAT_FLAGS} ${OS_FLAGS}") + set(CMAKE_C_FLAGS_RELEASE "-std=gnu11 -DNDEBUG -O2 -fomit-frame-pointer -Wall -Winline ${LUA_COMPAT_FLAGS} ${OS_FLAGS}") + set(CMAKE_C_FLAGS_RELWITHDEBINFO "${SANITIZER_FLAGS} -DNDEBUG -std=gnu11 -O2 -g3 -Wall ${LUA_COMPAT_FLAGS} ${OS_FLAGS}") set(CMAKE_CXX_FLAGS "-fno-rtti -O2 -fomit-frame-pointer -Wall -Wno-sign-compare -Winline -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} ${OS_FLAGS}") set(CMAKE_CXX_FLAGS_DEBUG "${SANITIZER_FLAGS} -UNDEBUG -fno-omit-frame-pointer -fno-rtti -O0 -g3 -Wall -Wno-sign-compare -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} ${OS_FLAGS}") set(CMAKE_CXX_FLAGS_RELEASE "-fno-rtti -DNDEBUG -O2 -fomit-frame-pointer -Wall -Wno-sign-compare -Winline -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} ${OS_FLAGS}") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${SANITIZER_FLAGS} -DNDEBUG -fno-rtti -O2 -g3 -Wall -Wno-sign-compare -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} ${OS_FLAGS}") elseif (APPLE) set(LUA_COMPAT_FLAGS "-DLUA_COMPAT_5_2 -DLUA_COMPAT_5_1") - set(CMAKE_C_FLAGS "-std=c99 -DNDEBUG -O2 -Wall -Wextra ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX") - set(CMAKE_C_FLAGS_DEBUG "-std=c99 -O0 -g3 -Wall -Wextra ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX") - set(CMAKE_C_FLAGS_RELEASE "-std=c99 -DNDEBUG -O2 -Wall -Wextra ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX") - set(CMAKE_C_FLAGS_RELWITHDEBINFO "-std=c99 -DNDEBUG -O2 -g3 -Wall -Wextra ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX") + set(CMAKE_C_FLAGS "-std=gnu11 -DNDEBUG -O2 -Wall ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX") + set(CMAKE_C_FLAGS_DEBUG "-std=gnu11 -O0 -g3 -Wall ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX") + set(CMAKE_C_FLAGS_RELEASE "-std=gnu11 -DNDEBUG -O2 -Wall ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX") + set(CMAKE_C_FLAGS_RELWITHDEBINFO "-std=gnu11 -DNDEBUG -O2 -g3 -Wall ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX") set(CMAKE_CXX_FLAGS "-O3 -DNDEBUG -Wall -fno-rtti -Wno-sign-compare -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX") set(CMAKE_CXX_FLAGS_DEBUG "-fno-rtti -O0 -g3 -Wall -Wno-sign-compare -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX") set(CMAKE_CXX_FLAGS_RELEASE "-fno-rtti -DNDEBUG -O2 -Wall -Wno-sign-compare -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX") @@ -415,7 +415,7 @@ if (LLVM_JIT) elseif (OMR_JIT) set(LIBRAVI_NAME libravilomr) elseif (MIR_JIT) - set(LIBRAVI_NAME libravimir) + set(LIBRAVI_NAME libravi) else () set(LIBRAVI_NAME libravinojit) endif () @@ -433,6 +433,9 @@ add_library(${LIBRAVI_NAME} ${LIBRAVI_BUILD_TYPE} ${DMR_C_SRCS} ${DMR_C_JIT_SRCS} ${ASMVM_DEPS} + ${MIR_HEADERS} + ${MIR_SRCS} + ${C2MIR_SRCS} ) if (EMBEDDED_DMRC) set(DMRC_DEF "USE_DMR_C=1") diff --git a/mir/LICENSE b/mir/LICENSE index 4221723..c8e33be 100644 --- a/mir/LICENSE +++ b/mir/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Vladimir Makarov +Copyright (c) 2018-2020 Vladimir Makarov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/mir/c2mir/c2mir.c b/mir/c2mir/c2mir.c index 595292c..9db08c9 100644 --- a/mir/c2mir/c2mir.c +++ b/mir/c2mir/c2mir.c @@ -1,5 +1,5 @@ /* This file is a part of MIR project. - Copyright (C) 2018, 2019 Vladimir Makarov . + Copyright (C) 2018-2020 Vladimir Makarov . */ /* C to MIR compiler. It is a four pass compiler: @@ -560,7 +560,7 @@ struct node { DEF_DLIST_CODE (node_t, op_link); struct token { - token_code_t code : 16; + int code : 16; /* token_code_t and EOF */ int processed_p : 16; pos_t pos; node_code_t node_code; @@ -606,14 +606,18 @@ static node_t new_node (c2m_ctx_t c2m_ctx, node_code_t nc) { return n; } -static node_t copy_node (c2m_ctx_t c2m_ctx, node_t n) { +static node_t copy_node_with_pos (c2m_ctx_t c2m_ctx, node_t n, pos_t pos) { node_t r = new_node (c2m_ctx, n->code); - r->pos = n->pos; + r->pos = pos; r->u = n->u; return r; } +static node_t copy_node (c2m_ctx_t c2m_ctx, node_t n) { + return copy_node_with_pos (c2m_ctx, n, n->pos); +} + static node_t new_pos_node (c2m_ctx_t c2m_ctx, node_code_t nc, pos_t p) { return add_pos (new_node (c2m_ctx, nc), p); } @@ -737,10 +741,10 @@ static token_t new_token (c2m_ctx_t c2m_ctx, pos_t pos, const char *repr, int to return token; } -static token_t copy_token (c2m_ctx_t c2m_ctx, token_t t) { - token_t token = new_token (c2m_ctx, t->pos, t->repr, t->code, t->node_code); +static token_t copy_token (c2m_ctx_t c2m_ctx, token_t t, pos_t pos) { + token_t token = new_token (c2m_ctx, pos, t->repr, t->code, t->node_code); - if (t->node != NULL) token->node = copy_node (c2m_ctx, t->node); + if (t->node != NULL) token->node = copy_node_with_pos (c2m_ctx, t->node, pos); return token; } @@ -1111,13 +1115,15 @@ static token_t get_next_pptoken_1 (c2m_ctx_t c2m_ctx, int header_p) { case '\r': case '\v': break; case '\n': - cs->pos.ln_pos = 0; if (comment_char < 0) { nl_p = TRUE; + pos = cs->pos; } else if (comment_char == '/') { comment_char = -1; nl_p = TRUE; + pos = cs->pos; } + cs->pos.ln_pos = 0; break; case '/': if (comment_char >= 0) break; @@ -1156,7 +1162,7 @@ static token_t get_next_pptoken_1 (c2m_ctx_t c2m_ctx, int header_p) { if (VARR_LENGTH (char, symbol_text) != 0) { cs_unget (c2m_ctx, curr_c); VARR_PUSH (char, symbol_text, '\0'); - return new_token_wo_uniq_repr (c2m_ctx, cs->pos, VARR_ADDR (char, symbol_text), + return new_token_wo_uniq_repr (c2m_ctx, nl_p ? pos : cs->pos, VARR_ADDR (char, symbol_text), nl_p ? '\n' : ' ', N_IGNORE); } if (header_p && (curr_c == '<' || curr_c == '\"')) { @@ -1739,6 +1745,7 @@ DEF_VARR (token_arr_t); typedef struct macro_call { macro_t macro; + pos_t pos; /* Var array of arguments, each arg is var array of tokens, NULL for args absence: */ VARR (token_arr_t) * args; int repl_pos; /* position in macro replacement */ @@ -1851,10 +1858,11 @@ static void finish_macros (c2m_ctx_t c2m_ctx) { if (macro_tab != NULL) HTAB_DESTROY (macro_t, macro_tab); } -static macro_call_t new_macro_call (macro_t m) { +static macro_call_t new_macro_call (macro_t m, pos_t pos) { macro_call_t mc = malloc (sizeof (struct macro_call)); mc->macro = m; + mc->pos = pos; mc->repl_pos = 0; mc->args = NULL; VARR_CREATE (token_t, mc->repl_buffer, 64); @@ -1936,7 +1944,7 @@ static void add_include_stream (c2m_ctx_t c2m_ctx, const char *fname) { assert (fname != NULL); if ((f = fopen (fname, "r")) == NULL) { - if (options->message_file != NULL) fprintf (f, "error in opening file %s\n", fname); + if (options->message_file != NULL) fprintf (stderr, "error in opening file %s\n", fname); longjmp (c2m_ctx->env, 1); // ??? } add_stream (c2m_ctx, f, fname, NULL); @@ -2096,7 +2104,7 @@ static void push_back (c2m_ctx_t c2m_ctx, VARR (token_t) * tokens) { #endif } -static void copy_and_push_back (c2m_ctx_t c2m_ctx, VARR (token_t) * tokens) { +static void copy_and_push_back (c2m_ctx_t c2m_ctx, VARR (token_t) * tokens, pos_t pos) { #ifdef C2MIR_PREPRO_DEBUG fprintf (stderr, "# copy & push back (macro call depth %d):", VARR_LENGTH (macro_call_t, macro_call_stack)); @@ -2105,7 +2113,7 @@ static void copy_and_push_back (c2m_ctx_t c2m_ctx, VARR (token_t) * tokens) { #ifdef C2MIR_PREPRO_DEBUG fprintf (stderr, " <%s>", get_token_str (VARR_GET (token_t, tokens, i))); #endif - unget_next_pptoken (c2m_ctx, copy_token (c2m_ctx, VARR_GET (token_t, tokens, i))); + unget_next_pptoken (c2m_ctx, copy_token (c2m_ctx, VARR_GET (token_t, tokens, i), pos)); } #ifdef C2MIR_PREPRO_DEBUG fprintf (stderr, "\n"); @@ -2499,7 +2507,7 @@ static void process_replacement (c2m_ctx_t c2m_ctx, macro_call_t mc) { #ifdef C2MIR_PREPRO_DEBUG fprintf (stderr, "# push back for macro %s call\n", mc->macro->id->repr); #endif - copy_and_push_back (c2m_ctx, arg); + copy_and_push_back (c2m_ctx, arg, mc->pos); unget_next_pptoken (c2m_ctx, new_token (c2m_ctx, t->pos, "", T_BOA, N_IGNORE)); #ifdef C2MIR_PREPRO_DEBUG fprintf (stderr, "# push back for macro %s call\n", mc->macro->id->repr); @@ -2512,7 +2520,7 @@ static void process_replacement (c2m_ctx_t c2m_ctx, macro_call_t mc) { } else if (t->code != ' ') { sharp_pos = -1; } - if (copy_p) t = copy_token (c2m_ctx, t); + if (copy_p) t = copy_token (c2m_ctx, t, mc->pos); add_token (mc->repl_buffer, t); } } @@ -2792,6 +2800,12 @@ static void process_directive (c2m_ctx_t c2m_ctx) { for (t1 = get_next_pptoken (c2m_ctx); t1->code != '\n'; t1 = get_next_pptoken (c2m_ctx)) add_to_temp_string (c2m_ctx, t1->repr); error (c2m_ctx, t->pos, "%s", VARR_ADDR (char, temp_string)); + } else if (!options->pedantic_p && strcmp (t->repr, "warning") == 0) { + VARR_TRUNC (char, temp_string, 0); + add_to_temp_string (c2m_ctx, "#warning"); + for (t1 = get_next_pptoken (c2m_ctx); t1->code != '\n'; t1 = get_next_pptoken (c2m_ctx)) + add_to_temp_string (c2m_ctx, t1->repr); + warning (c2m_ctx, t->pos, "%s", VARR_ADDR (char, temp_string)); } else if (strcmp (t->repr, "pragma") == 0) { skip_nl (c2m_ctx, NULL, temp_buffer); check_pragma (c2m_ctx, t, temp_buffer); @@ -2939,16 +2953,12 @@ static node_t parse_pre_expr (c2m_ctx_t c2m_ctx, VARR (token_t) * expr) { return NULL; } -static struct val eval (c2m_ctx_t c2m_ctx, node_t tree); - -static struct val eval_expr (c2m_ctx_t c2m_ctx, VARR (token_t) * expr_buffer, token_t if_token) { +static void replace_defined (c2m_ctx_t c2m_ctx, VARR (token_t) * expr_buffer) { int i, j, k, len; - token_t t, id, ppt; + token_t t, id; const char *res; struct macro macro_struct; macro_t tab_macro; - VARR (token_t) * temp_buffer; - node_t tree; for (i = 0; i < VARR_LENGTH (token_t, expr_buffer); i++) { /* Change defined ident and defined (ident) */ @@ -2981,6 +2991,17 @@ static struct val eval_expr (c2m_ctx_t c2m_ctx, VARR (token_t) * expr_buffer, to del_tokens (expr_buffer, i + 1, j - i); } } +} + +static struct val eval (c2m_ctx_t c2m_ctx, node_t tree); + +static struct val eval_expr (c2m_ctx_t c2m_ctx, VARR (token_t) * expr_buffer, token_t if_token) { + int i, j; + token_t t, ppt; + VARR (token_t) * temp_buffer; + node_t tree; + + replace_defined (c2m_ctx, expr_buffer); if (VARR_LENGTH (macro_call_t, macro_call_stack) != 0) error (c2m_ctx, if_token->pos, "#if/#elif inside a macro call"); assert (VARR_LENGTH (token_t, output_buffer) == 0 && !no_out_p); @@ -2989,6 +3010,7 @@ static struct val eval_expr (c2m_ctx_t c2m_ctx, VARR (token_t) * expr_buffer, to push_back (c2m_ctx, expr_buffer); no_out_p = TRUE; processing (c2m_ctx, TRUE); + replace_defined (c2m_ctx, output_buffer); no_out_p = FALSE; reverse_move_tokens (c2m_ctx, expr_buffer, output_buffer); VARR_CREATE (token_t, temp_buffer, VARR_LENGTH (token_t, expr_buffer)); @@ -3258,9 +3280,9 @@ static void processing (c2m_ctx_t c2m_ctx, int ignore_directive_p) { #ifdef C2MIR_PREPRO_DEBUG fprintf (stderr, "# push back \n"); #endif - mc = new_macro_call (m); + mc = new_macro_call (m, t->pos); add_tokens (mc->repl_buffer, m->replacement); - copy_and_push_back (c2m_ctx, do_concat (c2m_ctx, mc->repl_buffer)); + copy_and_push_back (c2m_ctx, do_concat (c2m_ctx, mc->repl_buffer), mc->pos); m->ignore_p = TRUE; VARR_PUSH (macro_call_t, macro_call_stack, mc); } else { /* macro with parameters */ @@ -3280,7 +3302,7 @@ static void processing (c2m_ctx_t c2m_ctx, int ignore_directive_p) { out_token (c2m_ctx, t); continue; } - mc = new_macro_call (m); + mc = new_macro_call (m, t->pos); find_args (c2m_ctx, mc); VARR_PUSH (macro_call_t, macro_call_stack, mc); process_replacement (c2m_ctx, mc); @@ -3768,7 +3790,8 @@ D (cond_expr) { D (assign_expr) { return right_op (c2m_ctx, no_err_p, T_ASSIGN, '=', cond_expr, assign_expr); } D (expr) { return right_op (c2m_ctx, no_err_p, ',', -1, assign_expr, expr); } -/* Declarations; */ +/* Declarations: */ +D (attr_spec); DA (declaration_specs); D (sc_spec); DA (type_spec); @@ -3790,10 +3813,40 @@ D (typedef_name); D (initializer); D (st_assert); +D (asm_spec) { + node_t r; + + PTN (T_ID); + if (strcmp (r->u.s.s, "__asm") != 0) PTFAIL (T_ID); + PT ('('); + while (! C (')')) { + PT (T_STR); + } + PT (')'); + return NULL; +} + +static node_t try_attr_spec (c2m_ctx_t c2m_ctx, pos_t pos) { + node_t r; + + if ((r = TRY (attr_spec)) != err_node) { + if (options->pedantic_p) + error (c2m_ctx, pos, "GCC attributes are not implemented"); + else + /*warning (c2m_ctx, pos, "GCC attributes are not implemented -- ignoring them")*/; + } else if ((r = TRY (asm_spec)) != err_node) { + if (options->pedantic_p) + error (c2m_ctx, pos, "asm is not implemented"); + else + /*warning (c2m_ctx, pos, "asm is not implemented -- ignoring it")*/; + } + return r; +} + D (declaration) { int typedef_p; node_t op, list, decl, spec, r; - pos_t pos; + pos_t pos, last_pos; if (C (T_STATIC_ASSERT)) { P (st_assert); @@ -3804,6 +3857,7 @@ D (declaration) { } else { PA (declaration_specs, curr_scope == top_scope ? (node_t) 1 : NULL); spec = r; + last_pos = spec->pos; list = new_node (c2m_ctx, N_LIST); if (C (';')) { op_append (list, new_node3 (c2m_ctx, N_SPEC_DECL, spec, new_node (c2m_ctx, N_IGNORE), @@ -3815,6 +3869,7 @@ D (declaration) { for (;;) { /* init-declarator */ P (declarator); decl = r; + last_pos = decl->pos; assert (decl->code == N_DECL); if (typedef_p) { op = NL_HEAD (decl->ops); @@ -3831,6 +3886,7 @@ D (declaration) { } } r = list; + try_attr_spec (c2m_ctx, last_pos); PT (';'); } return r; @@ -3892,11 +3948,7 @@ DA (declaration_specs) { prev_type_spec = r; } else if ((r = TRY_A (type_spec, prev_type_spec)) != err_node) { prev_type_spec = r; - } else if ((r = TRY (attr_spec)) != err_node) { - if (options->pedantic_p) - error (c2m_ctx, spec_pos, "GCC attributes are not implemented"); - else - warning (c2m_ctx, spec_pos, "GCC attributes are not implemented -- ignoring them"); + } else if ((r = try_attr_spec (c2m_ctx, spec_pos)) != err_node) { continue; } else break; @@ -5559,7 +5611,7 @@ static int incomplete_type_p (c2m_ctx_t c2m_ctx, struct type *type) { } case TM_FUNC: return ((type = type->u.func_type->ret_type) == NULL - || !void_type_p (type) && incomplete_type_p (c2m_ctx, type)); + || (!void_type_p (type) && incomplete_type_p (c2m_ctx, type))); default: return FALSE; } } @@ -8751,12 +8803,12 @@ static void check (c2m_ctx_t c2m_ctx, node_t r, node_t context) { another_e2 = another_case_expr2->attr; assert (another_e2->const_p && integer_type_p (another_e2->type)); if ((signed_p - && (e->u.i_val <= another_e->u.i_val && another_e->u.i_val <= e2->u.i_val - || e->u.i_val <= another_e2->u.i_val && another_e2->u.i_val <= e2->u.i_val)) + && ((e->u.i_val <= another_e->u.i_val && another_e->u.i_val <= e2->u.i_val) + || (e->u.i_val <= another_e2->u.i_val && another_e2->u.i_val <= e2->u.i_val))) || (!signed_p - && (e->u.u_val <= another_e->u.u_val && another_e->u.u_val <= e2->u.u_val - || e->u.u_val <= another_e2->u.u_val - && another_e2->u.u_val <= e2->u.u_val))) { + && ((e->u.u_val <= another_e->u.u_val && another_e->u.u_val <= e2->u.u_val) + || (e->u.u_val <= another_e2->u.u_val + && another_e2->u.u_val <= e2->u.u_val)))) { error (c2m_ctx, c->case_node->pos, "duplicate value in a range case"); break; } @@ -11720,7 +11772,7 @@ static void print_expr (MIR_context_t ctx, FILE *f, struct expr *e) { if (e->const_p) { fprintf (f, ", const = "); if (!integer_type_p (e->type)) { - fprintf (f, " %.*Lg\n", LDBL_DECIMAL_DIG, (long double) e->u.d_val); + fprintf (f, " %.*Lg\n", LDBL_MANT_DIG, (long double) e->u.d_val); } else if (signed_integer_type_p (e->type)) { fprintf (f, "%lld", (long long) e->u.i_val); } else { @@ -11749,9 +11801,9 @@ static void print_node (MIR_context_t ctx, FILE *f, node_t n, int indent, int at case N_U: fprintf (f, " %lluu", (unsigned long long) n->u.ul); goto expr; case N_UL: fprintf (f, " %lluul", (unsigned long long) n->u.ul); goto expr; case N_ULL: fprintf (f, " %lluull", (unsigned long long) n->u.ull); goto expr; - case N_F: fprintf (f, " %.*g", FLT_DECIMAL_DIG, (double) n->u.f); goto expr; - case N_D: fprintf (f, " %.*g", DBL_DECIMAL_DIG, (double) n->u.d); goto expr; - case N_LD: fprintf (f, " %.*Lg", LDBL_DECIMAL_DIG, (long double) n->u.ld); goto expr; + case N_F: fprintf (f, " %.*g", FLT_MANT_DIG, (double) n->u.f); goto expr; + case N_D: fprintf (f, " %.*g", DBL_MANT_DIG, (double) n->u.d); goto expr; + case N_LD: fprintf (f, " %.*Lg", LDBL_MANT_DIG, (long double) n->u.ld); goto expr; case N_CH: fprintf (f, " '"); print_char (f, n->u.ch); @@ -11957,8 +12009,11 @@ static void init_include_dirs (MIR_context_t ctx) { str = uniq_cstr (c2m_ctx, VARR_ADDR (char, temp_string)).s; VARR_PUSH (char_ptr_t, system_headers, str); } -#ifdef __linux__ +#if defined(__APPLE__) || defined(__unix__) VARR_PUSH (char_ptr_t, system_headers, "/usr/include"); +#if defined(__linux__) || defined(__x86_64__) + VARR_PUSH (char_ptr_t, system_headers, "/usr/include/x86_64-linux-gnu"); +#endif #endif VARR_PUSH (char_ptr_t, system_headers, NULL); header_dirs = (const char **) VARR_ADDR (char_ptr_t, headers); @@ -12087,7 +12142,7 @@ static const char *get_module_name (MIR_context_t ctx) { c2m_ctx_t c2m_ctx = *c2m_ctx_loc (ctx); static char str[50]; - sprintf (str, "M%d", options->module_num); + sprintf (str, "M%ld", (long) options->module_num); return str; } diff --git a/mir/c2mir/x86_64/cx86_64-code.c b/mir/c2mir/x86_64/cx86_64-code.c index 98d0905..6a260f4 100644 --- a/mir/c2mir/x86_64/cx86_64-code.c +++ b/mir/c2mir/x86_64/cx86_64-code.c @@ -1,5 +1,5 @@ /* This file is a part of MIR project. - Copyright (C) 2018, 2019 Vladimir Makarov . + Copyright (C) 2018-2020 Vladimir Makarov . */ #include "../mirc.h" diff --git a/mir/c2mir/x86_64/cx86_64.h b/mir/c2mir/x86_64/cx86_64.h index 4464976..a741dc1 100644 --- a/mir/c2mir/x86_64/cx86_64.h +++ b/mir/c2mir/x86_64/cx86_64.h @@ -1,5 +1,5 @@ /* This file is a part of MIR project. - Copyright (C) 2018, 2019 Vladimir Makarov . + Copyright (C) 2018-2020 Vladimir Makarov . */ #include diff --git a/mir/mir-bitmap.h b/mir/mir-bitmap.h index fde9564..084dee3 100644 --- a/mir/mir-bitmap.h +++ b/mir/mir-bitmap.h @@ -1,5 +1,5 @@ /* This file is a part of MIR project. - Copyright (C) 2018, 2019 Vladimir Makarov . + Copyright (C) 2018-2020 Vladimir Makarov . */ #ifndef MIR_BITMAP_H diff --git a/mir/mir-dlist.h b/mir/mir-dlist.h index 6da1972..1cd41da 100644 --- a/mir/mir-dlist.h +++ b/mir/mir-dlist.h @@ -1,5 +1,5 @@ /* This file is part of MIR project. - Copyright (C) 2018, 2019 Vladimir Makarov . + Copyright (C) 2018-2020 Vladimir Makarov . */ /* Typed doubly linked lists. */ diff --git a/mir/mir-gen-x86_64.c b/mir/mir-gen-x86_64.c index c0c725e..b74a5b9 100644 --- a/mir/mir-gen-x86_64.c +++ b/mir/mir-gen-x86_64.c @@ -1,5 +1,5 @@ /* This file is a part of MIR project. - Copyright (C) 2018, 2019 Vladimir Makarov . + Copyright (C) 2018-2020 Vladimir Makarov . */ #include diff --git a/mir/mir-gen.c b/mir/mir-gen.c index e7cc4e6..ff35aa6 100644 --- a/mir/mir-gen.c +++ b/mir/mir-gen.c @@ -1,5 +1,5 @@ /* This file is a part of MIR project. - Copyright (C) 2018, 2019 Vladimir Makarov . + Copyright (C) 2018-2020 Vladimir Makarov . */ /* Optimization pipeline: @@ -4182,7 +4182,7 @@ static void combine (MIR_context_t ctx) { for (bb_t bb = DLIST_HEAD (bb_t, curr_cfg->bbs); bb != NULL; bb = DLIST_NEXT (bb_t, bb)) { do { #if MIR_GEN_DEBUG - if (debug_file != NULL) fprintf (debug_file, "Processing bb%d\n", bb->index); + if (debug_file != NULL) fprintf (debug_file, "Processing bb%lu\n", (unsigned long) bb->index); #endif block_change_p = FALSE; curr_bb_hreg_ref_age++; diff --git a/mir/mir-gen.h b/mir/mir-gen.h index 0b4eec3..bec4252 100644 --- a/mir/mir-gen.h +++ b/mir/mir-gen.h @@ -1,5 +1,5 @@ /* This file is a part of MIR project. - Copyright (C) 2018, 2019 Vladimir Makarov . + Copyright (C) 2018-2020 Vladimir Makarov . */ #ifndef MIR_GEN_H diff --git a/mir/mir-hash.h b/mir/mir-hash.h index 22e7b80..88d08ad 100644 --- a/mir/mir-hash.h +++ b/mir/mir-hash.h @@ -1,6 +1,6 @@ /* This file is a part of MIR project. - Copyright (C) 2018, 2019 Vladimir Makarov . + Copyright (C) 2018-2020 Vladimir Makarov . */ /* Simple high-quality multiplicative hash passing demerphq-smhsher, diff --git a/mir/mir-htab.h b/mir/mir-htab.h index 5c6e780..44c343a 100644 --- a/mir/mir-htab.h +++ b/mir/mir-htab.h @@ -1,5 +1,5 @@ /* This file is a part of MIR project. - Copyright (C) 2018, 2019 Vladimir Makarov . + Copyright (C) 2018-2020 Vladimir Makarov . */ #ifndef MIR_HTAB_H diff --git a/mir/mir-interp.c b/mir/mir-interp.c index afdcf9d..3aece5d 100644 --- a/mir/mir-interp.c +++ b/mir/mir-interp.c @@ -1,5 +1,5 @@ /* This file is a part of MIR project. - Copyright (C) 2018, 2019 Vladimir Makarov . + Copyright (C) 2018-2020 Vladimir Makarov . File contains MIR interpreter which is an obligatory part of MIR API. */ @@ -731,7 +731,8 @@ static ALWAYS_INLINE int64_t get_mem_addr (MIR_val_t *bp, code_t c) { return bp[ } while (0) #if defined(__GNUC__) && !defined(__clang__) -#define OPTIMIZE __attribute__ ((__optimize__ ("O3"))) +#define OPTIMIZE \ + __attribute__ ((__optimize__ ("O2"))) __attribute__ ((__optimize__ ("-fno-ipa-cp-clone"))) #else #define OPTIMIZE #endif diff --git a/mir/mir-reduce.h b/mir/mir-reduce.h index f20aec5..baa77c3 100644 --- a/mir/mir-reduce.h +++ b/mir/mir-reduce.h @@ -1,5 +1,5 @@ /* This file is a part of MIR project. - Copyright (C) 2018, 2019 Vladimir Makarov . + Copyright (C) 2018-2020 Vladimir Makarov . */ #ifndef MIR_REDUCE_H @@ -123,7 +123,7 @@ static inline void _reduce_uint_write (struct reduce_data *data, uint32_t u) { assert (u < (1 << 7 * 4)); for (n = 1; n <= 4 && u >= (1 << 7 * n); n++) ; - _reduce_put (data, (1 << (8 - n)) | (u >> (n - 1) * 8) & 0xff); /* tag */ + _reduce_put (data, (1 << (8 - n)) | ((u >> (n - 1) * 8) & 0xff)); /* tag */ for (int i = 2; i <= n; i++) _reduce_put (data, (u >> (n - i) * 8) & 0xff); } @@ -365,7 +365,7 @@ static inline struct reduce_data *reduce_decode_start (reduce_reader_t reader, v static inline int reduce_decode_get (struct reduce_data *data) { uint8_t tag, hash_str[sizeof (uint64_t)]; uint32_t sym_len, ref_len, ref_ind, sym_pos, pos = 0, curr_ind = 0; - uint64_t r; + int64_t r; struct _reduce_decode_data *decode_data = &data->u.decode; reduce_reader_t reader = decode_data->reader; diff --git a/mir/mir-varr.h b/mir/mir-varr.h index e552ed4..181d781 100644 --- a/mir/mir-varr.h +++ b/mir/mir-varr.h @@ -1,5 +1,5 @@ /* This file is a part of MIR project. - Copyright (C) 2018, 2019 Vladimir Makarov . + Copyright (C) 2018-2020 Vladimir Makarov . */ #ifndef MIR_VARR_H diff --git a/mir/mir-x86_64.c b/mir/mir-x86_64.c index 21c523e..64c64ca 100644 --- a/mir/mir-x86_64.c +++ b/mir/mir-x86_64.c @@ -1,5 +1,5 @@ /* This file is a part of MIR project. - Copyright (C) 2018, 2019 Vladimir Makarov . + Copyright (C) 2018-2020 Vladimir Makarov . */ void *_MIR_get_bstart_builtin (MIR_context_t ctx) { diff --git a/mir/mir.c b/mir/mir.c index 749ef95..6b04ae1 100644 --- a/mir/mir.c +++ b/mir/mir.c @@ -1,5 +1,5 @@ /* This file is a part of MIR project. - Copyright (C) 2018, 2019 Vladimir Makarov . + Copyright (C) 2018-2020 Vladimir Makarov . */ #include "mir.h" @@ -723,6 +723,25 @@ const char *MIR_type_str (MIR_context_t ctx, MIR_type_t tp) { return str; } +static const char *mode_str (MIR_op_mode_t mode) { + switch (mode) { + case MIR_OP_REG: return "reg"; + case MIR_OP_HARD_REG: return "hard_reg"; + case MIR_OP_INT: return "int"; + case MIR_OP_UINT: return "uint"; + case MIR_OP_FLOAT: return "float"; + case MIR_OP_DOUBLE: return "double"; + case MIR_OP_LDOUBLE: return "ldouble"; + case MIR_OP_REF: return "ref"; + case MIR_OP_STR: return "str"; + case MIR_OP_MEM: return "mem"; + case MIR_OP_HARD_REG_MEM: return "hard_reg_mem"; + case MIR_OP_LABEL: return "label"; + case MIR_OP_BOUND: return "bound"; + default: return ""; + } +} + static MIR_item_t add_item (MIR_context_t ctx, MIR_item_t item) { int replace_p; MIR_item_t tab_item; @@ -1141,7 +1160,8 @@ MIR_reg_t MIR_new_func_reg (MIR_context_t ctx, MIR_func_t func, MIR_type_t type, MIR_var_t var; if (type != MIR_T_I64 && type != MIR_T_F && type != MIR_T_D && type != MIR_T_LD) - (*error_func) (MIR_reg_type_error, "wrong type for register %s: got '%s'", name, type_str(type)); + (*error_func) (MIR_reg_type_error, "wrong type for register %s: got '%s'", name, + type_str (type)); var.type = type; var.name = string_store (ctx, &strings, &string_tab, (MIR_str_t){strlen (name) + 1, name}).str.s; mir_assert (func != NULL); @@ -1208,7 +1228,8 @@ void MIR_finish_func (MIR_context_t ctx) { } else if (code == MIR_RET && actual_nops != curr_func->nres) { curr_func = NULL; (*error_func) (MIR_vararg_func_error, - "in instruction '%s': number of operands in return does not correspond number of function returns. Expected %d, got %d", + "in instruction '%s': number of operands in return does not correspond number " + "of function returns. Expected %d, got %d", insn_descs[code].name, curr_func->nres, actual_nops); } else if (MIR_call_code_p (code)) expr_p = FALSE; @@ -1253,7 +1274,9 @@ void MIR_finish_func (MIR_context_t ctx) { mir_assert (rd != NULL && insn->ops[i].u.mem.base == rd->reg); if (type2mode (rd->type) != MIR_OP_INT) { curr_func = NULL; - (*error_func) (MIR_reg_type_error, "in instruction '%s': base reg of non-integer type for operand #%d", insn_descs[code].name, i+1); + (*error_func) (MIR_reg_type_error, + "in instruction '%s': base reg of non-integer type for operand #%d", + insn_descs[code].name, i + 1); } } if (insn->ops[i].u.mem.index != 0) { @@ -1261,7 +1284,9 @@ void MIR_finish_func (MIR_context_t ctx) { mir_assert (rd != NULL && insn->ops[i].u.mem.index == rd->reg); if (type2mode (rd->type) != MIR_OP_INT) { curr_func = NULL; - (*error_func) (MIR_reg_type_error, "in instruction '%s': index reg of non-integer type for operand #%d", insn_descs[code].name, i+1); + (*error_func) (MIR_reg_type_error, + "in instruction '%s': index reg of non-integer type for operand #%d", + insn_descs[code].name, i + 1); } } mode = type2mode (insn->ops[i].u.mem.type); @@ -1282,12 +1307,15 @@ void MIR_finish_func (MIR_context_t ctx) { if (expected_mode != MIR_OP_UNDEF && (mode == MIR_OP_UINT ? MIR_OP_INT : mode) != expected_mode) { curr_func = NULL; - (*error_func) (MIR_op_mode_error, "in instruction '%s': unexpected operand mode for operand #%d. Got '%s', expected '%s'", - insn_descs[code].name, i+1, type_str(mode), type_str(expected_mode)); + (*error_func) (MIR_op_mode_error, + "in instruction '%s': unexpected operand mode for operand #%d. Got '%s', " + "expected '%s'", + insn_descs[code].name, i + 1, mode_str (mode), mode_str (expected_mode)); } if (out_p && !can_be_out_p) { curr_func = NULL; - (*error_func) (MIR_out_op_error, "in instruction '%s': wrong operand #%d for insn output", insn_descs[code].name, i+1); + (*error_func) (MIR_out_op_error, "in instruction '%s': wrong operand #%d for insn output", + insn_descs[code].name, i + 1); } } } @@ -1524,22 +1552,25 @@ void MIR_link (MIR_context_t ctx, void (*set_interface) (MIR_context_t ctx, MIR_ } static const char *insn_name (MIR_insn_code_t code) { - return code < 0 || code >= MIR_INSN_BOUND ? "" : insn_descs[code].name; + return (unsigned) code >= MIR_INSN_BOUND ? "" : insn_descs[code].name; } const char *MIR_insn_name (MIR_context_t ctx, MIR_insn_code_t code) { - if (code < 0 || code >= MIR_INSN_BOUND) + if ((unsigned) code >= MIR_INSN_BOUND) (*error_func) (MIR_wrong_param_value_error, "MIR_insn_name: wrong insn code %d", (int) code); return insn_descs[code].name; } static size_t insn_code_nops (MIR_context_t ctx, MIR_insn_code_t code) { /* 0 for calls */ - if (code < 0 || code >= MIR_INSN_BOUND) + if ((unsigned) code >= MIR_INSN_BOUND) (*error_func) (MIR_wrong_param_value_error, "insn_code_nops: wrong insn code %d", (int) code); return VARR_GET (size_t, insn_nops, code); } -size_t MIR_insn_nops (MIR_context_t ctx, MIR_insn_t insn) { mir_assert (insn != NULL); return insn->nops; } +size_t MIR_insn_nops (MIR_context_t ctx, MIR_insn_t insn) { + mir_assert (insn != NULL); + return insn->nops; +} MIR_op_mode_t _MIR_insn_code_op_mode (MIR_context_t ctx, MIR_insn_code_t code, size_t nop, int *out_p) { @@ -2082,9 +2113,9 @@ void MIR_output_op (MIR_context_t ctx, FILE *f, MIR_op_t op, MIR_func_t func) { case MIR_OP_HARD_REG: output_hard_reg (f, op.u.hard_reg); break; case MIR_OP_INT: fprintf (f, "%" PRId64, op.u.i); break; case MIR_OP_UINT: fprintf (f, "%" PRIu64, op.u.u); break; - case MIR_OP_FLOAT: fprintf (f, "%.*ef", FLT_DECIMAL_DIG, op.u.f); break; - case MIR_OP_DOUBLE: fprintf (f, "%.*e", DBL_DECIMAL_DIG, op.u.d); break; - case MIR_OP_LDOUBLE: fprintf (f, "%.*Le", LDBL_DECIMAL_DIG, op.u.ld); break; + case MIR_OP_FLOAT: fprintf (f, "%.*ef", FLT_MANT_DIG, op.u.f); break; + case MIR_OP_DOUBLE: fprintf (f, "%.*e", DBL_MANT_DIG, op.u.d); break; + case MIR_OP_LDOUBLE: fprintf (f, "%.*Le", LDBL_MANT_DIG, op.u.ld); break; case MIR_OP_MEM: case MIR_OP_HARD_REG_MEM: { MIR_reg_t no_reg = op.mode == MIR_OP_MEM ? 0 : MIR_NON_HARD_REG; @@ -2175,7 +2206,7 @@ void MIR_output_item (MIR_context_t ctx, FILE *f, MIR_item_t item) { MIR_expr_data_t expr_data; size_t i, nlocals; - mir_assert(f != NULL && item != NULL); + mir_assert (f != NULL && item != NULL); if (item->item_type == MIR_export_item) { fprintf (f, "\texport\t%s\n", item->u.export); return; @@ -2219,10 +2250,10 @@ void MIR_output_item (MIR_context_t ctx, FILE *f, MIR_item_t item) { case MIR_T_U32: fprintf (f, "%" PRIu32, ((uint32_t *) data->u.els)[i]); break; case MIR_T_I64: fprintf (f, "%" PRId64, ((int64_t *) data->u.els)[i]); break; case MIR_T_U64: fprintf (f, "%" PRIu64, ((uint64_t *) data->u.els)[i]); break; - case MIR_T_F: fprintf (f, "%.*ef", FLT_DECIMAL_DIG, ((float *) data->u.els)[i]); break; - case MIR_T_D: fprintf (f, "%.*e", DBL_DECIMAL_DIG, ((double *) data->u.els)[i]); break; + case MIR_T_F: fprintf (f, "%.*ef", FLT_MANT_DIG, ((float *) data->u.els)[i]); break; + case MIR_T_D: fprintf (f, "%.*e", DBL_MANT_DIG, ((double *) data->u.els)[i]); break; case MIR_T_LD: - fprintf (f, "%.*Le", LDBL_DECIMAL_DIG, ((long double *) data->u.els)[i]); + fprintf (f, "%.*Le", LDBL_MANT_DIG, ((long double *) data->u.els)[i]); break; /* only ptr as ref ??? */ case MIR_T_P: fprintf (f, "0x%" PRIxPTR, ((uintptr_t *) data->u.els)[i]); break; @@ -2265,7 +2296,7 @@ void MIR_output_item (MIR_context_t ctx, FILE *f, MIR_item_t item) { } void MIR_output_module (MIR_context_t ctx, FILE *f, MIR_module_t module) { - mir_assert(f != NULL && module != NULL); + mir_assert (f != NULL && module != NULL); fprintf (f, "%s:\tmodule\n", module->name); for (MIR_item_t item = DLIST_HEAD (MIR_item_t, module->items); item != NULL; item = DLIST_NEXT (MIR_item_t, item)) @@ -2274,7 +2305,7 @@ void MIR_output_module (MIR_context_t ctx, FILE *f, MIR_module_t module) { } void MIR_output (MIR_context_t ctx, FILE *f) { - mir_assert(f != NULL); + mir_assert (f != NULL); for (MIR_module_t module = DLIST_HEAD (MIR_module_t, all_modules); module != NULL; module = DLIST_NEXT (MIR_module_t, module)) MIR_output_module (ctx, f, module); @@ -3709,7 +3740,7 @@ static size_t reduce_writer (const void *start, size_t len, void *aux_data) { return n; } -void MIR_write_module_with_func (MIR_context_t ctx, const int (*writer) (MIR_context_t, uint8_t), +void MIR_write_module_with_func (MIR_context_t ctx, int (*const writer) (MIR_context_t, uint8_t), MIR_module_t module) { size_t len, str_len; @@ -3750,7 +3781,7 @@ void MIR_write_module_with_func (MIR_context_t ctx, const int (*writer) (MIR_con #endif } -void MIR_write_with_func (MIR_context_t ctx, const int (*writer) (MIR_context_t, uint8_t)) { +void MIR_write_with_func (MIR_context_t ctx, int (*const writer) (MIR_context_t, uint8_t)) { MIR_write_module_with_func (ctx, writer, NULL); } @@ -4090,7 +4121,7 @@ static size_t reduce_reader (void *start, size_t len, void *data) { return i; } -void MIR_read_with_func (MIR_context_t ctx, const int (*reader) (MIR_context_t)) { +void MIR_read_with_func (MIR_context_t ctx, int (*const reader) (MIR_context_t)) { int version; bin_tag_t tag; token_attr_t attr; @@ -4432,7 +4463,7 @@ enum token_code { #undef REP_SEP typedef struct token { - enum token_code code; + int code; /* enum token_code and EOF */ union { int64_t i; float f; diff --git a/mir/mir.h b/mir/mir.h index 0f9ffe1..f679eaf 100644 --- a/mir/mir.h +++ b/mir/mir.h @@ -1,5 +1,5 @@ /* This file is a part of MIR project. - Copyright (C) 2018, 2019 Vladimir Makarov . + Copyright (C) 2018-2020 Vladimir Makarov . */ #ifndef MIR_H @@ -492,11 +492,11 @@ extern void MIR_write (MIR_context_t ctx, FILE *f); extern void MIR_write_module (MIR_context_t ctx, FILE *f, MIR_module_t module); extern void MIR_read (MIR_context_t ctx, FILE *f); extern void MIR_write_with_func (MIR_context_t ctx, - const int (*writer_func) (MIR_context_t, uint8_t)); + int (*const writer_func) (MIR_context_t, uint8_t)); extern void MIR_write_module_with_func (MIR_context_t ctx, - const int (*writer_func) (MIR_context_t, uint8_t), + int (*const writer_func) (MIR_context_t, uint8_t), MIR_module_t module); -extern void MIR_read_with_func (MIR_context_t ctx, const int (*reader_func) (MIR_context_t)); +extern void MIR_read_with_func (MIR_context_t ctx, int (*const reader_func) (MIR_context_t)); #endif #if !MIR_NO_SCAN