issue #169 apply fixes from MIR project

asmvm
Dibyendu Majumdar 4 years ago
parent 544ee84c66
commit a12d049d42

@ -20,6 +20,7 @@
#include <stdarg.h>
#include <errno.h>
#include <setjmp.h>
#include <math.h>
#include "time.h"
#include "c2mir.h"
@ -127,7 +128,8 @@ struct c2m_ctx {
HTAB (str_t) * str_key_tab;
str_t empty_str;
unsigned long curr_uid;
int (*c_getc) (void); /* c2mir interface get function */
int (*c_getc) (void *); /* c2mir interface get function */
void *c_getc_data;
unsigned n_errors, n_warnings;
VARR (char) * symbol_text, *temp_string;
VARR (token_t) * recorded_tokens, *buffered_tokens;
@ -159,6 +161,7 @@ typedef struct c2m_ctx *c2m_ctx_t;
#define empty_str c2m_ctx->empty_str
#define curr_uid c2m_ctx->curr_uid
#define c_getc c2m_ctx->c_getc
#define c_getc_data c2m_ctx->c_getc_data
#define n_errors c2m_ctx->n_errors
#define n_warnings c2m_ctx->n_warnings
#define symbol_text c2m_ctx->symbol_text
@ -1700,8 +1703,12 @@ static token_t pptoken2token (c2m_ctx_t c2m_ctx, token_t t, int id2kw_p) {
fprintf (options->message_file, "%s:%s:%s\n", repr, stop, &repr[last + 1]);
error (c2m_ctx, t->pos, "wrong number: %s", t->repr);
} else if (errno) {
(options->pedantic_p ? error : warning) (c2m_ctx, t->pos, "number %s is out of range",
t->repr);
if (float_p || double_p || ldouble_p) {
warning (c2m_ctx, t->pos, "number %s is out of range -- using IEEE infinity", t->repr);
} else {
(options->pedantic_p ? error : warning) (c2m_ctx, t->pos, "number %s is out of range",
t->repr);
}
}
}
return t;
@ -7325,16 +7332,18 @@ static struct expr *check_assign_op (c2m_ctx_t c2m_ctx, node_t r, node_t op1, no
e->u.i_val = e1->u.i_val * e2->u.i_val;
else
e->u.u_val = e1->u.u_val * e2->u.u_val;
} else if ((floating_type_p (&t) && e2->u.d_val == 0.0)
} else if ((floating_type_p (&t) && e1->u.d_val == 0.0 && e2->u.d_val == 0.0)
|| (signed_integer_type_p (&t) && e2->u.i_val == 0)
|| (integer_type_p (&t) && !signed_integer_type_p (&t) && e2->u.u_val == 0)) {
error (c2m_ctx, r->pos, "Division by zero");
if (floating_type_p (&t))
e->u.d_val = 0.0;
else if (signed_integer_type_p (&t))
e->u.i_val = 0;
else
e->u.u_val = 0;
if (floating_type_p (&t)) {
e->u.d_val = nanl (""); /* Use NaN */
} else {
if (signed_integer_type_p (&t))
e->u.i_val = 0;
else
e->u.u_val = 0;
error (c2m_ctx, r->pos, "Division by zero");
}
} else if (r->code != N_MOD && floating_type_p (&t)) {
e->u.d_val = e1->u.d_val / e2->u.d_val;
} else if (signed_integer_type_p (&t)) { // ??? zero
@ -12028,12 +12037,14 @@ static void process_macro_commands (MIR_context_t ctx) {
undefine_cmd_macro (c2m_ctx, options->macro_commands[i].name);
}
static void compile_init (MIR_context_t ctx, struct c2mir_options *ops, int (*getc_func) (void)) {
static void compile_init (MIR_context_t ctx, struct c2mir_options *ops, int (*getc_func) (void *),
void *getc_data) {
c2m_ctx_t c2m_ctx = *c2m_ctx_loc (ctx);
options = ops;
n_errors = n_warnings = 0;
c_getc = getc_func;
c_getc_data = getc_data;
VARR_CREATE (char, symbol_text, 128);
VARR_CREATE (char, temp_string, 128);
parse_init (ctx);
@ -12080,10 +12091,10 @@ static const char *get_module_name (MIR_context_t ctx) {
return str;
}
static int top_level_getc (c2m_ctx_t c2m_ctx) { return c_getc (); }
static int top_level_getc (c2m_ctx_t c2m_ctx) { return c_getc (c_getc_data); }
int c2mir_compile (MIR_context_t ctx, struct c2mir_options *ops, int (*getc_func) (void),
const char *source_name, FILE *output_file) {
int c2mir_compile (MIR_context_t ctx, struct c2mir_options *ops, int (*getc_func) (void *),
void *getc_data, const char *source_name, FILE *output_file) {
c2m_ctx_t c2m_ctx = *c2m_ctx_loc (ctx);
double start_time = real_usec_time ();
node_t r;
@ -12091,12 +12102,12 @@ int c2mir_compile (MIR_context_t ctx, struct c2mir_options *ops, int (*getc_func
MIR_module_t m;
const char *base_name;
if (c2m_ctx == NULL) return 1;
if (c2m_ctx == NULL) return 0;
if (setjmp (c2m_ctx->env)) {
compile_finish (ctx);
return 1;
return 0;
}
compile_init (ctx, ops, getc_func);
compile_init (ctx, ops, getc_func, getc_data);
if (options->verbose_p && options->message_file != NULL)
fprintf (options->message_file, "C2MIR init end -- %.0f usec\n",
real_usec_time () - start_time);

@ -21,5 +21,5 @@ struct c2mir_options {
void c2mir_init (MIR_context_t ctx);
void c2mir_finish (MIR_context_t ctx);
int c2mir_compile (MIR_context_t ctx, struct c2mir_options *ops, int (*getc_func) (void),
const char *source_name, FILE *output_file);
int c2mir_compile (MIR_context_t ctx, struct c2mir_options *ops, int (*getc_func) (void *),
void *getc_data, const char *source_name, FILE *output_file);

@ -1,5 +1,6 @@
static const char mirc[]
= "#define __mirc__ 1\n"
"#define __MIRC__ 1\n"
"#define __STDC_HOSTED__ 1\n"
"//#define __STDC_ISO_10646__ 201103L\n"
"#define __STDC_NO_ATOMICS__ 1\n"

@ -378,6 +378,7 @@ static void generate_icode (MIR_context_t ctx, MIR_item_t func_item) {
v.a = ops[i].u.ref;
} else if (i == 1 && imm_call_p) {
mir_assert (ops[i].u.ref->item_type == MIR_import_item
|| ops[i].u.ref->item_type == MIR_export_item
|| ops[i].u.ref->item_type == MIR_func_item);
v.a = ops[i].u.ref->addr;
} else if (code == MIR_VA_ARG && i == 2) { /* type */

@ -103,32 +103,30 @@ static const uint8_t restore_pat[] = {
0x48, 0x81, 0xc4, 0x80, 0, 0, 0, /*add $0x80,%rsp */
};
VARR (uint8_t) * machine_insns;
static uint8_t *push_insns (const uint8_t *pat, size_t pat_len) {
static uint8_t *push_insns (MIR_context_t ctx, const uint8_t *pat, size_t pat_len) {
for (size_t i = 0; i < pat_len; i++) VARR_PUSH (uint8_t, machine_insns, pat[i]);
return VARR_ADDR (uint8_t, machine_insns) + VARR_LENGTH (uint8_t, machine_insns) - pat_len;
}
static void gen_mov (uint32_t offset, uint32_t reg, int ld_p) {
static void gen_mov (MIR_context_t ctx, uint32_t offset, uint32_t reg, int ld_p) {
static const uint8_t ld_gp_reg[] = {0x48, 0x8b, 0x83, 0, 0, 0, 0 /* mov <offset>(%rbx),%reg */};
static const uint8_t st_gp_reg[] = {0x48, 0x89, 0x83, 0, 0, 0, 0 /* mov %reg,<offset>(%rbx) */};
uint8_t *addr
= push_insns (ld_p ? ld_gp_reg : st_gp_reg, ld_p ? sizeof (ld_gp_reg) : sizeof (st_gp_reg));
uint8_t *addr = push_insns (ctx, ld_p ? ld_gp_reg : st_gp_reg,
ld_p ? sizeof (ld_gp_reg) : sizeof (st_gp_reg));
memcpy (addr + 3, &offset, sizeof (uint32_t));
assert (reg <= 15);
addr[0] |= (reg >> 1) & 4;
addr[2] |= (reg & 7) << 3;
}
static void gen_movxmm (uint32_t offset, uint32_t reg, int b32_p, int ld_p) {
static void gen_movxmm (MIR_context_t ctx, uint32_t offset, uint32_t reg, int b32_p, int ld_p) {
static const uint8_t ld_xmm_reg_pat[] = {
0xf2, 0x0f, 0x10, 0x83, 0, 0, 0, 0 /* movs[sd] <offset>(%rbx),%xmm */
};
static const uint8_t st_xmm_reg_pat[] = {
0xf2, 0x0f, 0x11, 0x83, 0, 0, 0, 0 /* movs[sd] %xmm, <offset>(%rbx) */
};
uint8_t *addr = push_insns (ld_p ? ld_xmm_reg_pat : st_xmm_reg_pat,
uint8_t *addr = push_insns (ctx, ld_p ? ld_xmm_reg_pat : st_xmm_reg_pat,
ld_p ? sizeof (ld_xmm_reg_pat) : sizeof (st_xmm_reg_pat));
memcpy (addr + 4, &offset, sizeof (uint32_t));
assert (reg <= 7);
@ -136,12 +134,12 @@ static void gen_movxmm (uint32_t offset, uint32_t reg, int b32_p, int ld_p) {
if (b32_p) addr[0] |= 1;
}
static void gen_ldst (uint32_t sp_offset, uint32_t src_offset, int b64_p) {
static void gen_ldst (MIR_context_t ctx, uint32_t sp_offset, uint32_t src_offset, int b64_p) {
static const uint8_t ldst_pat[] = {
0x44, 0x8b, 0x93, 0, 0, 0, 0, /* mov <src_offset>(%rbx),%r10 */
0x44, 0x89, 0x94, 0x24, 0, 0, 0, 0, /* mov %r10,<sp_offset>(%sp) */
};
uint8_t *addr = push_insns (ldst_pat, sizeof (ldst_pat));
uint8_t *addr = push_insns (ctx, ldst_pat, sizeof (ldst_pat));
memcpy (addr + 3, &src_offset, sizeof (uint32_t));
memcpy (addr + 11, &sp_offset, sizeof (uint32_t));
if (b64_p) {
@ -150,19 +148,19 @@ static void gen_ldst (uint32_t sp_offset, uint32_t src_offset, int b64_p) {
}
}
static void gen_ldst80 (uint32_t sp_offset, uint32_t src_offset) {
static void gen_ldst80 (MIR_context_t ctx, uint32_t sp_offset, uint32_t src_offset) {
static uint8_t const ldst80_pat[] = {
0xdb, 0xab, 0, 0, 0, 0, /* fldt <src_offset>(%rbx) */
0xdb, 0xbc, 0x24, 0, 0, 0, 0, /* fstpt <sp_offset>(%sp) */
};
uint8_t *addr = push_insns (ldst80_pat, sizeof (ldst80_pat));
uint8_t *addr = push_insns (ctx, ldst80_pat, sizeof (ldst80_pat));
memcpy (addr + 2, &src_offset, sizeof (uint32_t));
memcpy (addr + 9, &sp_offset, sizeof (uint32_t));
}
static void gen_st80 (uint32_t src_offset) {
static void gen_st80 (MIR_context_t ctx, uint32_t src_offset) {
static const uint8_t st80_pat[] = {0xdb, 0xbb, 0, 0, 0, 0 /* fstpt <src_offset>(%rbx) */};
memcpy (push_insns (st80_pat, sizeof (st80_pat)) + 2, &src_offset, sizeof (uint32_t));
memcpy (push_insns (ctx, st80_pat, sizeof (st80_pat)) + 2, &src_offset, sizeof (uint32_t));
}
/* Generation: fun (fun_addr, res_arg_addresses):
@ -193,24 +191,25 @@ void *_MIR_get_ff_call (MIR_context_t ctx, size_t nres, MIR_type_t *res_types, s
uint8_t *addr;
VARR_TRUNC (uint8_t, machine_insns, 0);
push_insns (prolog, sizeof (prolog));
push_insns (ctx, prolog, sizeof (prolog));
for (size_t i = 0; i < nargs; i++) {
if ((MIR_T_I8 <= arg_types[i] && arg_types[i] <= MIR_T_U64) || arg_types[i] == MIR_T_P) {
if (n_iregs < 6) {
gen_mov ((i + nres) * sizeof (long double), iregs[n_iregs++], TRUE);
gen_mov (ctx, (i + nres) * sizeof (long double), iregs[n_iregs++], TRUE);
} else {
gen_ldst (sp_offset, (i + nres) * sizeof (long double), TRUE);
gen_ldst (ctx, sp_offset, (i + nres) * sizeof (long double), TRUE);
sp_offset += 8;
}
} else if (arg_types[i] == MIR_T_F || arg_types[i] == MIR_T_D) {
if (n_xregs < 8) {
gen_movxmm ((i + nres) * sizeof (long double), n_xregs++, arg_types[i] == MIR_T_F, TRUE);
gen_movxmm (ctx, (i + nres) * sizeof (long double), n_xregs++, arg_types[i] == MIR_T_F,
TRUE);
} else {
gen_ldst (sp_offset, (i + nres) * sizeof (long double), arg_types[i] == MIR_T_D);
gen_ldst (ctx, sp_offset, (i + nres) * sizeof (long double), arg_types[i] == MIR_T_D);
sp_offset += 8;
}
} else if (arg_types[i] == MIR_T_LD) {
gen_ldst80 (sp_offset, (i + nres) * sizeof (long double));
gen_ldst80 (ctx, sp_offset, (i + nres) * sizeof (long double));
sp_offset += 16;
} else {
(*error_func) (MIR_call_op_error, "wrong type of arg value");
@ -219,22 +218,22 @@ void *_MIR_get_ff_call (MIR_context_t ctx, size_t nres, MIR_type_t *res_types, s
sp_offset = (sp_offset + 15) / 16 * 16;
addr = VARR_ADDR (uint8_t, machine_insns);
memcpy (addr + 4, &sp_offset, sizeof (uint32_t));
addr = push_insns (call_end, sizeof (call_end));
addr = push_insns (ctx, call_end, sizeof (call_end));
memcpy (addr + 13, &sp_offset, sizeof (uint32_t));
n_iregs = n_xregs = n_fregs = 0;
for (size_t i = 0; i < nres; i++) {
if (((MIR_T_I8 <= res_types[i] && res_types[i] <= MIR_T_U64) || res_types[i] == MIR_T_P)
&& n_iregs < 2) {
gen_mov (i * sizeof (long double), n_iregs++ == 0 ? 0 : 2, FALSE); /* rax or rdx */
gen_mov (ctx, i * sizeof (long double), n_iregs++ == 0 ? 0 : 2, FALSE); /* rax or rdx */
} else if ((res_types[i] == MIR_T_F || res_types[i] == MIR_T_D) && n_xregs < 2) {
gen_movxmm (i * sizeof (long double), n_xregs++, res_types[i] == MIR_T_F, FALSE);
gen_movxmm (ctx, i * sizeof (long double), n_xregs++, res_types[i] == MIR_T_F, FALSE);
} else if (res_types[i] == MIR_T_LD && n_fregs < 2) {
gen_st80 (i * sizeof (long double));
gen_st80 (ctx, i * sizeof (long double));
} else {
(*error_func) (MIR_ret_error, "x86-64 can not handle this combination of return values");
}
}
push_insns (epilog, sizeof (epilog));
push_insns (ctx, epilog, sizeof (epilog));
return _MIR_publish_code (ctx, VARR_ADDR (uint8_t, machine_insns),
VARR_LENGTH (uint8_t, machine_insns));
}
@ -277,9 +276,9 @@ void *_MIR_get_interp_shim (MIR_context_t ctx, MIR_item_t func_item, void *handl
MIR_type_t *results = func_item->u.func->res_types;
VARR_TRUNC (uint8_t, machine_insns, 0);
push_insns (push_rbx, sizeof (push_rbx));
push_insns (save_pat, sizeof (save_pat));
addr = push_insns (prepare_pat, sizeof (prepare_pat));
push_insns (ctx, push_rbx, sizeof (push_rbx));
push_insns (ctx, save_pat, sizeof (save_pat));
addr = push_insns (ctx, prepare_pat, sizeof (prepare_pat));
imm = nres * 16;
memcpy (addr + 0x2c, &imm, sizeof (uint32_t));
memcpy (addr + 0x38, &ctx, sizeof (void *));
@ -289,22 +288,22 @@ void *_MIR_get_interp_shim (MIR_context_t ctx, MIR_item_t func_item, void *handl
n_iregs = n_xregs = n_fregs = offset = 0;
for (uint32_t i = 0; i < nres; i++) {
if (results[i] == MIR_T_F && n_xregs < 2) {
addr = push_insns (movss_pat, sizeof (movss_pat));
addr = push_insns (ctx, movss_pat, sizeof (movss_pat));
addr[3] |= n_xregs << 3;
memcpy (addr + 4, &offset, sizeof (uint32_t));
n_xregs++;
} else if (results[i] == MIR_T_D && n_xregs < 2) {
addr = push_insns (movsd_pat, sizeof (movsd_pat));
addr = push_insns (ctx, movsd_pat, sizeof (movsd_pat));
addr[3] |= n_xregs << 3;
memcpy (addr + 4, &offset, sizeof (uint32_t));
n_xregs++;
} else if (results[i] == MIR_T_LD && n_fregs < 2) {
addr = push_insns (fldt_pat, sizeof (fldt_pat));
addr = push_insns (ctx, fldt_pat, sizeof (fldt_pat));
memcpy (addr + 2, &offset, sizeof (uint32_t));
if (n_fregs == 1) push_insns (fxch_pat, sizeof (fxch_pat));
if (n_fregs == 1) push_insns (ctx, fxch_pat, sizeof (fxch_pat));
n_fregs++;
} else if (n_iregs < 2) {
addr = push_insns (ld_pat, sizeof (ld_pat));
addr = push_insns (ctx, ld_pat, sizeof (ld_pat));
addr[2] |= n_iregs << 4;
memcpy (addr + 3, &offset, sizeof (uint32_t));
n_iregs++;
@ -313,7 +312,7 @@ void *_MIR_get_interp_shim (MIR_context_t ctx, MIR_item_t func_item, void *handl
}
offset += 16;
}
addr = push_insns (shim_end, sizeof (shim_end));
addr = push_insns (ctx, shim_end, sizeof (shim_end));
imm = 208 + nres * 16;
memcpy (addr + 3, &imm, sizeof (uint32_t));
return _MIR_publish_code (ctx, VARR_ADDR (uint8_t, machine_insns),
@ -338,14 +337,14 @@ void *_MIR_get_wrapper (MIR_context_t ctx, MIR_item_t called_func, void *hook_ad
uint8_t *addr;
VARR_TRUNC (uint8_t, machine_insns, 0);
push_insns (push_rax, sizeof (push_rax));
push_insns (save_pat, sizeof (save_pat));
addr = push_insns (call_pat, sizeof (call_pat));
push_insns (ctx, push_rax, sizeof (push_rax));
push_insns (ctx, save_pat, sizeof (save_pat));
addr = push_insns (ctx, call_pat, sizeof (call_pat));
memcpy (addr + 2, &called_func, sizeof (void *));
memcpy (addr + 12, &ctx, sizeof (void *));
memcpy (addr + 22, &hook_address, sizeof (void *));
push_insns (restore_pat, sizeof (restore_pat));
push_insns (wrap_end, sizeof (wrap_end));
push_insns (ctx, restore_pat, sizeof (restore_pat));
push_insns (ctx, wrap_end, sizeof (wrap_end));
return _MIR_publish_code (ctx, VARR_ADDR (uint8_t, machine_insns),
VARR_LENGTH (uint8_t, machine_insns));
}

@ -528,6 +528,7 @@ static void push_data (MIR_context_t ctx, uint8_t *els, size_t size) {
}
const char *MIR_item_name (MIR_context_t ctx, MIR_item_t item) {
mir_assert (item != NULL);
return (item->item_type == MIR_func_item
? item->u.func->name
: item->item_type == MIR_proto_item
@ -949,6 +950,7 @@ MIR_item_t MIR_new_expr_data (MIR_context_t ctx, const char *name, MIR_item_t ex
(*error_func) (MIR_alloc_error, "Not enough memory for creation of expr data %s",
name == NULL ? "" : name);
}
mir_assert (expr_item != NULL);
if (expr_item->item_type != MIR_func_item || expr_item->u.func->vararg_p
|| expr_item->u.func->nargs != 0 || expr_item->u.func->nres != 1)
(*error_func) (MIR_binary_io_error,
@ -1139,9 +1141,10 @@ 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", name);
(*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);
VARR_PUSH (MIR_var_t, func->vars, var);
return create_func_reg (ctx, func, name, VARR_LENGTH (MIR_var_t, func->vars), type, FALSE);
}
@ -1205,7 +1208,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,
"number of operands in return does not correspond number of function returns");
"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;
for (i = 0; i < actual_nops; i++) {
@ -1249,7 +1253,7 @@ 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, "base reg of non-integer type");
(*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) {
@ -1257,7 +1261,7 @@ 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, "index reg of non-integer type");
(*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);
@ -1278,11 +1282,12 @@ 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, "unexpected operand 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, type_str(mode), type_str(expected_mode));
}
if (out_p && !can_be_out_p) {
curr_func = NULL;
(*error_func) (MIR_out_op_error, "wrong operand for insn output");
(*error_func) (MIR_out_op_error, "in instruction '%s': wrong operand #%d for insn output", insn_descs[code].name, i+1);
}
}
}
@ -1389,6 +1394,7 @@ static MIR_item_t load_bss_data_section (MIR_context_t ctx, MIR_item_t item, int
}
void MIR_load_module (MIR_context_t ctx, MIR_module_t m) {
mir_assert (m != NULL);
for (MIR_item_t item = DLIST_HEAD (MIR_item_t, m->items); item != NULL;
item = DLIST_NEXT (MIR_item_t, item)) {
if (item->item_type == MIR_bss_item || item->item_type == MIR_data_item
@ -1533,14 +1539,16 @@ static size_t insn_code_nops (MIR_context_t ctx, MIR_insn_code_t code) { /* 0 fo
return VARR_GET (size_t, insn_nops, code);
}
size_t MIR_insn_nops (MIR_context_t ctx, MIR_insn_t insn) { 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) {
unsigned mode;
mir_assert (out_p != NULL);
if (nop >= insn_code_nops (ctx, code)) return MIR_OP_BOUND;
mode = insn_descs[code].op_modes[nop];
mir_assert (out_p != NULL);
*out_p = (mode & OUTPUT_FLAG) != 0;
return *out_p ? mode ^ OUTPUT_FLAG : mode;
}
@ -1551,6 +1559,7 @@ MIR_op_mode_t MIR_insn_op_mode (MIR_context_t ctx, MIR_insn_t insn, size_t nop,
unsigned mode;
if (nop >= nops) return MIR_OP_BOUND;
mir_assert (out_p != NULL);
if (code == MIR_RET || code == MIR_SWITCH) {
*out_p = FALSE;
/* should be already checked in MIR_finish_func */
@ -1597,6 +1606,7 @@ MIR_insn_t MIR_new_insn_arr (MIR_context_t ctx, MIR_insn_code_t code, size_t nop
MIR_insn_t insn;
MIR_proto_t proto;
size_t i = 0, expected_nops = insn_code_nops (ctx, code);
mir_assert (ops != NULL);
if (!MIR_call_code_p (code) && code != MIR_RET && code != MIR_SWITCH && nops != expected_nops) {
(*error_func) (MIR_ops_num_error, "wrong number of operands for insn %s",
@ -1663,8 +1673,9 @@ MIR_insn_t MIR_new_ret_insn (MIR_context_t ctx, size_t nops, ...) {
}
MIR_insn_t MIR_copy_insn (MIR_context_t ctx, MIR_insn_t insn) {
size_t size
= sizeof (struct MIR_insn) + sizeof (MIR_op_t) * (insn->nops == 0 ? 0 : insn->nops - 1);
size_t size;
mir_assert (insn != NULL);
size = sizeof (struct MIR_insn) + sizeof (MIR_op_t) * (insn->nops == 0 ? 0 : insn->nops - 1);
MIR_insn_t new_insn = malloc (size);
if (new_insn == NULL)
@ -1688,6 +1699,7 @@ MIR_reg_t _MIR_new_temp_reg (MIR_context_t ctx, MIR_type_t type, MIR_func_t func
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 %s for temporary register", type_str (type));
mir_assert (func != NULL);
for (;;) {
func->last_temp_num++;
if (func->last_temp_num == 0) (*error_func) (MIR_unique_reg_error, "out of unique regs");
@ -1925,12 +1937,14 @@ htab_hash_t MIR_op_hash_step (MIR_context_t ctx, htab_hash_t h, MIR_op_t op) {
}
void MIR_append_insn (MIR_context_t ctx, MIR_item_t func_item, MIR_insn_t insn) {
mir_assert (func_item != NULL);
if (func_item->item_type != MIR_func_item)
(*error_func) (MIR_wrong_param_value_error, "MIR_append_insn: wrong func item");
DLIST_APPEND (MIR_insn_t, func_item->u.func->insns, insn);
}
void MIR_prepend_insn (MIR_context_t ctx, MIR_item_t func_item, MIR_insn_t insn) {
mir_assert (func_item != NULL);
if (func_item->item_type != MIR_func_item)
(*error_func) (MIR_wrong_param_value_error, "MIR_prepend_insn: wrong func item");
DLIST_PREPEND (MIR_insn_t, func_item->u.func->insns, insn);
@ -1938,6 +1952,7 @@ void MIR_prepend_insn (MIR_context_t ctx, MIR_item_t func_item, MIR_insn_t insn)
void MIR_insert_insn_after (MIR_context_t ctx, MIR_item_t func_item, MIR_insn_t after,
MIR_insn_t insn) {
mir_assert (func_item != NULL);
if (func_item->item_type != MIR_func_item)
(*error_func) (MIR_wrong_param_value_error, "MIR_insert_insn_after: wrong func item");
DLIST_INSERT_AFTER (MIR_insn_t, func_item->u.func->insns, after, insn);
@ -1945,12 +1960,14 @@ void MIR_insert_insn_after (MIR_context_t ctx, MIR_item_t func_item, MIR_insn_t
void MIR_insert_insn_before (MIR_context_t ctx, MIR_item_t func_item, MIR_insn_t before,
MIR_insn_t insn) {
mir_assert (func_item != NULL);
if (func_item->item_type != MIR_func_item)
(*error_func) (MIR_wrong_param_value_error, "MIR_insert_insn_before: wrong func item");
DLIST_INSERT_BEFORE (MIR_insn_t, func_item->u.func->insns, before, insn);
}
void MIR_remove_insn (MIR_context_t ctx, MIR_item_t func_item, MIR_insn_t insn) {
mir_assert (func_item != NULL);
if (func_item->item_type != MIR_func_item)
(*error_func) (MIR_wrong_param_value_error, "MIR_remove_insn: wrong func item");
DLIST_REMOVE (MIR_insn_t, func_item->u.func->insns, insn);
@ -1991,7 +2008,7 @@ void _MIR_duplicate_func_insns (MIR_context_t ctx, MIR_item_t func_item) {
MIR_func_t func;
MIR_insn_t insn, new_insn;
mir_assert (func_item->item_type == MIR_func_item);
mir_assert (func_item != NULL && func_item->item_type == MIR_func_item);
func = func_item->u.func;
mir_assert (DLIST_HEAD (MIR_insn_t, func->original_insns) == NULL);
func->original_insns = func->insns;
@ -2011,7 +2028,7 @@ void _MIR_restore_func_insns (MIR_context_t ctx, MIR_item_t func_item) {
MIR_func_t func;
MIR_insn_t insn;
mir_assert (func_item->item_type == MIR_func_item);
mir_assert (func_item != NULL && func_item->item_type == MIR_func_item);
func = func_item->u.func;
while ((insn = DLIST_HEAD (MIR_insn_t, func->insns)) != NULL)
MIR_remove_insn (ctx, func_item, insn);
@ -2114,6 +2131,7 @@ static void output_label (MIR_context_t ctx, FILE *f, MIR_func_t func, MIR_label
void MIR_output_insn (MIR_context_t ctx, FILE *f, MIR_insn_t insn, MIR_func_t func, int newline_p) {
size_t i, nops;
mir_assert (insn != NULL);
if (insn->code == MIR_LABEL) {
output_label (ctx, f, func, insn);
if (newline_p) fprintf (f, ":\n");
@ -2157,6 +2175,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);
if (item->item_type == MIR_export_item) {
fprintf (f, "\texport\t%s\n", item->u.export);
return;
@ -2246,6 +2265,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);
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))
@ -2254,6 +2274,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);
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);
@ -2332,6 +2353,7 @@ static MIR_reg_t vn_add_val (MIR_context_t ctx, MIR_func_t func, MIR_type_t type
}
const char *_MIR_get_temp_item_name (MIR_context_t ctx, MIR_module_t module) {
mir_assert (module != NULL);
module->last_temp_item_num++;
snprintf (temp_buff, sizeof (temp_buff), "%s%u", TEMP_ITEM_NAME_PREFIX,
(unsigned) module->last_temp_item_num);
@ -2340,6 +2362,7 @@ const char *_MIR_get_temp_item_name (MIR_context_t ctx, MIR_module_t module) {
void MIR_simplify_op (MIR_context_t ctx, MIR_item_t func_item, MIR_insn_t insn, int nop, int out_p,
MIR_insn_code_t code, int keep_ref_p, int mem_float_p) {
mir_assert (insn != NULL && func_item != NULL);
MIR_op_t new_op, mem_op, *op = &insn->ops[nop];
MIR_insn_t new_insn;
MIR_func_t func = func_item->u.func;
@ -2519,6 +2542,7 @@ void MIR_simplify_op (MIR_context_t ctx, MIR_item_t func_item, MIR_insn_t insn,
void _MIR_simplify_insn (MIR_context_t ctx, MIR_item_t func_item, MIR_insn_t insn, int keep_ref_p,
int mem_float_p) {
int out_p;
mir_assert (insn != NULL);
MIR_insn_code_t code = insn->code;
size_t i, nops = MIR_insn_nops (ctx, insn);
@ -3089,10 +3113,12 @@ DEF_VARR (code_holder_t);
struct machine_code_ctx {
VARR (code_holder_t) * code_holders;
size_t page_size;
VARR (uint8_t) * machine_insns;
};
#define code_holders ctx->machine_code_ctx->code_holders
#define page_size ctx->machine_code_ctx->page_size
#define machine_insns ctx->machine_code_ctx->machine_insns
uint8_t *_MIR_publish_code (MIR_context_t ctx, const uint8_t *code, size_t code_len) {
uint8_t *start, *mem;
@ -3134,6 +3160,7 @@ void _MIR_update_code_arr (MIR_context_t ctx, uint8_t *base, size_t nloc,
const MIR_code_reloc_t *relocs) {
size_t i, len, start, max_offset = 0;
mir_assert (relocs != NULL);
for (i = 0; i < nloc; i++)
if (max_offset < relocs[i].offset) max_offset = relocs[i].offset;
start = (size_t) base / page_size * page_size;

@ -349,19 +349,19 @@ static void* import_resolver(const char *name) {
return NULL;
}
/* FIXME */
/* For now we have to use some static variables
due to limitations of the MIR api */
static size_t Current_char; /* position of current character */
static const char *Source_code; /* points to buffer containing source Source_code */
struct ReadBuffer {
size_t Current_char; /* position of current character */
const char *Source_code; /* points to buffer containing source Source_code */
};
static int t_getc (void) {
int c = Source_code[Current_char];
static int t_getc (void *data) {
struct ReadBuffer *buffer = data;
int c = buffer->Source_code[buffer->Current_char];
if (c == 0)
c = EOF;
else
Current_char++;
buffer->Current_char++;
return c;
}
@ -383,16 +383,14 @@ void *MIR_compile_C_module(
const char *func_name, /* Name of the function, must be unique */
void *(Import_resolver_func)(const char *name)) /* Resolve external symbols */
{
int n = 0;
int ret_code = 0;
int (*fun_addr) (void *) = NULL;
struct ReadBuffer read_buffer = {.Current_char = 0, .Source_code = inputbuffer};
MIR_module_t module = NULL;
c2mir_init(ctx);
Source_code = inputbuffer;
Current_char = 0;
options->module_num++;
options->message_file = stderr;
if (!c2mir_compile(ctx, options, t_getc, func_name, NULL)) {
if (!c2mir_compile(ctx, options, t_getc, &read_buffer, func_name, NULL)) {
ret_code = 1;
}
else {

Loading…
Cancel
Save