aboutsummaryrefslogtreecommitdiff
path: root/gcc/reg-stack.c
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2017-10-17 18:35:11 +0200
committerUros Bizjak <uros@gcc.gnu.org>2017-10-17 18:35:11 +0200
commit7061821d4aa300b600f689cadb994d7658600414 (patch)
treea3619d841745f6bbd60f09336e5dcbfe8866245c /gcc/reg-stack.c
parent5a2018625a1192831f76b5bac3cb679a88947577 (diff)
downloadgcc-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.c27
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: