From patchwork Sat Sep 4 09:49:58 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [i386] : Tighten constraints of FPmode splitters a bit. X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 63764 Message-Id: To: gcc-patches@gcc.gnu.org Date: Sat, 4 Sep 2010 11:49:58 +0200 From: Uros Bizjak List-Id: Hello! XFmode can be moved directly from stack regs only and TFmode can be moved directly from SSE regs only. 2010-09-04 Uros Bizjak * config/i386/predicates.md (sse_reg_operand): New predicate. * config/i386/i386.md (TFmode push splitter): Use sse_reg_operand predicate for operand 1. (XFmode push splitter): Use fp_register_operand predicate for operand 1. (*dummy_extendsfdf2, *dummy_extendsfxf2): Remove disabled patterns. (SF-DF float_extend push splitter): Add reload_completed insn predicate. ({SF,DF}-XF float_extend_push splitter): Macroize splitter using MODEF mode macro. Add reload_completed insn predicate. Tested on x86_64-pc-linux-gnu {,-m32}, committed to mainline SVN. Uros. Index: i386.md =================================================================== --- i386.md (revision 163806) +++ i386.md (working copy) @@ -1685,7 +1685,7 @@ ;; "push a byte/word". But actually we use pushl, which has the effect ;; of rounding the amount pushed up to a word. -;; For 64BIT abi we always round up to 8 bytes. +;; For TARGET_64BIT we always round up to 8 bytes. (define_insn "*push2_rex64" [(set (match_operand:SWI124 0 "push_operand" "=X") (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r"))] @@ -2588,19 +2588,19 @@ (define_split [(set (match_operand:TF 0 "push_operand" "") + (match_operand:TF 1 "sse_reg_operand" ""))] + "TARGET_SSE2 && reload_completed" + [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16))) + (set (mem:TF (reg:P SP_REG)) (match_dup 1))]) + +(define_split + [(set (match_operand:TF 0 "push_operand" "") (match_operand:TF 1 "general_operand" ""))] "TARGET_SSE2 && reload_completed && !SSE_REG_P (operands[1])" [(const_int 0)] "ix86_split_long_move (operands); DONE;") -(define_split - [(set (match_operand:TF 0 "push_operand" "") - (match_operand:TF 1 "any_fp_register_operand" ""))] - "TARGET_SSE2" - [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16))) - (set (mem:TF (reg:P SP_REG)) (match_dup 1))]) - (define_insn "*pushxf" [(set (match_operand:XF 0 "push_operand" "=<,<") (match_operand:XF 1 "general_no_elim_operand" "f,ro"))] @@ -2633,7 +2633,7 @@ (define_split [(set (match_operand:XF 0 "push_operand" "") - (match_operand:XF 1 "any_fp_register_operand" ""))] + (match_operand:XF 1 "fp_register_operand" ""))] "reload_completed" [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) (set (mem:XF (reg:P SP_REG)) (match_dup 1))] @@ -2643,7 +2643,7 @@ [(set (match_operand:XF 0 "push_operand" "") (match_operand:XF 1 "general_operand" ""))] "reload_completed - && !ANY_FP_REG_P (operands[1])" + && !FP_REG_P (operands[1])" [(const_int 0)] "ix86_split_long_move (operands); DONE;") @@ -3970,45 +3970,25 @@ ;; Conversions between float and double. -;; These are all no-ops in the model used for the 80387. So just -;; emit moves. +;; These are all no-ops in the model used for the 80387. +;; So just emit moves. ;; %%% Kill these when call knows how to work out a DFmode push earlier. -(define_insn "*dummy_extendsfdf2" - [(set (match_operand:DF 0 "push_operand" "=<") - (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))] - "0" - "#") - (define_split [(set (match_operand:DF 0 "push_operand" "") (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))] - "" + "reload_completed" [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8))) (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))]) -(define_insn "*dummy_extendsfxf2" - [(set (match_operand:XF 0 "push_operand" "=<") - (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))] - "0" - "#") - (define_split [(set (match_operand:XF 0 "push_operand" "") - (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))] - "" + (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))] + "reload_completed" [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))] "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));") -(define_split - [(set (match_operand:XF 0 "push_operand" "") - (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))] - "" - [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) - (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))] - "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));") - (define_expand "extendsfdf2" [(set (match_operand:DF 0 "nonimmediate_operand" "") (float_extend:DF (match_operand:SF 1 "general_operand" "")))] Index: predicates.md =================================================================== --- predicates.md (revision 163797) +++ predicates.md (working copy) @@ -43,6 +43,11 @@ (and (match_code "reg") (match_test "MMX_REGNO_P (REGNO (op))"))) +;; True if the operand is an SSE register. +(define_predicate "sse_reg_operand" + (and (match_code "reg") + (match_test "SSE_REGNO_P (REGNO (op))"))) + ;; True if the operand is a Q_REGS class register. (define_predicate "q_regs_operand" (match_operand 0 "register_operand")