Commit 7e2f8e64 authored by Matthias Braun's avatar Matthias Braun
Browse files

amd64: x87 sim function for amd64_call

parent d54ff09c
......@@ -512,6 +512,12 @@ end_of_mods:
= amd64_get_x87_attr_const(node);
if (attr->pop)
be_emit_char('p');
} else if (*fmt == '0') {
++fmt;
x87_attr_t const *const attr
= amd64_get_x87_attr_const(node);
be_emit_char('%');
be_emit_string(attr->reg->name);
} else {
x87_attr_t const *const attr
= amd64_get_x87_attr_const(node);
......
......@@ -125,6 +125,7 @@ typedef struct {
typedef struct {
amd64_addr_attr_t base;
unsigned n_reg_results; /**< number of results in registers */
ir_type *call_tp;
} amd64_call_addr_attr_t;
......
......@@ -1775,7 +1775,8 @@ no_call_mem:
.insn_mode = INSN_MODE_64,
.addr = addr,
},
.call_tp = type,
.call_tp = type,
.n_reg_results = cconv->n_reg_results,
};
/* create call node */
......@@ -1791,11 +1792,12 @@ no_call_mem:
/* add register requirements for the result regs */
for (size_t r = 0; r < n_ress; ++r) {
const reg_or_stackslot_t *result_info = &cconv->results[r];
const arch_register_t *reg = result_info->reg;
const reg_or_stackslot_t *result_info = &cconv->results[r];
const arch_register_t *reg = result_info->reg;
if (reg != NULL)
arch_set_irn_register_req_out(call, o++, reg->single_req);
}
const unsigned *allocatable_regs = be_birg_from_irg(irg)->allocatable_regs;
for (size_t i = 0; i < N_AMD64_REGISTERS; ++i) {
if (!rbitset_is_set(cconv->caller_saves, i))
......
......@@ -36,9 +36,25 @@ static void sim_amd64_fld(x87_state *const state, ir_node *const node)
x86_sim_x87_load(state, node, value);
}
static void sim_amd64_call(x87_state *const state, ir_node *const node)
{
/** push fp results onto x87 stack */
amd64_call_addr_attr_t const *const attr
= get_amd64_call_addr_attr(node);
for (unsigned o = 0, n = attr->n_reg_results; o < n; ++o) {
unsigned const pn = pn_amd64_call_first_result + o;
arch_register_t const *const reg = arch_get_irn_register_out(node, pn);
if (reg->cls == &amd64_reg_classes[CLASS_amd64_x87]) {
ir_node *const value = get_Proj_for_pn(node, pn);
x86_x87_push(state, value);
}
}
}
static void prepare_callbacks(void)
{
x86_prepare_x87_callbacks();
x86_register_x87_sim(op_amd64_call, sim_amd64_call);
x86_register_x87_sim(op_amd64_fld, sim_amd64_fld);
x86_register_x87_sim(op_amd64_fst, sim_amd64_fst);
x86_register_x87_sim(op_amd64_fstp, sim_amd64_fstp);
......
......@@ -219,7 +219,7 @@ static unsigned is_at_pos(x87_state const *const state, ir_node const *const val
* @param state the x87 state
* @param node the node that produces the value of the fp register
*/
static void x87_push(x87_state *const state, ir_node *const node)
void x86_x87_push(x87_state *const state, ir_node *const node)
{
assert(x87_on_stack(state, node) == (unsigned)-1 && "double push");
assert(state->depth < N_X87_REGS && "stack overrun");
......@@ -453,7 +453,7 @@ static ir_node *x87_create_fdup(x87_state *const state, ir_node *const block,
arch_register_t const *const reg = get_st_reg(pos);
ir_node *const fdup = x87.new_bd_fdup(NULL, block, val, reg);
arch_set_irn_register(fdup, out);
x87_push(state, fdup);
x86_x87_push(state, fdup);
DB((dbg, LEVEL_1, "<<< %s %s\n", get_irn_opname(fdup), reg->name));
return fdup;
}
......@@ -781,7 +781,7 @@ static void sim_unop(x87_state *state, ir_node *n)
void x86_sim_x87_load(x87_state *state, ir_node *n, ir_node *value)
{
DB((dbg, LEVEL_1, ">>> %+F\n", n));
x87_push(state, value);
x86_x87_push(state, value);
DB((dbg, LEVEL_1, "<<< %s -> %s\n", get_irn_opname(n), get_st_reg(0)->name));
}
......@@ -1075,7 +1075,7 @@ static void sim_be_Copy(x87_state *state, ir_node *n)
copy = exact_copy(pred);
set_nodes_block(copy, block);
arch_set_irn_register(copy, out);
x87_push(state, copy);
x86_x87_push(state, copy);
} else {
copy = x87_create_fdup(state, block, pred, out);
}
......@@ -1103,7 +1103,7 @@ static void sim_be_Copy(x87_state *state, ir_node *n)
* @param state the x87 state
* @param n the node that should be simulated (and patched)
*/
static void sim_Call(x87_state *state, ir_node *n)
static void sim_ia32_Call(x87_state *const state, ir_node *const n)
{
DB((dbg, LEVEL_1, ">>> %+F\n", n));
......@@ -1117,7 +1117,7 @@ static void sim_Call(x87_state *state, ir_node *n)
* Moreover, only one return result is supported. */
if (is_x87_req(arch_get_irn_register_req_out(n, pn_ia32_Call_first_result))) {
ir_node *const res = get_Proj_for_pn(n, pn_ia32_Call_first_result);
x87_push(state, res);
x86_x87_push(state, res);
}
}
DB((dbg, LEVEL_1, "Stack after: "));
......@@ -1342,11 +1342,11 @@ static void sim_be_Asm(x87_state *const state, ir_node *const n)
if (out_u) {
if (!out_t && !in_t)
panic("\"u\" output constraint without \"t\" constraint in %+F", n);
x87_push(state, out_u);
x86_x87_push(state, out_u);
}
if (out_t)
x87_push(state, out_t);
x86_x87_push(state, out_t);
/* Remove dying values. */
x87_kill_deads(state->sim, n, state);
......@@ -1445,7 +1445,7 @@ void x86_prepare_x87_callbacks(void)
void x86_prepare_x87_callbacks_ia32(void)
{
x86_prepare_x87_callbacks();
x86_register_x87_sim(op_ia32_Call, sim_Call);
x86_register_x87_sim(op_ia32_Call, sim_ia32_Call);
x86_register_x87_sim(op_ia32_fabs, sim_unop);
x86_register_x87_sim(op_ia32_fadd, sim_binop);
x86_register_x87_sim(op_ia32_fchs, sim_unop);
......
......@@ -60,6 +60,9 @@ void x86_sim_x87_store_pop(x87_state *state, ir_node *n, int val_pos);
void x86_sim_x87_ret(x87_state *state, ir_node *node);
/** Push a value on the x87 stack. Intended to be used in sim functions. */
void x86_x87_push(x87_state *state, ir_node *value);
/**
* Register a simulator function.
*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment