Commit 362d8b84 authored by Christoph Mallon's avatar Christoph Mallon
Browse files

ia32: Do not add fp register inputs/outputs when compiling for soft-float.

parent 5624adba
......@@ -12,6 +12,7 @@
#include "bearch_ia32_t.h"
#include "becconv.h"
#include "beirg.h"
#include "ia32_architecture.h"
#include "x86_cconv.h"
#include "irmode_t.h"
#include "irgwalk.h"
......@@ -69,10 +70,13 @@ static const arch_register_t* const sse_result_regs[] = {
};
#endif
static const unsigned caller_saves[] = {
static const unsigned caller_saves_gp[] = {
REG_EAX,
REG_ECX,
REG_EDX,
};
static const unsigned caller_saves_fp[] = {
REG_ST0,
REG_ST1,
REG_ST2,
......@@ -90,6 +94,7 @@ static const unsigned caller_saves[] = {
REG_XMM6,
REG_XMM7,
};
static unsigned default_caller_saves[BITSET_SIZE_ELEMS(N_IA32_REGISTERS)];
static const unsigned callee_saves[] = {
......@@ -97,7 +102,6 @@ static const unsigned callee_saves[] = {
REG_EBP,
REG_ESI,
REG_EDI,
REG_FPCW,
};
static unsigned default_callee_saves[BITSET_SIZE_ELEMS(N_IA32_REGISTERS)];
......@@ -232,6 +236,10 @@ align_stack:;
void ia32_cconv_init(void)
{
be_cconv_add_regs(default_caller_saves, caller_saves, ARRAY_SIZE(caller_saves));
be_cconv_add_regs(default_caller_saves, caller_saves_gp, ARRAY_SIZE(caller_saves_gp));
be_cconv_add_regs(default_callee_saves, callee_saves, ARRAY_SIZE(callee_saves));
if (!ia32_cg_config.use_softfloat) {
be_cconv_add_regs(default_caller_saves, caller_saves_fp, ARRAY_SIZE(caller_saves_fp));
rbitset_set(default_callee_saves, REG_FPCW);
}
}
......@@ -1135,8 +1135,8 @@ Call => {
state => "exc_pinned",
in_reqs => "...",
out_reqs => "...",
ins => [ "base", "index", "mem", "callee", "stack", "fpcw", "first_argument" ],
outs => [ "mem", "stack", "fpcw", "first_result" ],
ins => [ "base", "index", "mem", "callee", "stack", "first_argument" ],
outs => [ "mem", "stack", "first_result" ],
emit => "call %*AS3",
attr_type => "ia32_call_attr_t",
attr => "unsigned pop, ir_type *call_tp",
......
......@@ -4953,9 +4953,10 @@ static ir_node *gen_Call(ir_node *node)
x86_cconv_t *const cconv = ia32_decide_calling_convention(type, NULL);
ir_graph *const irg = get_irn_irg(node);
unsigned in_arity = n_ia32_Call_first_argument;
bool const has_fpcw = !ia32_cg_config.use_softfloat;
bool const is_plt = callee_is_plt(callee);
unsigned const n_ins
= in_arity + cconv->n_param_regs + is_plt;
= has_fpcw + in_arity + cconv->n_param_regs + is_plt;
ir_node **const in = ALLOCAN(ir_node*, n_ins);
arch_register_req_t const **const in_req = be_allocate_in_reqs(irg, n_ins);
......@@ -4978,8 +4979,11 @@ static ir_node *gen_Call(ir_node *node)
in[n_ia32_Call_stack] = callframe;
in_req[n_ia32_Call_stack] = sp->single_req;
in[n_ia32_Call_fpcw] = get_initial_fpcw(irg);
in_req[n_ia32_Call_fpcw] = fpcw->single_req;
if (has_fpcw) {
unsigned const fpcwi = in_arity++;
in[fpcwi] = get_initial_fpcw(irg);
in_req[fpcwi] = fpcw->single_req;
}
uint8_t add_pressure = 0;
unsigned sync_arity = 0;
......@@ -5042,7 +5046,7 @@ static ir_node *gen_Call(ir_node *node)
unsigned o = pn_ia32_Call_first_result;
unsigned const n_reg_results = cconv->n_reg_results;
unsigned const n_caller_saves = rbitset_popcount(cconv->caller_saves, N_IA32_REGISTERS);
unsigned const n_out = o + n_reg_results + n_caller_saves;
unsigned const n_out = has_fpcw + o + n_reg_results + n_caller_saves;
/* Create node. */
ir_node *const call = new_bd_ia32_Call(dbgi, block, in_arity, in, in_req, n_out, cconv->sp_delta, type);
......@@ -5061,9 +5065,6 @@ static ir_node *gen_Call(ir_node *node)
arch_copy_irn_out_info(call, pn_ia32_Call_stack, callframe);
arch_set_irn_register_req_out(call, pn_ia32_Call_fpcw, fpcw->single_req);
arch_set_irn_register_out(call, pn_ia32_Call_fpcw, fpcw);
unsigned const n_ress = get_method_n_ress(type);
for (unsigned r = 0; r < n_ress; ++r) {
arch_register_t const *const reg = cconv->results[r].reg;
......@@ -5072,6 +5073,13 @@ static ir_node *gen_Call(ir_node *node)
if (reg->cls == &ia32_reg_classes[CLASS_ia32_fp])
ia32_request_x87_sim(irg);
}
if (has_fpcw) {
unsigned const fpcwo = o++;
arch_set_irn_register_req_out(call, fpcwo, fpcw->single_req);
arch_set_irn_register_out( call, fpcwo, fpcw);
}
/* Caller saves. */
unsigned const *const allocatable_regs = be_birg_from_irg(irg)->allocatable_regs;
for (unsigned i = 0; i < N_IA32_REGISTERS; ++i) {
......
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