diff options
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 5 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 2 | ||||
-rw-r--r-- | gcc/reg-stack.c | 33 |
4 files changed, 44 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 86a06dd..155b0da 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +Wed Apr 11 14:06:10 CEST 2001 Jan Hubicka <jh@suse.cz> + + * i386.md (floatsisf_sse): Fix output template + * i386.c (ix86_expand_fp_movcc) + + * reg-stack.c (emit_pop_insn): Handle complex modes. + (move_for_stack_reg): Emit proper move mode. + (subst_stack_regs_pat): Handle complex modes. + 2001-04-11 Jakub Jelinek <jakub@redhat.com> * cpplex.c (_cpp_lex_token): Only warn if -Wcomment. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index a108a97..e6e76fe 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -6664,8 +6664,9 @@ ix86_expand_fp_movcc (operands) /* Similary try to manage result to be first operand of conditional move. We also don't support the NE comparison on SSE, so try to avoid it. */ - if (rtx_equal_p (operands[0], operands[3]) - || GET_CODE (operands[1]) == NE) + if ((rtx_equal_p (operands[0], operands[3]) + && (!TARGET_IEEE_FP || GET_CODE (operands[1]) != EQ)) + || (GET_CODE (operands[1]) == NE && TARGET_IEEE_FP)) { rtx tmp = operands[2]; operands[2] = operands[3]; diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 9b8a704..d3990ca 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -5117,7 +5117,7 @@ [(set (match_operand:DF 0 "register_operand" "=Y") (float:DF (match_operand:DI 1 "nonimmediate_operand" "mr")))] "TARGET_SSE2" - "cvtsi2sd\\t{%1, %0|%0, %1}" + "cvtsi2sd{q}\\t{%1, %0|%0, %1}" [(set_attr "type" "sse") (set_attr "mode" "DF") (set_attr "fp_int_src" "true")]) diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index 6c204467..e31338a 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -906,6 +906,23 @@ emit_pop_insn (insn, regstack, reg, where) rtx pop_insn, pop_rtx; int hard_regno; + /* For complex types take care to pop both halves. These may survive in + CLOBBER and USE expressions. */ + if (COMPLEX_MODE_P (GET_MODE (reg))) + { + rtx reg1 = FP_MODE_REG (REGNO (reg), DFmode); + rtx reg2 = FP_MODE_REG (REGNO (reg) + 1, DFmode); + + pop_insn = NULL_RTX; + if (get_hard_regnum (regstack, reg1) >= 0) + pop_insn = emit_pop_insn (insn, regstack, reg1, where); + if (get_hard_regnum (regstack, reg2) >= 0) + pop_insn = emit_pop_insn (insn, regstack, reg2, where); + if (!pop_insn) + abort (); + return pop_insn; + } + hard_regno = get_hard_regnum (regstack, reg); if (hard_regno < FIRST_STACK_REG) @@ -1129,9 +1146,12 @@ move_for_stack_reg (insn, regstack, pat) stack is not full, and then write the value to memory via a pop. */ rtx push_rtx, push_insn; - rtx top_stack_reg = FP_MODE_REG (FIRST_STACK_REG, XFmode); + rtx top_stack_reg = FP_MODE_REG (FIRST_STACK_REG, GET_MODE (src)); - push_rtx = gen_movxf (top_stack_reg, top_stack_reg); + if (GET_MODE (src) == TFmode) + push_rtx = gen_movtf (top_stack_reg, top_stack_reg); + else + push_rtx = gen_movxf (top_stack_reg, top_stack_reg); push_insn = emit_insn_before (push_rtx, insn); REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_DEAD, top_stack_reg, REG_NOTES (insn)); @@ -1447,6 +1467,15 @@ subst_stack_regs_pat (insn, regstack, pat) PATTERN (insn) = pat; move_for_stack_reg (insn, regstack, pat); } + if (! note && COMPLEX_MODE_P (GET_MODE (*dest)) + && get_hard_regnum (regstack, FP_MODE_REG (REGNO (*dest), DFmode)) == -1) + { + pat = gen_rtx_SET (VOIDmode, + FP_MODE_REG (REGNO (*dest) + 1, SFmode), + nan); + PATTERN (insn) = pat; + move_for_stack_reg (insn, regstack, pat); + } } } break; |