From: Christoph Mallon Date: Sun, 11 Nov 2012 10:44:24 +0000 (+0100) Subject: Merge the (single) pop and non-pop variants of x87 compare operations. X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=a5119453079dc020a76b9c8f31919e8592c8f072;p=libfirm Merge the (single) pop and non-pop variants of x87 compare operations. Let a flag and the emitter handle printing the pop variant. --- diff --git a/ir/be/ia32/ia32_emitter.c b/ir/be/ia32/ia32_emitter.c index fa64cb76c..02c3b21fb 100644 --- a/ir/be/ia32/ia32_emitter.c +++ b/ir/be/ia32/ia32_emitter.c @@ -794,13 +794,11 @@ static ia32_condition_code_t determine_final_cc(const ir_node *node, if (is_ia32_Sahf(flags)) { ir_node *cmp = get_irn_n(flags, n_ia32_Sahf_val); - if (!(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp) - || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp))) { + if (!(is_ia32_FucomFnstsw(cmp) || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp))) { inc_irg_visited(current_ir_graph); cmp = find_original_value(cmp); assert(cmp != NULL); - assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp) - || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp)); + assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp)); } flags_attr = get_ia32_attr_const(cmp); @@ -3490,30 +3488,15 @@ static void bemit_ftstfnstsw(const ir_node *node) static void bemit_fucomi(const ir_node *node) { const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node); - bemit8(0xDB); // fucomi - 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(attr->pop ? 0xDF : 0xDB); // fucom[p]i bemit8(0xE8 + attr->x87[1]->index); } static void bemit_fucomfnstsw(const ir_node *node) { const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node); - bemit8(0xDD); // fucom - bemit8(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); + bemit8(0xDD); // fucom[p] + bemit8((attr->pop ? 0xE8 : 0xE0) + attr->x87[1]->index); bemit_fnstsw(); } @@ -3587,8 +3570,6 @@ static void ia32_register_binary_emitters(void) register_emitter(op_ia32_FtstFnstsw, bemit_ftstfnstsw); register_emitter(op_ia32_FucomFnstsw, bemit_fucomfnstsw); 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_IDiv, bemit_idiv); register_emitter(op_ia32_IJmp, bemit_ijmp); diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index eda6bc1c7..77471cedd 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -2509,15 +2509,7 @@ femms => { FucomFnstsw => { reg_req => { }, - emit => "fucom %F1\n". - "fnstsw %%ax", - attr_type => "ia32_x87_attr_t", - latency => 2, -}, - -FucompFnstsw => { - reg_req => { }, - emit => "fucomp %F1\n". + emit => "fucom%FP %F1\n". "fnstsw %%ax", attr_type => "ia32_x87_attr_t", latency => 2, @@ -2533,14 +2525,7 @@ FucomppFnstsw => { Fucomi => { reg_req => { }, - emit => 'fucomi %F1', - attr_type => "ia32_x87_attr_t", - latency => 1, -}, - -Fucompi => { - reg_req => { }, - emit => 'fucompi %F1', + emit => 'fucom%FPi %F1', attr_type => "ia32_x87_attr_t", latency => 1, }, diff --git a/ir/be/ia32/ia32_x87.c b/ir/be/ia32/ia32_x87.c index 0f1828e21..5728efe3c 100644 --- a/ir/be/ia32/ia32_x87.c +++ b/ir/be/ia32/ia32_x87.c @@ -1383,8 +1383,8 @@ static int sim_Fucom(x87_state *state, ir_node *n) int i; switch (pops) { + case 1: attr->pop = true; /* FALLTHROUGH */ case 0: dst = op_ia32_FucomFnstsw; break; - case 1: dst = op_ia32_FucompFnstsw; break; case 2: dst = op_ia32_FucomppFnstsw; break; default: panic("invalid popcount"); } @@ -1393,11 +1393,12 @@ static int sim_Fucom(x87_state *state, ir_node *n) x87_pop(state); } } else if (is_ia32_vFucomi(n)) { + dst = op_ia32_Fucomi; switch (pops) { - case 0: dst = op_ia32_Fucomi; break; - case 1: dst = op_ia32_Fucompi; x87_pop(state); break; + case 0: break; + case 1: attr->pop = true; x87_pop(state); break; case 2: - dst = op_ia32_Fucompi; + attr->pop = true; x87_pop(state); x87_create_fpop(state, sched_next(n), 1); break;