diff options
author | Uros Bizjak <ubizjak@gmail.com> | 2017-10-17 18:35:11 +0200 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2017-10-17 18:35:11 +0200 |
commit | 7061821d4aa300b600f689cadb994d7658600414 (patch) | |
tree | a3619d841745f6bbd60f09336e5dcbfe8866245c /gcc/reg-stack.c | |
parent | 5a2018625a1192831f76b5bac3cb679a88947577 (diff) | |
download | gcc-7061821d4aa300b600f689cadb994d7658600414.zip gcc-7061821d4aa300b600f689cadb994d7658600414.tar.gz gcc-7061821d4aa300b600f689cadb994d7658600414.tar.bz2 |
reg-stack.c (compare_for_stack_reg): Add bool argument.
* reg-stack.c (compare_for_stack_reg): Add bool argument.
Detect FTST instruction and handle its register pops. Only pop
second operand if can_pop_second_op is true.
(subst_stack_regs_pat) <case COMPARE>: Detect FCOMI instruction to
set can_pop_second_op to false in the compare_for_stack_reg call.
* config/i386/i386.md (*cmpi<FPCMP:unord><MODEF:mode>): Only call
output_fp_compare for stack register operands.
* config/i386/i386.c (output_fp_compare): Do not output SSE compare
instructions here. Do not emit stack register pops here. Assert
that FCOMPP pops next to top stack register. Rewrite function.
From-SVN: r253821
Diffstat (limited to 'gcc/reg-stack.c')
-rw-r--r-- | gcc/reg-stack.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index f238106..86021ab 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -262,7 +262,7 @@ static bool move_for_stack_reg (rtx_insn *, stack_ptr, rtx); static bool move_nan_for_stack_reg (rtx_insn *, stack_ptr, rtx); static int swap_rtx_condition_1 (rtx); static int swap_rtx_condition (rtx_insn *); -static void compare_for_stack_reg (rtx_insn *, stack_ptr, rtx); +static void compare_for_stack_reg (rtx_insn *, stack_ptr, rtx, bool); static bool subst_stack_regs_pat (rtx_insn *, stack_ptr, rtx); static void subst_asm_stack_regs (rtx_insn *, stack_ptr); static bool subst_stack_regs (rtx_insn *, stack_ptr); @@ -1325,7 +1325,8 @@ swap_rtx_condition (rtx_insn *insn) set up. */ static void -compare_for_stack_reg (rtx_insn *insn, stack_ptr regstack, rtx pat_src) +compare_for_stack_reg (rtx_insn *insn, stack_ptr regstack, + rtx pat_src, bool can_pop_second_op) { rtx *src1, *src2; rtx src1_note, src2_note; @@ -1366,8 +1367,18 @@ compare_for_stack_reg (rtx_insn *insn, stack_ptr regstack, rtx pat_src) if (src1_note) { - pop_stack (regstack, REGNO (XEXP (src1_note, 0))); - replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG); + if (*src2 == CONST0_RTX (GET_MODE (*src2))) + { + /* This is `ftst' insn that can't pop register. */ + remove_regno_note (insn, REG_DEAD, REGNO (XEXP (src1_note, 0))); + emit_pop_insn (insn, regstack, XEXP (src1_note, 0), + EMIT_AFTER); + } + else + { + pop_stack (regstack, REGNO (XEXP (src1_note, 0))); + replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG); + } } /* If the second operand dies, handle that. But if the operands are @@ -1384,7 +1395,7 @@ compare_for_stack_reg (rtx_insn *insn, stack_ptr regstack, rtx pat_src) at top (FIRST_STACK_REG) now. */ if (get_hard_regnum (regstack, XEXP (src2_note, 0)) == FIRST_STACK_REG - && src1_note) + && src1_note && can_pop_second_op) { pop_stack (regstack, REGNO (XEXP (src2_note, 0))); replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG + 1); @@ -1550,7 +1561,9 @@ subst_stack_regs_pat (rtx_insn *insn, stack_ptr regstack, rtx pat) switch (GET_CODE (pat_src)) { case COMPARE: - compare_for_stack_reg (insn, regstack, pat_src); + /* `fcomi' insn can't pop two regs. */ + compare_for_stack_reg (insn, regstack, pat_src, + REGNO (*dest) != FLAGS_REG); break; case CALL: @@ -1970,7 +1983,7 @@ subst_stack_regs_pat (rtx_insn *insn, stack_ptr regstack, rtx pat) pat_src = XVECEXP (pat_src, 0, 0); gcc_assert (GET_CODE (pat_src) == COMPARE); - compare_for_stack_reg (insn, regstack, pat_src); + compare_for_stack_reg (insn, regstack, pat_src, true); break; default: |