aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/sparc/sparc.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/sparc/sparc.md')
-rw-r--r--gcc/config/sparc/sparc.md570
1 files changed, 360 insertions, 210 deletions
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 3b62a5eff7d..9b91c3090a3 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -1187,7 +1187,8 @@
[(set (match_operand:DI 0 "register_operand" "")
(ne:DI (match_operand:DI 1 "register_operand" "")
(const_int 0)))]
- "TARGET_ARCH64"
+ "TARGET_ARCH64
+ && ! reg_overlap_mentioned_p (operands[1], operands[0])"
[(set (match_dup 0) (const_int 0))
(set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
(const_int 0))
@@ -1208,7 +1209,8 @@
[(set (match_operand:DI 0 "register_operand" "")
(neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
(const_int 0))))]
- "TARGET_ARCH64"
+ "TARGET_ARCH64
+ && ! reg_overlap_mentioned_p (operands[1], operands[0])"
[(set (match_dup 0) (const_int 0))
(set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
(const_int 0))
@@ -1229,7 +1231,8 @@
[(set (match_operand:SI 0 "register_operand" "")
(ne:SI (match_operand:DI 1 "register_operand" "")
(const_int 0)))]
- "TARGET_ARCH64"
+ "TARGET_ARCH64
+ && ! reg_overlap_mentioned_p (operands[1], operands[0])"
[(set (match_dup 0) (const_int 0))
(set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
(const_int 0))
@@ -1314,7 +1317,8 @@
[(set (match_operand:DI 0 "register_operand" "")
(eq:DI (match_operand:DI 1 "register_operand" "")
(const_int 0)))]
- "TARGET_ARCH64"
+ "TARGET_ARCH64
+ && ! reg_overlap_mentioned_p (operands[1], operands[0])"
[(set (match_dup 0) (const_int 0))
(set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
(const_int 0))
@@ -1335,7 +1339,8 @@
[(set (match_operand:DI 0 "register_operand" "")
(neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
(const_int 0))))]
- "TARGET_ARCH64"
+ "TARGET_ARCH64
+ && ! reg_overlap_mentioned_p (operands[1], operands[0])"
[(set (match_dup 0) (const_int 0))
(set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
(const_int 0))
@@ -1356,7 +1361,8 @@
[(set (match_operand:SI 0 "register_operand" "")
(eq:SI (match_operand:DI 1 "register_operand" "")
(const_int 0)))]
- "TARGET_ARCH64"
+ "TARGET_ARCH64
+ && ! reg_overlap_mentioned_p (operands[1], operands[0])"
[(set (match_dup 0) (const_int 0))
(set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
(const_int 0))
@@ -2568,10 +2574,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 +3151,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 +3204,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 +3214,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 +3231,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 +3265,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 +3287,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 +3304,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))"
+ || 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,load,store,*,*,*")
- (set_attr "length" "1,1,1,1,1,2,2,2")])
+ [(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)
+ || 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,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 +3541,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 +3576,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 +3597,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 +3653,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 +3670,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 +3705,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,r")
+ (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
+ "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")])
+
+(define_insn "*movtf_insn_vis_sp32"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
+ (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
"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")])
@@ -3653,26 +3733,47 @@
;; 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,roG,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")
+ (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
"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")])
+
+(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,roG,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 +3787,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" "=e,o,r")
+ (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
"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_insn_vis_sp64"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
+ (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
+ "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_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" "orG,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 +3865,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