Commit a5119453 authored by Christoph Mallon's avatar Christoph Mallon
Browse files

Merge the (single) pop and non-pop variants of x87 compare operations.

Let a flag and the emitter handle printing the pop variant.
parent f8783b28
...@@ -794,13 +794,11 @@ static ia32_condition_code_t determine_final_cc(const ir_node *node, ...@@ -794,13 +794,11 @@ static ia32_condition_code_t determine_final_cc(const ir_node *node,
if (is_ia32_Sahf(flags)) { if (is_ia32_Sahf(flags)) {
ir_node *cmp = get_irn_n(flags, n_ia32_Sahf_val); ir_node *cmp = get_irn_n(flags, n_ia32_Sahf_val);
if (!(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp) if (!(is_ia32_FucomFnstsw(cmp) || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp))) {
|| is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp))) {
inc_irg_visited(current_ir_graph); inc_irg_visited(current_ir_graph);
cmp = find_original_value(cmp); cmp = find_original_value(cmp);
assert(cmp != NULL); assert(cmp != NULL);
assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp) assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp));
|| is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp));
} }
flags_attr = get_ia32_attr_const(cmp); flags_attr = get_ia32_attr_const(cmp);
...@@ -3490,30 +3488,15 @@ static void bemit_ftstfnstsw(const ir_node *node) ...@@ -3490,30 +3488,15 @@ static void bemit_ftstfnstsw(const ir_node *node)
static void bemit_fucomi(const ir_node *node) static void bemit_fucomi(const ir_node *node)
{ {
const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node); const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
bemit8(0xDB); // fucomi bemit8(attr->pop ? 0xDF : 0xDB); // fucom[p]i
bemit8(0xE8 + attr->x87[1]->index);
}
static void bemit_fucomip(const ir_node *node)
{
const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
bemit8(0xDF); // fucomip
bemit8(0xE8 + attr->x87[1]->index); bemit8(0xE8 + attr->x87[1]->index);
} }
static void bemit_fucomfnstsw(const ir_node *node) static void bemit_fucomfnstsw(const ir_node *node)
{ {
const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node); const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
bemit8(0xDD); // fucom bemit8(0xDD); // fucom[p]
bemit8(0xE0 + attr->x87[1]->index); bemit8((attr->pop ? 0xE8 : 0xE0) + attr->x87[1]->index);
bemit_fnstsw();
}
static void bemit_fucompfnstsw(const ir_node *node)
{
const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
bemit8(0xDD); // fucomp
bemit8(0xE8 + attr->x87[1]->index);
bemit_fnstsw(); bemit_fnstsw();
} }
...@@ -3587,8 +3570,6 @@ static void ia32_register_binary_emitters(void) ...@@ -3587,8 +3570,6 @@ static void ia32_register_binary_emitters(void)
register_emitter(op_ia32_FtstFnstsw, bemit_ftstfnstsw); register_emitter(op_ia32_FtstFnstsw, bemit_ftstfnstsw);
register_emitter(op_ia32_FucomFnstsw, bemit_fucomfnstsw); register_emitter(op_ia32_FucomFnstsw, bemit_fucomfnstsw);
register_emitter(op_ia32_Fucomi, bemit_fucomi); register_emitter(op_ia32_Fucomi, bemit_fucomi);
register_emitter(op_ia32_FucompFnstsw, bemit_fucompfnstsw);
register_emitter(op_ia32_Fucompi, bemit_fucomip);
register_emitter(op_ia32_FucomppFnstsw, bemit_fucomppfnstsw); register_emitter(op_ia32_FucomppFnstsw, bemit_fucomppfnstsw);
register_emitter(op_ia32_IDiv, bemit_idiv); register_emitter(op_ia32_IDiv, bemit_idiv);
register_emitter(op_ia32_IJmp, bemit_ijmp); register_emitter(op_ia32_IJmp, bemit_ijmp);
......
...@@ -2509,15 +2509,7 @@ femms => { ...@@ -2509,15 +2509,7 @@ femms => {
FucomFnstsw => { FucomFnstsw => {
reg_req => { }, reg_req => { },
emit => "fucom %F1\n". emit => "fucom%FP %F1\n".
"fnstsw %%ax",
attr_type => "ia32_x87_attr_t",
latency => 2,
},
FucompFnstsw => {
reg_req => { },
emit => "fucomp %F1\n".
"fnstsw %%ax", "fnstsw %%ax",
attr_type => "ia32_x87_attr_t", attr_type => "ia32_x87_attr_t",
latency => 2, latency => 2,
...@@ -2533,14 +2525,7 @@ FucomppFnstsw => { ...@@ -2533,14 +2525,7 @@ FucomppFnstsw => {
Fucomi => { Fucomi => {
reg_req => { }, reg_req => { },
emit => 'fucomi %F1', emit => 'fucom%FPi %F1',
attr_type => "ia32_x87_attr_t",
latency => 1,
},
Fucompi => {
reg_req => { },
emit => 'fucompi %F1',
attr_type => "ia32_x87_attr_t", attr_type => "ia32_x87_attr_t",
latency => 1, latency => 1,
}, },
......
...@@ -1383,8 +1383,8 @@ static int sim_Fucom(x87_state *state, ir_node *n) ...@@ -1383,8 +1383,8 @@ static int sim_Fucom(x87_state *state, ir_node *n)
int i; int i;
switch (pops) { switch (pops) {
case 1: attr->pop = true; /* FALLTHROUGH */
case 0: dst = op_ia32_FucomFnstsw; break; case 0: dst = op_ia32_FucomFnstsw; break;
case 1: dst = op_ia32_FucompFnstsw; break;
case 2: dst = op_ia32_FucomppFnstsw; break; case 2: dst = op_ia32_FucomppFnstsw; break;
default: panic("invalid popcount"); default: panic("invalid popcount");
} }
...@@ -1393,11 +1393,12 @@ static int sim_Fucom(x87_state *state, ir_node *n) ...@@ -1393,11 +1393,12 @@ static int sim_Fucom(x87_state *state, ir_node *n)
x87_pop(state); x87_pop(state);
} }
} else if (is_ia32_vFucomi(n)) { } else if (is_ia32_vFucomi(n)) {
dst = op_ia32_Fucomi;
switch (pops) { switch (pops) {
case 0: dst = op_ia32_Fucomi; break; case 0: break;
case 1: dst = op_ia32_Fucompi; x87_pop(state); break; case 1: attr->pop = true; x87_pop(state); break;
case 2: case 2:
dst = op_ia32_Fucompi; attr->pop = true;
x87_pop(state); x87_pop(state);
x87_create_fpop(state, sched_next(n), 1); x87_create_fpop(state, sched_next(n), 1);
break; break;
......
Supports Markdown
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