From f8783b286f710b6729ca1b1099cadee53ef2939b Mon Sep 17 00:00:00 2001 From: Christoph Mallon Date: Sun, 11 Nov 2012 11:14:39 +0100 Subject: [PATCH] Merge the pop and non-pop variants of x87 store operations. Let a flag and the emitter handle printing the pop variant. --- ir/be/ia32/bearch_ia32.c | 1 - ir/be/ia32/ia32_emitter.c | 98 ++++++++++----------------------------- ir/be/ia32/ia32_spec.pl | 23 +-------- ir/be/ia32/ia32_x87.c | 22 +++++---- 4 files changed, 40 insertions(+), 104 deletions(-) diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index 304f5dc3d..3bf373b97 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -1134,7 +1134,6 @@ need_stackent: case iro_ia32_Store8Bit: case iro_ia32_Store: case iro_ia32_fst: - case iro_ia32_fstp: case iro_ia32_vfist: case iro_ia32_vfisttp: case iro_ia32_vfst: diff --git a/ir/be/ia32/ia32_emitter.c b/ir/be/ia32/ia32_emitter.c index f304d8029..fa64cb76c 100644 --- a/ir/be/ia32/ia32_emitter.c +++ b/ir/be/ia32/ia32_emitter.c @@ -3353,42 +3353,19 @@ static void bemit_fild(const ir_node *node) static void bemit_fist(const ir_node *node) { - switch (get_mode_size_bits(get_ia32_ls_mode(node))) { - case 16: - bemit8(0xDF); // fists - break; - - case 32: - bemit8(0xDB); // fistl - break; - - default: - panic("invalid mode size"); - } - bemit_mod_am(2, node); -} - -static void bemit_fistp(const ir_node *node) -{ - switch (get_mode_size_bits(get_ia32_ls_mode(node))) { - case 16: - bemit8(0xDF); // fistps - bemit_mod_am(3, node); - return; - - case 32: - bemit8(0xDB); // fistpl - bemit_mod_am(3, node); - return; - - case 64: - bemit8(0xDF); // fistpll - bemit_mod_am(7, node); - return; - - default: - panic("invalid mode size"); + unsigned op; + unsigned const size = get_mode_size_bits(get_ia32_ls_mode(node)); + switch (size) { + case 16: bemit8(0xDF); op = 2; break; // fist[p]s + case 32: bemit8(0xDB); op = 2; break; // fist[p]l + case 64: bemit8(0xDF); op = 6; break; // fistpll + default: panic("invalid mode size"); } + if (get_ia32_x87_attr_const(node)->pop) + ++op; + // There is only a pop variant for 64 bit integer store. + assert(size < 64 || get_ia32_x87_attr_const(node)->pop); + bemit_mod_am(op, node); } static void bemit_fisttp(ir_node const *const node) @@ -3468,43 +3445,20 @@ static void bemit_fpushcopy(const ir_node *node) static void bemit_fst(const ir_node *node) { - switch (get_mode_size_bits(get_ia32_ls_mode(node))) { - case 32: - bemit8(0xD9); // fsts - break; - - case 64: - bemit8(0xDD); // fstl - break; - - default: - panic("invalid mode size"); - } - bemit_mod_am(2, node); -} - -static void bemit_fstp(const ir_node *node) -{ - switch (get_mode_size_bits(get_ia32_ls_mode(node))) { - case 32: - bemit8(0xD9); // fstps - bemit_mod_am(3, node); - return; - - case 64: - bemit8(0xDD); // fstpl - bemit_mod_am(3, node); - return; - - case 80: - case 96: - bemit8(0xDB); // fstpt - bemit_mod_am(7, node); - return; - - default: - panic("invalid mode size"); + unsigned op; + unsigned const size = get_mode_size_bits(get_ia32_ls_mode(node)); + switch (size) { + case 32: bemit8(0xD9); op = 2; break; // fst[p]s + case 64: bemit8(0xDD); op = 2; break; // fst[p]l + case 80: + case 96: bemit8(0xDB); op = 6; break; // fstpt + default: panic("invalid mode size"); } + if (get_ia32_x87_attr_const(node)->pop) + ++op; + // There is only a pop variant for long double store. + assert(size < 80 || get_ia32_x87_attr_const(node)->pop); + bemit_mod_am(op, node); } static void bemit_fsub(const ir_node *node) @@ -3700,7 +3654,6 @@ static void ia32_register_binary_emitters(void) register_emitter(op_ia32_ffreep, bemit_ffreep); register_emitter(op_ia32_fild, bemit_fild); register_emitter(op_ia32_fist, bemit_fist); - register_emitter(op_ia32_fistp, bemit_fistp); register_emitter(op_ia32_fisttp, bemit_fisttp); register_emitter(op_ia32_fld, bemit_fld); register_emitter(op_ia32_fld1, bemit_fld1); @@ -3710,7 +3663,6 @@ static void ia32_register_binary_emitters(void) register_emitter(op_ia32_fpush, bemit_fpush); register_emitter(op_ia32_fpushCopy, bemit_fpushcopy); register_emitter(op_ia32_fst, bemit_fst); - register_emitter(op_ia32_fstp, bemit_fstp); register_emitter(op_ia32_fsub, bemit_fsub); register_emitter(op_ia32_fxch, bemit_fxch); diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index 933922ce6..eda6bc1c7 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -2338,17 +2338,7 @@ fld => { fst => { irn_flags => [ "rematerializable" ], state => "exc_pinned", - emit => 'fst%FM %AM', - mode => "mode_M", - attr_type => "ia32_x87_attr_t", - latency => 2, - constructors => {}, -}, - -fstp => { - irn_flags => [ "rematerializable" ], - state => "exc_pinned", - emit => 'fstp%FM %AM', + emit => 'fst%FP%FM %AM', mode => "mode_M", attr_type => "ia32_x87_attr_t", latency => 2, @@ -2365,16 +2355,7 @@ fild => { fist => { state => "exc_pinned", - emit => 'fist%FM %AM', - mode => "mode_M", - attr_type => "ia32_x87_attr_t", - latency => 2, - constructors => {}, -}, - -fistp => { - state => "exc_pinned", - emit => 'fistp%FM %AM', + emit => 'fist%FP%FM %AM', mode => "mode_M", attr_type => "ia32_x87_attr_t", latency => 2, diff --git a/ir/be/ia32/ia32_x87.c b/ir/be/ia32/ia32_x87.c index d45d57e0d..0f1828e21 100644 --- a/ir/be/ia32/ia32_x87.c +++ b/ir/be/ia32/ia32_x87.c @@ -980,14 +980,14 @@ static void collect_and_rewire_users(ir_node *store, ir_node *old_val, ir_node * * @param state the x87 state * @param n the node that should be simulated (and patched) * @param op the x87 store opcode - * @param op_p the x87 store and pop opcode */ -static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p) +static int sim_store(x87_state *state, ir_node *n, ir_op *op) { ir_node *const val = get_irn_n(n, n_ia32_vfst_val); arch_register_t const *const op2 = x87_get_irn_register(val); DB((dbg, LEVEL_1, ">>> %+F %s ->\n", n, arch_register_get_name(op2))); + bool do_pop = false; int insn = NO_NODE_ADDED; int const op2_reg_idx = arch_register_get_index(op2); int const op2_idx = x87_on_stack(state, op2_reg_idx); @@ -1006,12 +1006,12 @@ static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p) if (x87_get_depth(state) < N_ia32_st_REGS) { /* ok, we have a free register: push + fstp */ x87_create_fpush(state, n, op2_idx, REG_VFP_VFP_NOREG, val); - x87_pop(state); - x87_patch_insn(n, op_p); + x87_patch_insn(n, op); + do_pop = true; } else { /* stack full here: need fstp + load */ - x87_pop(state); - x87_patch_insn(n, op_p); + x87_patch_insn(n, op); + do_pop = true; ir_node *const block = get_nodes_block(n); ir_node *const mem = get_irn_Proj_for_mode(n, mode_M); @@ -1054,11 +1054,15 @@ static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p) if (op2_idx != 0) x87_create_fxch(state, n, op2_idx); - x87_pop(state); - x87_patch_insn(n, op_p); + x87_patch_insn(n, op); + do_pop = true; } + if (do_pop) + x87_pop(state); + ia32_x87_attr_t *const attr = get_ia32_x87_attr(n); + attr->pop = do_pop; attr->x87[1] = get_st_reg(0); DB((dbg, LEVEL_1, "<<< %s %s ->\n", get_irn_opname(n), arch_register_get_name(attr->x87[1]))); @@ -1082,7 +1086,7 @@ static int sim_##op(x87_state *state, ir_node *n) { \ #define GEN_STORE(op) \ static int sim_##op(x87_state *state, ir_node *n) { \ - return sim_store(state, n, op_ia32_##op, op_ia32_##op##p); \ + return sim_store(state, n, op_ia32_##op); \ } /* all stubs */ -- 2.20.1