Commit 66e62b49 by Kazu Hirata Committed by Kazu Hirata

re PR target/35574 (unrecognizable insn generated for vector move)

	PR target/35574
	* config/sparc/constraints.md (D): New.
	* config/sparc/predicates.md (const_double_or_vector_operand):
	New.
	* config/sparc/sparc.c (sparc_extra_constraint_check): Handle the
	'D' constraint.
	* config/sparc/sparc.md (*movdf_insn_sp32_v9, *movdf_insn_sp64):
	Use the 'D' constraint in addition to 'F' in some alternatives.
	(DF splitter): Generalize for V64mode.
	* doc/md.texi (SPARC): Document the 'D' constraint.

From-SVN: r141644
parent 1ddb9ec9
2008-11-06 Kazu Hirata <kazu@codesourcery.com>
PR target/35574
* config/sparc/constraints.md (D): New.
* config/sparc/predicates.md (const_double_or_vector_operand):
New.
* config/sparc/sparc.c (sparc_extra_constraint_check): Handle the
'D' constraint.
* config/sparc/sparc.md (*movdf_insn_sp32_v9, *movdf_insn_sp64):
Use the 'D' constraint in addition to 'F' in some alternatives.
(DF splitter): Generalize for V64mode.
* doc/md.texi (SPARC): Document the 'D' constraint.
2008-11-06 Uros Bizjak <ubizjak@gmail.com> 2008-11-06 Uros Bizjak <ubizjak@gmail.com>
* reg-stack.c (reg_to_stack): Generate +QNaN using real_nan. * reg-stack.c (reg_to_stack): Generate +QNaN using real_nan.
......
...@@ -100,6 +100,11 @@ ...@@ -100,6 +100,11 @@
;; Our memory extra constraints have to emulate the behavior of 'm' and 'o', ;; Our memory extra constraints have to emulate the behavior of 'm' and 'o',
;; i.e. accept pseudo-registers during reload. ;; i.e. accept pseudo-registers during reload.
(define_constraint "D"
"const_vector"
(and (match_code "const_vector")
(match_test "GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_INT")))
(define_constraint "Q" (define_constraint "Q"
"Floating-point constant that can be loaded with a sethi instruction" "Floating-point constant that can be loaded with a sethi instruction"
(and (match_code "const_double") (and (match_code "const_double")
......
...@@ -83,6 +83,10 @@ ...@@ -83,6 +83,10 @@
return fp_high_losum_p (op); return fp_high_losum_p (op);
}) })
;; Return true if OP is a const_double or const_vector.
(define_predicate "const_double_or_vector_operand"
(match_code "const_double,const_vector"))
;; Predicates for symbolic constants. ;; Predicates for symbolic constants.
......
...@@ -2571,7 +2571,7 @@ ...@@ -2571,7 +2571,7 @@
;; We have available v9 double floats but not 64-bit integer registers. ;; We have available v9 double floats but not 64-bit integer registers.
(define_insn "*movdf_insn_sp32_v9" (define_insn "*movdf_insn_sp32_v9"
[(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o") [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
(match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))] (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
"TARGET_FPU "TARGET_FPU
&& TARGET_V9 && TARGET_V9
&& ! TARGET_ARCH64 && ! TARGET_ARCH64
...@@ -2612,7 +2612,7 @@ ...@@ -2612,7 +2612,7 @@
;; We have available both v9 double floats and 64-bit integer registers. ;; We have available both v9 double floats and 64-bit integer registers.
(define_insn "*movdf_insn_sp64" (define_insn "*movdf_insn_sp64"
[(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r") [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
(match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,F"))] (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
"TARGET_FPU "TARGET_FPU
&& TARGET_ARCH64 && TARGET_ARCH64
&& (register_operand (operands[0], <V64:MODE>mode) && (register_operand (operands[0], <V64:MODE>mode)
...@@ -2643,22 +2643,17 @@ ...@@ -2643,22 +2643,17 @@
stx\t%r1, %0" stx\t%r1, %0"
[(set_attr "type" "*,load,store")]) [(set_attr "type" "*,load,store")])
;; This pattern build DFmode constants in integer registers. ;; This pattern builds V64mode constants in integer registers.
(define_split (define_split
[(set (match_operand:DF 0 "register_operand" "") [(set (match_operand:V64 0 "register_operand" "")
(match_operand:DF 1 "const_double_operand" ""))] (match_operand:V64 1 "const_double_or_vector_operand" ""))]
"TARGET_FPU "TARGET_FPU
&& (GET_CODE (operands[0]) == REG && (GET_CODE (operands[0]) == REG
&& REGNO (operands[0]) < 32) && REGNO (operands[0]) < 32)
&& ! const_zero_operand(operands[1], DFmode) && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
&& reload_completed" && reload_completed"
[(clobber (const_int 0))] [(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);
operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0])); operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
if (TARGET_ARCH64) if (TARGET_ARCH64)
...@@ -2666,31 +2661,34 @@ ...@@ -2666,31 +2661,34 @@
#if HOST_BITS_PER_WIDE_INT == 32 #if HOST_BITS_PER_WIDE_INT == 32
gcc_unreachable (); gcc_unreachable ();
#else #else
HOST_WIDE_INT val; enum machine_mode mode = GET_MODE (operands[1]);
rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
val = ((HOST_WIDE_INT)(unsigned long)l[1] | emit_insn (gen_movdi (operands[0], tem));
((HOST_WIDE_INT)(unsigned long)l[0] << 32));
emit_insn (gen_movdi (operands[0], gen_int_mode (val, DImode)));
#endif #endif
} }
else else
{ {
emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), enum machine_mode mode = GET_MODE (operands[1]);
gen_int_mode (l[0], SImode))); rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
gcc_assert (GET_CODE (hi) == CONST_INT);
gcc_assert (GET_CODE (lo) == CONST_INT);
emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
/* Slick... but this trick loses if this subreg constant part /* Slick... but this trick loses if this subreg constant part
can be done in one insn. */ can be done in one insn. */
if (l[1] == l[0] if (lo == hi
&& ! SPARC_SETHI32_P (l[0]) && ! SPARC_SETHI32_P (INTVAL (hi))
&& ! SPARC_SIMM13_P (l[0])) && ! SPARC_SIMM13_P (INTVAL (hi)))
{ {
emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
gen_highpart (SImode, operands[0]))); gen_highpart (SImode, operands[0])));
} }
else else
{ {
emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
gen_int_mode (l[1], SImode)));
} }
} }
DONE; DONE;
......
...@@ -2738,6 +2738,9 @@ when the Visual Instruction Set is available. ...@@ -2738,6 +2738,9 @@ when the Visual Instruction Set is available.
@item h @item h
64-bit global or out register for the SPARC-V8+ architecture. 64-bit global or out register for the SPARC-V8+ architecture.
@item D
A vector constant
@item I @item I
Signed 13-bit constant Signed 13-bit constant
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment