diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-04-04 10:13:26 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-04-04 10:13:26 +0000 |
commit | 14a72bf61fc0d6902a98429c8d05fe8dbaad1abd (patch) | |
tree | d148e0f0d7d04e9462b558abf79681cde24bc20a | |
parent | 13a6c2e21c3b8d551f092c485d6b2de2d19de135 (diff) | |
download | gcc-14a72bf61fc0d6902a98429c8d05fe8dbaad1abd.tar.gz |
* config/sparc/sparc.md (movdi_insn_sp64_novis): New pattern.
(movdi_insn_sp64_vis): Renamed from movdi_insn_sp64.
(movsf): Don't force any constant to memory if target is integer
hard register.
Move fp_zero_operand check below the const0_rtx check.
(movtf): Likewise. Also allow fp_zero_operand for stores into
memory.
(movdf): Likewise. Also allow fp_zero_operand for stores into
memory and into integer hard registers.
(clear_df, clear_dfp, movdf_const_intreg_sp32,
movdf_const_intreg_sp64): Remove.
(movdf_insn_sp32, movdf_no_e_insn_sp32): Redo constraints and
conditions.
(movdf_no_e_insn_v9_sp32): New pattern.
(movdf_insn_v9only): Remove.
(movdf_insn_v9only_novis, movdf_insn_v9only_vis): New patterns.
(movdf_insn_sp64): Remove.
(movdf_insn_sp64_novis, movdf_insn_sp64_vis): New patterns.
(movdf_no_e_insn_sp64): Allow storing 0.0 into memory.
(following splits): Rewrite conditions. Add two new splits
for storing 0.0 into memory and registers.
(clear_tf, clear_tf+1, clear_tfp, clear_tfp+1): Remove.
(movtf_insn_sp32): Redo constraints and conditions.
(movtf_insn_vis_sp32): New pattern.
(movtf_no_e_insn_sp32): Redo constraints and conditions.
(movtf_insn_hq_sp64): Likewise.
(movtf_insn_hq_vis_sp64): New pattern.
(movtf_insn_sp64): Redo constraints and conditions.
(movtf_insn_vis_sp64): New pattern.
(movtf_no_e_insn_sp64): Redo constraints and conditions.
(movtf_no_e_insn_sp64+1): New split for storing 0.0L into registers
or memory.
* config/sparc/sparc.c (sparc_override_options): Assume v9 if either
-mvis or -m64 to take down the number of various reload patterns.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@32901 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 35 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.c | 14 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.h | 2 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.md | 553 |
4 files changed, 395 insertions, 209 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7b1f3249c16..4bdff451c3a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -6,6 +6,41 @@ non-optimizing TARGET_ARCH32 in DF or DI modes because it is not offsetable. + * config/sparc/sparc.md (movdi_insn_sp64_novis): New pattern. + (movdi_insn_sp64_vis): Renamed from movdi_insn_sp64. + (movsf): Don't force any constant to memory if target is integer + hard register. + Move fp_zero_operand check below the const0_rtx check. + (movtf): Likewise. Also allow fp_zero_operand for stores into + memory. + (movdf): Likewise. Also allow fp_zero_operand for stores into + memory and into integer hard registers. + (clear_df, clear_dfp, movdf_const_intreg_sp32, + movdf_const_intreg_sp64): Remove. + (movdf_insn_sp32, movdf_no_e_insn_sp32): Redo constraints and + conditions. + (movdf_no_e_insn_v9_sp32): New pattern. + (movdf_insn_v9only): Remove. + (movdf_insn_v9only_novis, movdf_insn_v9only_vis): New patterns. + (movdf_insn_sp64): Remove. + (movdf_insn_sp64_novis, movdf_insn_sp64_vis): New patterns. + (movdf_no_e_insn_sp64): Allow storing 0.0 into memory. + (following splits): Rewrite conditions. Add two new splits + for storing 0.0 into memory and registers. + (clear_tf, clear_tf+1, clear_tfp, clear_tfp+1): Remove. + (movtf_insn_sp32): Redo constraints and conditions. + (movtf_insn_vis_sp32): New pattern. + (movtf_no_e_insn_sp32): Redo constraints and conditions. + (movtf_insn_hq_sp64): Likewise. + (movtf_insn_hq_vis_sp64): New pattern. + (movtf_insn_sp64): Redo constraints and conditions. + (movtf_insn_vis_sp64): New pattern. + (movtf_no_e_insn_sp64): Redo constraints and conditions. + (movtf_no_e_insn_sp64+1): New split for storing 0.0L into registers + or memory. + * config/sparc/sparc.c (sparc_override_options): Assume v9 if either + -mvis or -m64 to take down the number of various reload patterns. + Tue Apr 4 00:41:53 2000 Jeffrey A Law (law@cygnus.com) * pa/pa-64.h: New file. diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 2ee24c17e57..557079695ec 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -342,6 +342,16 @@ sparc_override_options () target_flags &= ~MASK_FPU_SET; } + /* Don't allow -mvis if FPU is disabled. */ + if (! TARGET_FPU) + target_flags &= ~MASK_VIS; + + /* -mvis assumes UltraSPARC+, so we are sure v9 instructions + are available. + -m64 also implies v9. */ + if (TARGET_VIS || TARGET_ARCH64) + target_flags |= MASK_V9; + /* Use the deprecated v8 insns for sparc64 in 32 bit mode. */ if (TARGET_V9 && TARGET_ARCH32) target_flags |= MASK_DEPRECATED_V8_INSNS; @@ -354,10 +364,6 @@ sparc_override_options () if (TARGET_ARCH32) target_flags &= ~MASK_STACK_BIAS; - /* Don't allow -mvis if FPU is disabled. */ - if (! TARGET_FPU) - target_flags &= ~MASK_VIS; - /* Supply a default value for align_functions. */ if (align_functions == 0 && sparc_cpu == PROCESSOR_ULTRASPARC) align_functions = 32; diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index b98a3801f73..477e45d5b37 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -2298,7 +2298,7 @@ LFLGRET"ID":\n\ #define REG_OK_FOR_BASE_P(X) \ (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32)) -/* 'T', 'U' are for aligned memory loads which aren't needed for v9. */ +/* 'T', 'U' are for aligned memory loads which aren't needed for arch64. */ #define EXTRA_CONSTRAINT(OP, C) \ (EXTRA_CONSTRAINT_BASE(OP, C) \ diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 3b62a5eff7d..f72f8a81b9d 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -2568,10 +2568,28 @@ [(set_attr "type" "move") (set_attr "length" "1")]) -(define_insn "*movdi_insn_sp64" +(define_insn "*movdi_insn_sp64_novis" + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m") + (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e"))] + "TARGET_ARCH64 && ! TARGET_VIS && + (register_operand (operands[0], DImode) + || reg_or_0_operand (operands[1], DImode))" + "@ + mov\\t%1, %0 + sethi\\t%%hi(%a1), %0 + clr\\t%0 + ldx\\t%1, %0 + stx\\t%r1, %0 + fmovd\\t%1, %0 + ldd\\t%1, %0 + std\\t%1, %0" + [(set_attr "type" "move,move,move,load,store,fpmove,fpload,fpstore") + (set_attr "length" "1")]) + +(define_insn "*movdi_insn_sp64_vis" [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m,b") (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e,J"))] - "TARGET_ARCH64 && + "TARGET_ARCH64 && TARGET_VIS && (register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode))" "@ @@ -3127,14 +3145,20 @@ if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1])) { - if (TARGET_VIS && fp_zero_operand (operands[1], SFmode)) - goto movsf_is_ok; - /* emit_group_store will send such bogosity to us when it is not storing directly into memory. So fix this up to avoid crashes in output_constant_pool. */ if (operands [1] == const0_rtx) operands[1] = CONST0_RTX (SFmode); + + if (TARGET_VIS && fp_zero_operand (operands[1], SFmode)) + goto movsf_is_ok; + + /* We are able to build any SF constant in integer registers + with at most 2 instructions. */ + if (REGNO (operands[0]) < 32) + goto movsf_is_ok; + operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]), operands[1])); } @@ -3174,101 +3198,6 @@ ; }") -(define_insn "*clear_df" - [(set (match_operand:DF 0 "register_operand" "=e") - (match_operand:DF 1 "fp_zero_operand" ""))] - "TARGET_VIS" - "fzero\\t%0" - [(set_attr "type" "fpmove") - (set_attr "length" "1")]) - -(define_insn "*clear_dfp" - [(set (match_operand:DF 0 "memory_operand" "=m") - (match_operand:DF 1 "fp_zero_operand" ""))] - "TARGET_V9" - "stx\\t%%g0, %0" - [(set_attr "type" "store") - (set_attr "length" "1")]) - -(define_insn "*movdf_const_intreg_sp32" - [(set (match_operand:DF 0 "register_operand" "=e,e,?r") - (match_operand:DF 1 "const_double_operand" "T#F,o#F,F"))] - "TARGET_FPU && ! TARGET_ARCH64" - "@ - ldd\\t%1, %0 - # - #" - [(set_attr "type" "move") - (set_attr "length" "1,2,2")]) - -;; Now that we redo life analysis with a clean slate after -;; instruction splitting for sched2 this can work. -(define_insn "*movdf_const_intreg_sp64" - [(set (match_operand:DF 0 "register_operand" "=e,?r") - (match_operand:DF 1 "const_double_operand" "m#F,F"))] - "TARGET_FPU && TARGET_ARCH64" - "@ - ldd\\t%1, %0 - #" - [(set_attr "type" "move") - (set_attr "length" "1,2")]) - -(define_split - [(set (match_operand:DF 0 "register_operand" "") - (match_operand:DF 1 "const_double_operand" ""))] - "TARGET_FPU - && (GET_CODE (operands[0]) == REG - && REGNO (operands[0]) < 32) - && reload_completed" - [(clobber (const_int 0))] - " -{ - REAL_VALUE_TYPE r; - long l[2]; - - REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); - REAL_VALUE_TO_TARGET_DOUBLE (r, l); - if (GET_CODE (operands[0]) == SUBREG) - operands[0] = alter_subreg (operands[0]); - operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0])); - - if (TARGET_ARCH64) - { -#if HOST_BITS_PER_WIDE_INT == 64 - HOST_WIDE_INT val; - - val = ((HOST_WIDE_INT)(unsigned long)l[1] | - ((HOST_WIDE_INT)(unsigned long)l[0] << 32)); - emit_insn (gen_movdi (operands[0], GEN_INT (val))); -#else - emit_insn (gen_movdi (operands[0], - gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx, - l[1], l[0]))); -#endif - } - else - { - emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), - GEN_INT (l[0]))); - - /* Slick... but this trick loses if this subreg constant part - can be done in one insn. */ - if (l[1] == l[0] - && !(SPARC_SETHI_P (l[0]) - || SPARC_SIMM13_P (l[0]))) - { - emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), - gen_highpart (SImode, operands[0]))); - } - else - { - emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), - GEN_INT (l[1]))); - } - } - DONE; -}") - (define_expand "movdf" [(set (match_operand:DF 0 "general_operand" "") (match_operand:DF 1 "general_operand" ""))] @@ -3279,14 +3208,16 @@ if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1])) { - if (TARGET_VIS && fp_zero_operand (operands[1], DFmode)) - goto movdf_is_ok; - /* emit_group_store will send such bogosity to us when it is not storing directly into memory. So fix this up to avoid crashes in output_constant_pool. */ if (operands [1] == const0_rtx) operands[1] = CONST0_RTX (DFmode); + + if ((TARGET_VIS || REGNO (operands[0]) < 32) + && fp_zero_operand (operands[1], DFmode)) + goto movdf_is_ok; + operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]), operands[1])); } @@ -3294,7 +3225,8 @@ /* Handle MEM cases first. */ if (GET_CODE (operands[0]) == MEM) { - if (register_operand (operands[1], DFmode)) + if (register_operand (operands[1], DFmode) + || fp_zero_operand (operands[1], DFmode)) goto movdf_is_ok; if (! reload_in_progress) @@ -3327,12 +3259,13 @@ ;; Be careful, fmovd does not exist when !v9. (define_insn "*movdf_insn_sp32" - [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,e,r,r,o,e,o") - (match_operand:DF 1 "input_operand" "T,e,T,U,e,r,o,r,o,e"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o") + (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))] "TARGET_FPU && ! TARGET_V9 && (register_operand (operands[0], DFmode) - || register_operand (operands[1], DFmode))" + || register_operand (operands[1], DFmode) + || fp_zero_operand (operands[1], DFmode))" "@ ldd\\t%1, %0 std\\t%1, %0 @@ -3348,12 +3281,14 @@ (set_attr "length" "1,1,1,1,2,2,2,2,2,2")]) (define_insn "*movdf_no_e_insn_sp32" - [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,r,r,o") - (match_operand:DF 1 "input_operand" "T,U,r,o,r"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o") + (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))] "! TARGET_FPU + && ! TARGET_V9 && ! TARGET_ARCH64 && (register_operand (operands[0], DFmode) - || register_operand (operands[1], DFmode))" + || register_operand (operands[1], DFmode) + || fp_zero_operand (operands[1], DFmode))" "@ ldd\\t%1, %0 std\\t%1, %0 @@ -3363,62 +3298,191 @@ [(set_attr "type" "load,store,*,*,*") (set_attr "length" "1,1,2,2,2")]) +(define_insn "*movdf_no_e_insn_v9_sp32" + [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o") + (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))] + "! TARGET_FPU + && TARGET_V9 + && ! TARGET_ARCH64 + && (register_operand (operands[0], DFmode) + || register_operand (operands[1], DFmode) + || fp_zero_operand (operands[1], DFmode))" + "@ + ldd\\t%1, %0 + std\\t%1, %0 + stx\\t%r1, %0 + # + #" + [(set_attr "type" "load,store,store,*,*") + (set_attr "length" "1,1,1,2,2")]) + ;; We have available v9 double floats but not 64-bit -;; integer registers. -(define_insn "*movdf_insn_v9only" - [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,U,T,r,r,o") - (match_operand:DF 1 "input_operand" "e,m,e,T,U,r,o,r"))] +;; integer registers and no VIS. +(define_insn "*movdf_insn_v9only_novis" + [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o") + (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))] "TARGET_FPU && TARGET_V9 + && ! TARGET_VIS + && ! TARGET_ARCH64 + && (register_operand (operands[0], DFmode) + || register_operand (operands[1], DFmode) + || fp_zero_operand (operands[1], DFmode))" + "@ + fmovd\\t%1, %0 + ldd\\t%1, %0 + stx\\t%r1, %0 + std\\t%1, %0 + ldd\\t%1, %0 + std\\t%1, %0 + # + # + #" + [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*") + (set_attr "length" "1,1,1,1,1,1,2,2,2")]) + +;; We have available v9 double floats but not 64-bit +;; integer registers but we have VIS. +(define_insn "*movdf_insn_v9only_vis" + [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o") + (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))] + "TARGET_FPU + && TARGET_VIS && ! TARGET_ARCH64 && (register_operand (operands[0], DFmode) - || register_operand (operands[1], DFmode))" + || register_operand (operands[1], DFmode) + || fp_zero_operand (operands[1], DFmode))" "@ + fzero\\t%1, %0 fmovd\\t%1, %0 ldd\\t%1, %0 + stx\\t%r1, %0 std\\t%1, %0 ldd\\t%1, %0 std\\t%1, %0 # # #" - [(set_attr "type" "fpmove,load,store,load,store,*,*,*") - (set_attr "length" "1,1,1,1,1,2,2,2")]) + [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*") + (set_attr "length" "1,1,1,1,1,1,1,2,2,2")]) ;; We have available both v9 double floats and 64-bit -;; integer registers. -(define_insn "*movdf_insn_sp64" - [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,r,r,m") - (match_operand:DF 1 "input_operand" "e,m,e,r,m,r"))] +;; integer registers. No VIS though. +(define_insn "*movdf_insn_sp64_novis" + [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r") + (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))] "TARGET_FPU - && TARGET_V9 + && ! TARGET_VIS && TARGET_ARCH64 && (register_operand (operands[0], DFmode) - || register_operand (operands[1], DFmode))" + || register_operand (operands[1], DFmode) + || fp_zero_operand (operands[1], DFmode))" "@ fmovd\\t%1, %0 ldd\\t%1, %0 std\\t%1, %0 - mov\\t%1, %0 + mov\\t%r1, %0 ldx\\t%1, %0 - stx\\t%1, %0" - [(set_attr "type" "fpmove,load,store,move,load,store") - (set_attr "length" "1")]) + stx\\t%r1, %0 + #" + [(set_attr "type" "fpmove,load,store,move,load,store,*") + (set_attr "length" "1,1,1,1,1,1,2")]) + +;; We have available both v9 double floats and 64-bit +;; integer registers. And we have VIS. +(define_insn "*movdf_insn_sp64_vis" + [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r") + (match_operand:DF 1 "input_operand" "G,e,m#F,e,*rG,m,*rG,F"))] + "TARGET_FPU + && TARGET_VIS + && TARGET_ARCH64 + && (register_operand (operands[0], DFmode) + || register_operand (operands[1], DFmode) + || fp_zero_operand (operands[1], DFmode))" + "@ + fzero\\t%0 + fmovd\\t%1, %0 + ldd\\t%1, %0 + std\\t%1, %0 + mov\\t%r1, %0 + ldx\\t%1, %0 + stx\\t%r1, %0 + #" + [(set_attr "type" "fpmove,fpmove,load,store,move,load,store,*") + (set_attr "length" "1,1,1,1,1,1,1,2")]) (define_insn "*movdf_no_e_insn_sp64" [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m") - (match_operand:DF 1 "input_operand" "r,m,r"))] + (match_operand:DF 1 "input_operand" "r,m,rG"))] "! TARGET_FPU && TARGET_ARCH64 && (register_operand (operands[0], DFmode) - || register_operand (operands[1], DFmode))" + || register_operand (operands[1], DFmode) + || fp_zero_operand (operands[1], DFmode))" "@ mov\\t%1, %0 ldx\\t%1, %0 - stx\\t%1, %0" + stx\\t%r1, %0" [(set_attr "type" "move,load,store") (set_attr "length" "1")]) +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (match_operand:DF 1 "const_double_operand" ""))] + "TARGET_FPU + && (GET_CODE (operands[0]) == REG + && REGNO (operands[0]) < 32) + && ! fp_zero_operand(operands[1], DFmode) + && reload_completed" + [(clobber (const_int 0))] + " +{ + REAL_VALUE_TYPE r; + long l[2]; + + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); + REAL_VALUE_TO_TARGET_DOUBLE (r, l); + if (GET_CODE (operands[0]) == SUBREG) + operands[0] = alter_subreg (operands[0]); + operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0])); + + if (TARGET_ARCH64) + { +#if HOST_BITS_PER_WIDE_INT == 64 + HOST_WIDE_INT val; + + val = ((HOST_WIDE_INT)(unsigned long)l[1] | + ((HOST_WIDE_INT)(unsigned long)l[0] << 32)); + emit_insn (gen_movdi (operands[0], GEN_INT (val))); +#else + emit_insn (gen_movdi (operands[0], + gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx, + l[1], l[0]))); +#endif + } + else + { + emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), + GEN_INT (l[0]))); + + /* Slick... but this trick loses if this subreg constant part + can be done in one insn. */ + if (l[1] == l[0] + && !(SPARC_SETHI_P (l[0]) + || SPARC_SIMM13_P (l[0]))) + { + emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), + gen_highpart (SImode, operands[0]))); + } + else + { + emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), + GEN_INT (l[1]))); + } + } + DONE; +}") + ;; Ok, now the splits to handle all the multi insn and ;; mis-aligned memory address cases. ;; In these splits please take note that we must be @@ -3471,17 +3535,11 @@ (define_split [(set (match_operand:DF 0 "register_operand" "") (match_operand:DF 1 "memory_operand" ""))] - "((! TARGET_V9 - || (! TARGET_ARCH64 - && ((GET_CODE (operands[0]) == REG - && REGNO (operands[0]) < 32) - || (GET_CODE (operands[0]) == SUBREG - && GET_CODE (SUBREG_REG (operands[0])) == REG - && REGNO (SUBREG_REG (operands[0])) < 32)))) - && (reload_completed - && (((REGNO (operands[0])) % 2) != 0 - || ! mem_min_alignment (operands[1], 8)) - && offsettable_memref_p (operands[1])))" + "reload_completed + && ! TARGET_ARCH64 + && (((REGNO (operands[0]) % 2) != 0) + || ! mem_min_alignment (operands[1], 8)) + && offsettable_memref_p (operands[1])" [(clobber (const_int 0))] " { @@ -3512,17 +3570,11 @@ (define_split [(set (match_operand:DF 0 "memory_operand" "") (match_operand:DF 1 "register_operand" ""))] - "((! TARGET_V9 - || (! TARGET_ARCH64 - && ((GET_CODE (operands[1]) == REG - && REGNO (operands[1]) < 32) - || (GET_CODE (operands[1]) == SUBREG - && GET_CODE (SUBREG_REG (operands[1])) == REG - && REGNO (SUBREG_REG (operands[1])) < 32)))) - && (reload_completed - && (((REGNO (operands[1])) % 2) != 0 - || ! mem_min_alignment (operands[0], 8)) - && offsettable_memref_p (operands[0])))" + "reload_completed + && ! TARGET_ARCH64 + && (((REGNO (operands[1]) % 2) != 0) + || ! mem_min_alignment (operands[0], 8)) + && offsettable_memref_p (operands[0])" [(clobber (const_int 0))] " { @@ -3539,45 +3591,51 @@ DONE; }") -(define_insn "*clear_tf" - [(set (match_operand:TF 0 "register_operand" "=e") - (match_operand:TF 1 "fp_zero_operand" ""))] - "TARGET_VIS" - "#" - [(set_attr "type" "fpmove") - (set_attr "length" "2")]) - (define_split - [(set (match_operand:TF 0 "register_operand" "") - (match_operand:TF 1 "fp_zero_operand" ""))] - "TARGET_VIS && reload_completed" - [(set (subreg:DF (match_dup 0) 0) (match_dup 1)) - (set (subreg:DF (match_dup 0) 8) (match_dup 1))] + [(set (match_operand:DF 0 "memory_operand" "") + (match_operand:DF 1 "fp_zero_operand" ""))] + "reload_completed + && (! TARGET_V9 + || (! TARGET_ARCH64 + && ! mem_min_alignment (operands[0], 8))) + && offsettable_memref_p (operands[0])" + [(clobber (const_int 0))] " { - operands[1] = CONST0_RTX (DFmode); -} -") + rtx dest1, dest2; -(define_insn "*clear_tfp" - [(set (match_operand:TF 0 "memory_operand" "=m") - (match_operand:TF 1 "fp_zero_operand" ""))] - "TARGET_V9" - "#" - [(set_attr "type" "fpmove") - (set_attr "length" "2")]) + dest1 = change_address (operands[0], SFmode, NULL_RTX); + dest2 = change_address (operands[0], SFmode, + plus_constant_for_output (XEXP (dest1, 0), 4)); + emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode))); + emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode))); + DONE; +}") (define_split - [(set (match_operand:TF 0 "memory_operand" "=m") - (match_operand:TF 1 "fp_zero_operand" ""))] - "TARGET_V9 && reload_completed" - [(set (subreg:DF (match_dup 0) 0) (match_dup 1)) - (set (subreg:DF (match_dup 0) 8) (match_dup 1))] + [(set (match_operand:DF 0 "register_operand" "") + (match_operand:DF 1 "fp_zero_operand" ""))] + "reload_completed + && ! TARGET_ARCH64 + && ((GET_CODE (operands[0]) == REG + && REGNO (operands[0]) < 32) + || (GET_CODE (operands[0]) == SUBREG + && GET_CODE (SUBREG_REG (operands[0])) == REG + && REGNO (SUBREG_REG (operands[0])) < 32))" + [(clobber (const_int 0))] " { - operands[1] = CONST0_RTX (DFmode); -} -") + rtx set_dest = operands[0]; + rtx dest1, dest2; + + if (GET_CODE (set_dest) == SUBREG) + set_dest = alter_subreg (set_dest); + dest1 = gen_highpart (SFmode, set_dest); + dest2 = gen_lowpart (SFmode, set_dest); + emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode))); + emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode))); + DONE; +}") (define_expand "movtf" [(set (match_operand:TF 0 "general_operand" "") @@ -3589,14 +3647,15 @@ if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1])) { - if (TARGET_VIS && fp_zero_operand (operands[1], TFmode)) - goto movtf_is_ok; - /* emit_group_store will send such bogosity to us when it is not storing directly into memory. So fix this up to avoid crashes in output_constant_pool. */ if (operands [1] == const0_rtx) operands[1] = CONST0_RTX (TFmode); + + if (TARGET_VIS && fp_zero_operand (operands[1], TFmode)) + goto movtf_is_ok; + operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]), operands[1])); } @@ -3605,8 +3664,9 @@ full 16-byte alignment for quads. */ if (GET_CODE (operands[0]) == MEM) { - if (register_operand (operands[1], TFmode)) - goto movtf_is_ok; + if (register_operand (operands[1], TFmode) + || fp_zero_operand (operands[1], TFmode)) + goto movtf_is_ok; if (! reload_in_progress) { @@ -3639,12 +3699,26 @@ ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so ;; we must split them all. :-( (define_insn "*movtf_insn_sp32" - [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,o,e,r,r,o") - (match_operand:TF 1 "input_operand" "o,e,o,U,e,r,o,r"))] + [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,o,r,o") + (match_operand:TF 1 "input_operand" "oe,Ge,o,U,ro,r"))] "TARGET_FPU + && ! TARGET_VIS && ! TARGET_ARCH64 && (register_operand (operands[0], TFmode) - || register_operand (operands[1], TFmode))" + || register_operand (operands[1], TFmode) + || fp_zero_operand (operands[1], TFmode))" + "#" + [(set_attr "length" "4")]) + +(define_insn "*movtf_insn_vis_sp32" + [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,o,r,o") + (match_operand:TF 1 "input_operand" "Goe,Ge,o,U,ro,r"))] + "TARGET_FPU + && TARGET_VIS + && ! TARGET_ARCH64 + && (register_operand (operands[0], TFmode) + || register_operand (operands[1], TFmode) + || fp_zero_operand (operands[1], TFmode))" "#" [(set_attr "length" "4")]) @@ -3653,26 +3727,48 @@ ;; when -mno-fpu. (define_insn "*movtf_no_e_insn_sp32" - [(set (match_operand:TF 0 "nonimmediate_operand" "=U,o,r,r,o") - (match_operand:TF 1 "input_operand" "o,U,r,o,r"))] + [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o") + (match_operand:TF 1 "input_operand" "G,o,U,ro,r"))] "! TARGET_FPU && ! TARGET_ARCH64 && (register_operand (operands[0], TFmode) - || register_operand (operands[1], TFmode))" + || register_operand (operands[1], TFmode) + || fp_zero_operand (operands[1], TFmode))" "#" [(set_attr "length" "4")]) ;; Now handle the float reg cases directly when arch64, ;; hard_quad, and proper reg number alignment are all true. (define_insn "*movtf_insn_hq_sp64" - [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,r,r,o") - (match_operand:TF 1 "input_operand" "e,m,e,r,o,r"))] + [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r,o") + (match_operand:TF 1 "input_operand" "e,m,e,G,ro,r"))] "TARGET_FPU + && ! TARGET_VIS && TARGET_ARCH64 - && TARGET_V9 && TARGET_HARD_QUAD && (register_operand (operands[0], TFmode) - || register_operand (operands[1], TFmode))" + || register_operand (operands[1], TFmode) + || fp_zero_operand (operands[1], TFmode))" + "@ + fmovq\\t%1, %0 + ldq\\t%1, %0 + stq\\t%1, %0 + # + # + #" + [(set_attr "type" "fpmove,fpload,fpstore,*,*,*") + (set_attr "length" "1,1,1,2,2,2")]) + +(define_insn "*movtf_insn_hq_vis_sp64" + [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o") + (match_operand:TF 1 "input_operand" "e,m,e,G,ro,r"))] + "TARGET_FPU + && TARGET_VIS + && TARGET_ARCH64 + && TARGET_HARD_QUAD + && (register_operand (operands[0], TFmode) + || register_operand (operands[1], TFmode) + || fp_zero_operand (operands[1], TFmode))" "@ fmovq\\t%1, %0 ldq\\t%1, %0 @@ -3686,23 +3782,39 @@ ;; Now we allow the integer register cases even when ;; only arch64 is true. (define_insn "*movtf_insn_sp64" - [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r,o,e,r") - (match_operand:TF 1 "input_operand" "o,e,o,r,e,r"))] + [(set (match_operand:TF 0 "nonimmediate_operand" "=o,e,r") + (match_operand:TF 1 "input_operand" "Ge,oe,or"))] + "TARGET_FPU + && ! TARGET_VIS + && TARGET_ARCH64 + && ! TARGET_HARD_QUAD + && (register_operand (operands[0], TFmode) + || register_operand (operands[1], TFmode) + || fp_zero_operand (operands[1], TFmode))" + "#" + [(set_attr "length" "2")]) + +(define_insn "*movtf_insn_vis_sp64" + [(set (match_operand:TF 0 "nonimmediate_operand" "=eo,e,r") + (match_operand:TF 1 "input_operand" "Ge,o,or"))] "TARGET_FPU + && TARGET_VIS && TARGET_ARCH64 && ! TARGET_HARD_QUAD && (register_operand (operands[0], TFmode) - || register_operand (operands[1], TFmode))" + || register_operand (operands[1], TFmode) + || fp_zero_operand (operands[1], TFmode))" "#" [(set_attr "length" "2")]) (define_insn "*movtf_no_e_insn_sp64" - [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,r") - (match_operand:TF 1 "input_operand" "o,r,r"))] + [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o") + (match_operand:TF 1 "input_operand" "or,rG"))] "! TARGET_FPU && TARGET_ARCH64 && (register_operand (operands[0], TFmode) - || register_operand (operands[1], TFmode))" + || register_operand (operands[1], TFmode) + || fp_zero_operand (operands[1], TFmode))" "#" [(set_attr "length" "2")]) @@ -3748,6 +3860,39 @@ }") (define_split + [(set (match_operand:TF 0 "nonimmediate_operand" "") + (match_operand:TF 1 "fp_zero_operand" ""))] + "reload_completed" + [(clobber (const_int 0))] + " +{ + rtx set_dest = operands[0]; + rtx dest1, dest2; + + switch (GET_CODE (set_dest)) + { + case SUBREG: + set_dest = alter_subreg (set_dest); + /* FALLTHROUGH */ + case REG: + dest1 = gen_df_reg (set_dest, 0); + dest2 = gen_df_reg (set_dest, 1); + break; + case MEM: + dest1 = change_address (set_dest, DFmode, NULL_RTX); + dest2 = change_address (set_dest, DFmode, + plus_constant_for_output (XEXP (dest1, 0), 8)); + break; + default: + abort (); + } + + emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode))); + emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode))); + DONE; +}") + +(define_split [(set (match_operand:TF 0 "register_operand" "") (match_operand:TF 1 "memory_operand" ""))] "(reload_completed |