issue #169 update MIR sources from upstream
parent
174cfa0168
commit
7f94078e8e
@ -0,0 +1,91 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2018-2020 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
aarch64 call ABI target specific code.
|
||||
*/
|
||||
|
||||
typedef int target_arg_info_t;
|
||||
|
||||
static void target_init_arg_vars (c2m_ctx_t c2m_ctx, target_arg_info_t *arg_info) {}
|
||||
|
||||
static int target_return_by_addr_p (c2m_ctx_t c2m_ctx, struct type *ret_type) {
|
||||
return ((ret_type->mode == TM_STRUCT || ret_type->mode == TM_UNION)
|
||||
&& type_size (c2m_ctx, ret_type) > 2 * 8);
|
||||
}
|
||||
|
||||
static int reg_aggregate_size (c2m_ctx_t c2m_ctx, struct type *type) {
|
||||
int size;
|
||||
|
||||
if (type->mode != TM_STRUCT && type->mode != TM_UNION) return -1;
|
||||
return (size = type_size (c2m_ctx, type)) <= 2 * 8 ? size : -1;
|
||||
}
|
||||
|
||||
static void target_add_res_proto (c2m_ctx_t c2m_ctx, struct type *ret_type,
|
||||
target_arg_info_t *arg_info, VARR (MIR_type_t) * res_types,
|
||||
VARR (MIR_var_t) * arg_vars) {
|
||||
MIR_var_t var;
|
||||
int size;
|
||||
|
||||
if ((size = reg_aggregate_size (c2m_ctx, ret_type)) < 0) {
|
||||
simple_add_res_proto (c2m_ctx, ret_type, arg_info, res_types, arg_vars);
|
||||
return;
|
||||
}
|
||||
if (size == 0) return;
|
||||
VARR_PUSH (MIR_type_t, res_types, MIR_T_I64);
|
||||
if (size > 8) VARR_PUSH (MIR_type_t, res_types, MIR_T_I64);
|
||||
}
|
||||
|
||||
static int target_add_call_res_op (c2m_ctx_t c2m_ctx, struct type *ret_type,
|
||||
target_arg_info_t *arg_info, size_t call_arg_area_offset) {
|
||||
MIR_context_t ctx = c2m_ctx->ctx;
|
||||
int size;
|
||||
|
||||
if ((size = reg_aggregate_size (c2m_ctx, ret_type)) < 0)
|
||||
return simple_add_call_res_op (c2m_ctx, ret_type, arg_info, call_arg_area_offset);
|
||||
if (size == 0) return -1;
|
||||
VARR_PUSH (MIR_op_t, call_ops,
|
||||
MIR_new_reg_op (ctx, get_new_temp (c2m_ctx, MIR_T_I64).mir_op.u.reg));
|
||||
if (size > 8)
|
||||
VARR_PUSH (MIR_op_t, call_ops,
|
||||
MIR_new_reg_op (ctx, get_new_temp (c2m_ctx, MIR_T_I64).mir_op.u.reg));
|
||||
return size <= 8 ? 1 : 2;
|
||||
}
|
||||
|
||||
static op_t target_gen_post_call_res_code (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res,
|
||||
MIR_insn_t call, size_t call_ops_start) {
|
||||
int size;
|
||||
|
||||
if ((size = reg_aggregate_size (c2m_ctx, ret_type)) < 0)
|
||||
return simple_gen_post_call_res_code (c2m_ctx, ret_type, res, call, call_ops_start);
|
||||
if (size != 0)
|
||||
gen_multiple_load_store (c2m_ctx, ret_type, &VARR_ADDR (MIR_op_t, call_ops)[call_ops_start + 2],
|
||||
res.mir_op, FALSE);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void target_add_ret_ops (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res) {
|
||||
int i, size;
|
||||
|
||||
if ((size = reg_aggregate_size (c2m_ctx, ret_type)) < 0) {
|
||||
simple_add_ret_ops (c2m_ctx, ret_type, res);
|
||||
return;
|
||||
}
|
||||
assert (res.mir_op.mode == MIR_OP_MEM && VARR_LENGTH (MIR_op_t, ret_ops) == 0 && size <= 2 * 8);
|
||||
for (i = 0; size > 0; size -= 8, i++)
|
||||
VARR_PUSH (MIR_op_t, ret_ops, get_new_temp (c2m_ctx, MIR_T_I64).mir_op);
|
||||
gen_multiple_load_store (c2m_ctx, ret_type, VARR_ADDR (MIR_op_t, ret_ops), res.mir_op, TRUE);
|
||||
}
|
||||
|
||||
static void target_add_arg_proto (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
|
||||
target_arg_info_t *arg_info, VARR (MIR_var_t) * arg_vars) {
|
||||
simple_add_arg_proto (c2m_ctx, name, arg_type, arg_info, arg_vars);
|
||||
}
|
||||
|
||||
static void target_add_call_arg_op (c2m_ctx_t c2m_ctx, struct type *arg_type,
|
||||
target_arg_info_t *arg_info, op_t arg) {
|
||||
simple_add_call_arg_op (c2m_ctx, arg_type, arg_info, arg);
|
||||
}
|
||||
|
||||
static int target_gen_gather_arg (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
|
||||
decl_t param_decl, target_arg_info_t *arg_info) {
|
||||
return FALSE;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,300 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2018-2020 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
ppc64 call ABI target specific code.
|
||||
*/
|
||||
|
||||
typedef int target_arg_info_t;
|
||||
|
||||
static void target_init_arg_vars (c2m_ctx_t c2m_ctx, target_arg_info_t *arg_info) {}
|
||||
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
static MIR_type_t fp_homogeneous_type (c2m_ctx_t c2m_ctx, struct type *param_type, int *num) {
|
||||
return MIR_T_UNDEF;
|
||||
}
|
||||
#else
|
||||
static MIR_type_t fp_homogeneous_type_1 (c2m_ctx_t c2m_ctx, MIR_type_t curr_type, struct type *type,
|
||||
int *num) {
|
||||
int n;
|
||||
MIR_type_t t;
|
||||
|
||||
if (type->mode == TM_STRUCT || type->mode == TM_UNION || type->mode == TM_ARR) {
|
||||
switch (type->mode) {
|
||||
case TM_ARR: { /* Arrays are handled as small records. */
|
||||
struct arr_type *arr_type = type->u.arr_type;
|
||||
struct expr *cexpr = arr_type->size->attr;
|
||||
|
||||
if ((t = fp_homogeneous_type_1 (c2m_ctx, curr_type, type->u.arr_type->el_type, &n))
|
||||
== MIR_T_UNDEF)
|
||||
return MIR_T_UNDEF;
|
||||
*num = arr_type->size->code == N_IGNORE || !cexpr->const_p ? 1 : cexpr->u.i_val;
|
||||
return t;
|
||||
}
|
||||
case TM_STRUCT:
|
||||
case TM_UNION:
|
||||
t = curr_type;
|
||||
*num = 0;
|
||||
for (node_t el = NL_HEAD (NL_EL (type->u.tag_type->ops, 1)->ops); el != NULL;
|
||||
el = NL_NEXT (el))
|
||||
if (el->code == N_MEMBER) {
|
||||
decl_t decl = el->attr;
|
||||
|
||||
if ((t = fp_homogeneous_type_1 (c2m_ctx, t, decl->decl_spec.type, &n)) == MIR_T_UNDEF)
|
||||
return MIR_T_UNDEF;
|
||||
if (type->mode == TM_STRUCT)
|
||||
*num += n;
|
||||
else if (*num < n)
|
||||
*num = n;
|
||||
}
|
||||
return t;
|
||||
default: assert (FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
assert (scalar_type_p (type));
|
||||
if ((t = get_mir_type (c2m_ctx, type)) != MIR_T_F && t != MIR_T_D) return MIR_T_UNDEF;
|
||||
if (curr_type != t && curr_type != MIR_T_UNDEF) return MIR_T_UNDEF;
|
||||
*num = 1;
|
||||
return t;
|
||||
}
|
||||
|
||||
static MIR_type_t fp_homogeneous_type (c2m_ctx_t c2m_ctx, struct type *param_type, int *num) {
|
||||
if (param_type->mode != TM_STRUCT && param_type->mode != TM_UNION) return MIR_T_UNDEF;
|
||||
return fp_homogeneous_type_1 (c2m_ctx, MIR_T_UNDEF, param_type, num);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int reg_aggregate_p (c2m_ctx_t c2m_ctx, struct type *ret_type) {
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
return FALSE;
|
||||
#else
|
||||
return type_size (c2m_ctx, ret_type) <= 2 * 8;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int target_return_by_addr_p (c2m_ctx_t c2m_ctx, struct type *ret_type) {
|
||||
MIR_type_t type;
|
||||
int n;
|
||||
|
||||
if (ret_type->mode != TM_STRUCT && ret_type->mode != TM_UNION) return FALSE;
|
||||
if (((type = fp_homogeneous_type (c2m_ctx, ret_type, &n)) == MIR_T_F || type == MIR_T_D)
|
||||
&& n <= 8)
|
||||
return FALSE;
|
||||
return !reg_aggregate_p (c2m_ctx, ret_type);
|
||||
}
|
||||
|
||||
static void target_add_res_proto (c2m_ctx_t c2m_ctx, struct type *ret_type,
|
||||
target_arg_info_t *arg_info, VARR (MIR_type_t) * res_types,
|
||||
VARR (MIR_var_t) * arg_vars) {
|
||||
MIR_var_t var;
|
||||
MIR_type_t type;
|
||||
int i, n, size;
|
||||
|
||||
if (void_type_p (ret_type)) return;
|
||||
if (((type = fp_homogeneous_type (c2m_ctx, ret_type, &n)) == MIR_T_F || type == MIR_T_D)
|
||||
&& n <= 8) {
|
||||
for (i = 0; i < n; i++) VARR_PUSH (MIR_type_t, res_types, type);
|
||||
} else if (ret_type->mode != TM_STRUCT && ret_type->mode != TM_UNION) {
|
||||
VARR_PUSH (MIR_type_t, res_types, get_mir_type (c2m_ctx, ret_type));
|
||||
} else if (reg_aggregate_p (c2m_ctx, ret_type)) {
|
||||
size = type_size (c2m_ctx, ret_type);
|
||||
for (; size > 0; size -= 8) VARR_PUSH (MIR_type_t, res_types, MIR_T_I64);
|
||||
} else {
|
||||
var.name = RET_ADDR_NAME;
|
||||
var.type = MIR_T_RBLK;
|
||||
var.size = type_size (c2m_ctx, ret_type);
|
||||
VARR_PUSH (MIR_var_t, arg_vars, var);
|
||||
}
|
||||
}
|
||||
|
||||
static int target_add_call_res_op (c2m_ctx_t c2m_ctx, struct type *ret_type,
|
||||
target_arg_info_t *arg_info, size_t call_arg_area_offset) {
|
||||
MIR_context_t ctx = c2m_ctx->ctx;
|
||||
MIR_type_t type;
|
||||
op_t temp;
|
||||
int i, n, size;
|
||||
|
||||
if (void_type_p (ret_type)) return -1;
|
||||
if (((type = fp_homogeneous_type (c2m_ctx, ret_type, &n)) == MIR_T_F || type == MIR_T_D)
|
||||
&& n <= 8) {
|
||||
for (i = 0; i < n; i++) {
|
||||
temp = get_new_temp (c2m_ctx, type);
|
||||
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
|
||||
}
|
||||
return n;
|
||||
} else if (ret_type->mode != TM_STRUCT && ret_type->mode != TM_UNION) {
|
||||
type = get_mir_type (c2m_ctx, ret_type);
|
||||
type = promote_mir_int_type (type);
|
||||
temp = get_new_temp (c2m_ctx, type);
|
||||
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
|
||||
return 1;
|
||||
} else if (reg_aggregate_p (c2m_ctx, ret_type)) {
|
||||
size = type_size (c2m_ctx, ret_type);
|
||||
if (size == 0) return -1;
|
||||
for (int s = size; s > 0; s -= 8) {
|
||||
temp = get_new_temp (c2m_ctx, MIR_T_I64);
|
||||
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
|
||||
}
|
||||
return (size + 7) / 8;
|
||||
} else {
|
||||
temp = get_new_temp (c2m_ctx, MIR_T_I64);
|
||||
emit3 (c2m_ctx, MIR_ADD, temp.mir_op,
|
||||
MIR_new_reg_op (ctx, MIR_reg (ctx, FP_NAME, curr_func->u.func)),
|
||||
MIR_new_int_op (ctx, call_arg_area_offset));
|
||||
temp.mir_op
|
||||
= MIR_new_mem_op (ctx, MIR_T_RBLK, type_size (c2m_ctx, ret_type), temp.mir_op.u.reg, 0, 1);
|
||||
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static op_t target_gen_post_call_res_code (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res,
|
||||
MIR_insn_t call, size_t call_ops_start) {
|
||||
MIR_context_t ctx = c2m_ctx->ctx;
|
||||
MIR_type_t type;
|
||||
MIR_insn_t insn;
|
||||
int i, n;
|
||||
|
||||
if (void_type_p (ret_type)) return res;
|
||||
if (((type = fp_homogeneous_type (c2m_ctx, ret_type, &n)) == MIR_T_F || type == MIR_T_D)
|
||||
&& n <= 8) {
|
||||
assert (res.mir_op.mode == MIR_OP_MEM);
|
||||
for (i = 0; i < n; i++) {
|
||||
insn = MIR_new_insn (ctx, tp_mov (type),
|
||||
MIR_new_mem_op (ctx, type,
|
||||
res.mir_op.u.mem.disp + (type == MIR_T_F ? 4 : 8) * i,
|
||||
res.mir_op.u.mem.base, res.mir_op.u.mem.index,
|
||||
res.mir_op.u.mem.scale),
|
||||
VARR_GET (MIR_op_t, call_ops, i + call_ops_start + 2));
|
||||
MIR_append_insn (ctx, curr_func, insn);
|
||||
}
|
||||
} else if ((ret_type->mode == TM_STRUCT || ret_type->mode == TM_UNION)
|
||||
&& reg_aggregate_p (c2m_ctx, ret_type)) {
|
||||
assert (res.mir_op.mode == MIR_OP_MEM); /* addr */
|
||||
gen_multiple_load_store (c2m_ctx, ret_type, &VARR_ADDR (MIR_op_t, call_ops)[call_ops_start + 2],
|
||||
res.mir_op, FALSE);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static void target_add_ret_ops (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res) {
|
||||
MIR_context_t ctx = c2m_ctx->ctx;
|
||||
MIR_type_t type;
|
||||
MIR_insn_t insn;
|
||||
MIR_reg_t ret_addr_reg;
|
||||
op_t temp, var;
|
||||
int i, n, size;
|
||||
|
||||
if (void_type_p (ret_type)) return;
|
||||
if (((type = fp_homogeneous_type (c2m_ctx, ret_type, &n)) == MIR_T_F || type == MIR_T_D)
|
||||
&& n <= 8) {
|
||||
assert (res.mir_op.mode == MIR_OP_MEM);
|
||||
for (int i = 0; i < n; i++) {
|
||||
temp = get_new_temp (c2m_ctx, type);
|
||||
insn = MIR_new_insn (ctx, tp_mov (type), temp.mir_op,
|
||||
MIR_new_mem_op (ctx, type,
|
||||
res.mir_op.u.mem.disp + (type == MIR_T_F ? 4 : 8) * i,
|
||||
res.mir_op.u.mem.base, res.mir_op.u.mem.index,
|
||||
res.mir_op.u.mem.scale));
|
||||
MIR_append_insn (ctx, curr_func, insn);
|
||||
VARR_PUSH (MIR_op_t, ret_ops, temp.mir_op);
|
||||
}
|
||||
} else if (ret_type->mode != TM_STRUCT && ret_type->mode != TM_UNION) {
|
||||
VARR_PUSH (MIR_op_t, ret_ops, res.mir_op);
|
||||
} else if (reg_aggregate_p (c2m_ctx, ret_type)) {
|
||||
size = type_size (c2m_ctx, ret_type);
|
||||
assert (res.mir_op.mode == MIR_OP_MEM && VARR_LENGTH (MIR_op_t, ret_ops) == 0);
|
||||
for (int i = 0; size > 0; size -= 8, i++)
|
||||
VARR_PUSH (MIR_op_t, ret_ops, get_new_temp (c2m_ctx, MIR_T_I64).mir_op);
|
||||
gen_multiple_load_store (c2m_ctx, ret_type, &VARR_ADDR (MIR_op_t, ret_ops)[0], res.mir_op,
|
||||
TRUE);
|
||||
} else {
|
||||
ret_addr_reg = MIR_reg (ctx, RET_ADDR_NAME, curr_func->u.func);
|
||||
var = new_op (NULL, MIR_new_mem_op (ctx, MIR_T_I8, 0, ret_addr_reg, 0, 1));
|
||||
size = type_size (c2m_ctx, ret_type);
|
||||
block_move (c2m_ctx, var, res, size);
|
||||
}
|
||||
}
|
||||
|
||||
static void target_add_arg_proto (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
|
||||
target_arg_info_t *arg_info, VARR (MIR_var_t) * arg_vars) {
|
||||
MIR_var_t var;
|
||||
MIR_type_t type;
|
||||
int n;
|
||||
|
||||
if (((type = fp_homogeneous_type (c2m_ctx, arg_type, &n)) == MIR_T_F || type == MIR_T_D)
|
||||
&& n <= 8) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
var.name = gen_get_indexed_name (c2m_ctx, name, i);
|
||||
var.type = type;
|
||||
VARR_PUSH (MIR_var_t, arg_vars, var);
|
||||
}
|
||||
return;
|
||||
}
|
||||
type = (arg_type->mode == TM_STRUCT || arg_type->mode == TM_UNION
|
||||
? MIR_T_BLK
|
||||
: get_mir_type (c2m_ctx, arg_type));
|
||||
var.name = name;
|
||||
var.type = type;
|
||||
if (type == MIR_T_BLK) var.size = type_size (c2m_ctx, arg_type);
|
||||
VARR_PUSH (MIR_var_t, arg_vars, var);
|
||||
}
|
||||
|
||||
static void target_add_call_arg_op (c2m_ctx_t c2m_ctx, struct type *arg_type,
|
||||
target_arg_info_t *arg_info, op_t arg) {
|
||||
MIR_context_t ctx = c2m_ctx->ctx;
|
||||
MIR_var_t var;
|
||||
MIR_type_t type;
|
||||
op_t temp;
|
||||
int n;
|
||||
|
||||
if (((type = fp_homogeneous_type (c2m_ctx, arg_type, &n)) == MIR_T_F || type == MIR_T_D)
|
||||
&& n <= 8) {
|
||||
assert (arg.mir_op.mode == MIR_OP_MEM);
|
||||
arg = mem_to_address (c2m_ctx, arg, TRUE);
|
||||
for (int i = 0; i < n; i++) {
|
||||
temp = get_new_temp (c2m_ctx, type);
|
||||
MIR_append_insn (ctx, curr_func,
|
||||
MIR_new_insn (ctx, tp_mov (type), temp.mir_op,
|
||||
MIR_new_mem_op (ctx, type, (type == MIR_T_F ? 4 : 8) * i,
|
||||
arg.mir_op.u.reg, 0, 1)));
|
||||
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (arg_type->mode != TM_STRUCT && arg_type->mode != TM_UNION) {
|
||||
VARR_PUSH (MIR_op_t, call_ops, arg.mir_op);
|
||||
} else {
|
||||
assert (arg.mir_op.mode == MIR_OP_MEM);
|
||||
arg = mem_to_address (c2m_ctx, arg, TRUE);
|
||||
VARR_PUSH (MIR_op_t, call_ops,
|
||||
MIR_new_mem_op (ctx, MIR_T_BLK, type_size (c2m_ctx, arg_type), arg.mir_op.u.reg, 0,
|
||||
1));
|
||||
}
|
||||
}
|
||||
|
||||
static int target_gen_gather_arg (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
|
||||
decl_t param_decl, target_arg_info_t *arg_info) {
|
||||
MIR_context_t ctx = c2m_ctx->ctx;
|
||||
MIR_var_t var;
|
||||
MIR_type_t type;
|
||||
reg_var_t reg_var;
|
||||
int i, n;
|
||||
|
||||
if (((type = fp_homogeneous_type (c2m_ctx, arg_type, &n)) == MIR_T_F || type == MIR_T_D)
|
||||
&& n <= 8) {
|
||||
for (i = 0; i < n; i++) {
|
||||
assert (!param_decl->reg_p);
|
||||
reg_var = get_reg_var (c2m_ctx, type, gen_get_indexed_name (c2m_ctx, name, i));
|
||||
MIR_append_insn (ctx, curr_func,
|
||||
MIR_new_insn (ctx, tp_mov (type),
|
||||
MIR_new_mem_op (ctx, type,
|
||||
param_decl->offset
|
||||
+ (type == MIR_T_F ? 4 : 8) * i,
|
||||
MIR_reg (ctx, FP_NAME, curr_func->u.func), 0,
|
||||
1),
|
||||
MIR_new_reg_op (ctx, reg_var.reg)));
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2018-2020 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
s390x call ABI target specific code.
|
||||
*/
|
||||
|
||||
typedef int target_arg_info_t;
|
||||
|
||||
static void target_init_arg_vars (c2m_ctx_t c2m_ctx, target_arg_info_t *arg_info) {}
|
||||
|
||||
static int target_return_by_addr_p (c2m_ctx_t c2m_ctx, struct type *ret_type) {
|
||||
return simple_return_by_addr_p (c2m_ctx, ret_type);
|
||||
}
|
||||
|
||||
static void target_add_res_proto (c2m_ctx_t c2m_ctx, struct type *ret_type,
|
||||
target_arg_info_t *arg_info, VARR (MIR_type_t) * res_types,
|
||||
VARR (MIR_var_t) * arg_vars) {
|
||||
simple_add_res_proto (c2m_ctx, ret_type, arg_info, res_types, arg_vars);
|
||||
}
|
||||
|
||||
static int target_add_call_res_op (c2m_ctx_t c2m_ctx, struct type *ret_type,
|
||||
target_arg_info_t *arg_info, size_t call_arg_area_offset) {
|
||||
return simple_add_call_res_op (c2m_ctx, ret_type, arg_info, call_arg_area_offset);
|
||||
}
|
||||
|
||||
static op_t target_gen_post_call_res_code (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res,
|
||||
MIR_insn_t call, size_t call_ops_start) {
|
||||
return simple_gen_post_call_res_code (c2m_ctx, ret_type, res, call, call_ops_start);
|
||||
}
|
||||
|
||||
static void target_add_ret_ops (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res) {
|
||||
simple_add_ret_ops (c2m_ctx, ret_type, res);
|
||||
}
|
||||
|
||||
static int reg_aggregate_p (c2m_ctx_t c2m_ctx, struct type *arg_type) {
|
||||
size_t size = type_size (c2m_ctx, arg_type);
|
||||
return size == 1 || size == 2 || size == 4 || size == 8;
|
||||
}
|
||||
|
||||
static void target_add_arg_proto (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
|
||||
target_arg_info_t *arg_info, VARR (MIR_var_t) * arg_vars) {
|
||||
MIR_var_t var;
|
||||
MIR_type_t type;
|
||||
|
||||
if (arg_type->mode != TM_STRUCT && arg_type->mode != TM_UNION)
|
||||
type = get_mir_type (c2m_ctx, arg_type);
|
||||
else if (reg_aggregate_p (c2m_ctx, arg_type))
|
||||
type = MIR_T_I64;
|
||||
else
|
||||
type = MIR_T_BLK;
|
||||
var.name = name;
|
||||
var.type = type;
|
||||
if (type == MIR_T_BLK) var.size = type_size (c2m_ctx, arg_type);
|
||||
VARR_PUSH (MIR_var_t, arg_vars, var);
|
||||
}
|
||||
|
||||
static void target_add_call_arg_op (c2m_ctx_t c2m_ctx, struct type *arg_type,
|
||||
target_arg_info_t *arg_info, op_t arg) {
|
||||
op_t temp;
|
||||
|
||||
if (arg_type->mode != TM_STRUCT && arg_type->mode != TM_UNION) {
|
||||
VARR_PUSH (MIR_op_t, call_ops, arg.mir_op);
|
||||
} else if (reg_aggregate_p (c2m_ctx, arg_type)) {
|
||||
assert (arg.mir_op.mode == MIR_OP_MEM);
|
||||
temp = get_new_temp (c2m_ctx, MIR_T_I64);
|
||||
gen_multiple_load_store (c2m_ctx, arg_type, &temp.mir_op, arg.mir_op, TRUE);
|
||||
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
|
||||
} else {
|
||||
assert (arg.mir_op.mode == MIR_OP_MEM);
|
||||
arg = mem_to_address (c2m_ctx, arg, TRUE);
|
||||
VARR_PUSH (MIR_op_t, call_ops,
|
||||
MIR_new_mem_op (c2m_ctx->ctx, MIR_T_BLK, type_size (c2m_ctx, arg_type),
|
||||
arg.mir_op.u.reg, 0, 1));
|
||||
}
|
||||
}
|
||||
|
||||
static int target_gen_gather_arg (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
|
||||
decl_t param_decl, target_arg_info_t *arg_info) {
|
||||
MIR_context_t ctx = c2m_ctx->ctx;
|
||||
MIR_type_t type;
|
||||
MIR_op_t param_op;
|
||||
reg_var_t reg_var;
|
||||
|
||||
if ((arg_type->mode != TM_STRUCT && arg_type->mode != TM_UNION)
|
||||
|| !reg_aggregate_p (c2m_ctx, arg_type))
|
||||
return FALSE;
|
||||
assert (!param_decl->reg_p);
|
||||
reg_var = get_reg_var (c2m_ctx, MIR_T_I64, name);
|
||||
param_op = MIR_new_reg_op (ctx, reg_var.reg);
|
||||
gen_multiple_load_store (c2m_ctx, arg_type, ¶m_op,
|
||||
MIR_new_mem_op (ctx, MIR_T_UNDEF, param_decl->offset,
|
||||
MIR_reg (ctx, FP_NAME, curr_func->u.func), 0, 1),
|
||||
FALSE);
|
||||
return TRUE;
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2019-2020 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
static char x86_64_mirc[]
|
||||
= "#define __amd64 1\n"
|
||||
"#define __amd64__ 1\n"
|
||||
"#define __x86_64 1\n"
|
||||
"#define __x86_64__ 1\n"
|
||||
"\n"
|
||||
"#define __SIZEOF_DOUBLE__ 8\n"
|
||||
"#define __SIZEOF_FLOAT__ 4\n"
|
||||
"#define __SIZEOF_INT__ 4\n"
|
||||
#if __SIZEOF_LONG_DOUBLE__ == 16
|
||||
"#define __SIZEOF_LONG_DOUBLE__ 16\n"
|
||||
#else
|
||||
"#define __SIZEOF_LONG_DOUBLE__ 8\n"
|
||||
#endif
|
||||
"#define __SIZEOF_LONG_LONG__ 8\n"
|
||||
"#define __SIZEOF_LONG__ 4\n"
|
||||
"#define __SIZEOF_POINTER__ 8\n"
|
||||
"#define __SIZEOF_PTRDIFF_T__ 8\n"
|
||||
"#define __SIZEOF_SHORT__ 2\n"
|
||||
"#define __SIZEOF_SIZE_T__ 8\n"
|
||||
"\n"
|
||||
"#define __BYTE_ORDER__ 1234\n"
|
||||
"#define __ORDER_LITTLE_ENDIAN__ 1234\n"
|
||||
"#define __ORDER_BIG_ENDIAN__ 4321\n"
|
||||
"\n"
|
||||
"/* Some type macros: */\n"
|
||||
"#define __SIZE_TYPE__ long long unsigned int\n"
|
||||
"#define __PTRDIFF_TYPE__ long long int\n"
|
||||
"#define __INTMAX_TYPE__ long long int\n"
|
||||
"#define __UINTMAX_TYPE__ long long unsigned int\n"
|
||||
"#define __INT8_TYPE__ signed char\n"
|
||||
"#define __INT16_TYPE__ short\n"
|
||||
"#define __INT32_TYPE__ int\n"
|
||||
"#define __INT64_TYPE__ long long int\n"
|
||||
"#define __UINT8_TYPE__ unsigned char\n"
|
||||
"#define __UINT16_TYPE__ unsigned short\n"
|
||||
"#define __UINT32_TYPE__ unsigned int\n"
|
||||
"#define __UINT64_TYPE__ long long unsigned int\n"
|
||||
"#define __INTPTR_TYPE__ long long int\n"
|
||||
"#define __UINTPTR_TYPE__ long long unsigned int\n"
|
||||
"\n"
|
||||
"#define __CHAR_BIT__ 8\n"
|
||||
"#define __INT8_MAX__ 127\n"
|
||||
"#define __INT16_MAX__ 32767\n"
|
||||
"#define __INT32_MAX__ 2147483647\n"
|
||||
"#define __INT64_MAX__ 9223372036854775807LL\n"
|
||||
"#define __UINT8_MAX__ (__INT8_MAX__ * 2u + 1u)\n"
|
||||
"#define __UINT16_MAX__ (__INT16_MAX__ * 2u + 1u)\n"
|
||||
"#define __UINT32_MAX__ (__INT32_MAX__ * 2u + 1u)\n"
|
||||
"#define __UINT64_MAX__ (__INT64_MAX__ * 2u + 1u)\n"
|
||||
"#define __SCHAR_MAX__ __INT8_MAX__\n"
|
||||
"#define __SHRT_MAX__ __INT16_MAX__\n"
|
||||
"#define __INT_MAX__ __INT32_MAX__\n"
|
||||
"#define __LONG_MAX__ __INT32_MAX__\n"
|
||||
"#define __LONG_LONG_MAX__ __INT64_MAX__\n"
|
||||
"#define __SIZE_MAX__ __UINT64_MAX__\n"
|
||||
"#define __PTRDIFF_MAX__ __INT64_MAX__\n"
|
||||
"#define __INTMAX_MAX__ __INT64_MAX__\n"
|
||||
"#define __UINTMAX_MAX__ __UINT64_MAX__\n"
|
||||
"#define __INTPTR_MAX__ __INT64_MAX__\n"
|
||||
"#define __UINTPTR_MAX__ __UINT64_MAX__\n"
|
||||
"\n"
|
||||
"#define __FLT_MIN_EXP__ (-125)\n"
|
||||
"#define __FLT_MAX_EXP__ 128\n"
|
||||
"#define __FLT_DIG__ 6\n"
|
||||
"#define __FLT_DECIMAL_DIG__ 9\n"
|
||||
"#define __FLT_MANT_DIG__ 24\n"
|
||||
"#define __FLT_MIN__ 1.17549435082228750796873653722224568e-38F\n"
|
||||
"#define __FLT_MAX__ 3.40282346638528859811704183484516925e+38F\n"
|
||||
"#define __FLT_EPSILON__ 1.19209289550781250000000000000000000e-7F\n"
|
||||
"\n"
|
||||
"#define __DBL_MIN_EXP__ (-1021)\n"
|
||||
"#define __DBL_MAX_EXP__ 1024\n"
|
||||
"#define __DBL_DIG__ 15\n"
|
||||
"#define __DBL_DECIMAL_DIG__ 17\n"
|
||||
"#define __DBL_MANT_DIG__ 53\n"
|
||||
"#define __DBL_MAX__ ((double) 1.79769313486231570814527423731704357e+308L)\n"
|
||||
"#define __DBL_MIN__ ((double) 2.22507385850720138309023271733240406e-308L)\n"
|
||||
"#define __DBL_EPSILON__ ((double) 2.22044604925031308084726333618164062e-16L)\n"
|
||||
"\n"
|
||||
"typedef unsigned short char16_t;\n"
|
||||
"typedef unsigned int char32_t;\n"
|
||||
"\n"
|
||||
"#define WIN32 1\n"
|
||||
"#define _WIN32 1\n"
|
||||
"#define __WIN32 1\n"
|
||||
"#define __WIN32__ 1\n"
|
||||
"#define WIN64 1\n"
|
||||
"#define _WIN64 1\n"
|
||||
"#define __WIN64 1\n"
|
||||
"#define __WIN64__ 1\n"
|
||||
"#define WINNT 1\n"
|
||||
"#define __WINNT 1\n"
|
||||
"#define __WINNT__ 1\n"
|
||||
"#define __MSVCRT__ 1\n"
|
||||
"\n"
|
||||
"void *alloca (long long unsigned);\n";
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue