Merge the (single) pop and non-pop variants of x87 compare operations.
authorChristoph Mallon <christoph.mallon@gmx.de>
Sun, 11 Nov 2012 10:44:24 +0000 (11:44 +0100)
committerChristoph Mallon <christoph.mallon@gmx.de>
Mon, 12 Nov 2012 08:57:58 +0000 (09:57 +0100)
Let a flag and the emitter handle printing the pop variant.

ir/be/ia32/ia32_emitter.c
ir/be/ia32/ia32_spec.pl
ir/be/ia32/ia32_x87.c

index fa64cb7..02c3b21 100644 (file)
@@ -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);
index eda6bc1..77471ce 100644 (file)
@@ -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,
 },
index 0f1828e..5728efe 100644 (file)
@@ -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;