Commit cdbf870f by Andrew Stubbs Committed by Ulrich Weigand

arm.md (zero_extend<mode>di2): Add extra alternatives for NEON registers.

2012-12-17  Andrew Stubbs  <ams@codesourcery.com>
	    Ulrich Weigand  <ulrich.weigand@linaro.org>

	gcc/
	* config/arm/arm.md (zero_extend<mode>di2): Add extra alternatives
	for NEON registers.
	Add alternative for one-instruction extend-in-place.
	(extend<mode>di2): Likewise.
	Add constraints for Thumb-mode memory loads.
	Prevent extend splitters doing NEON alternatives.
	* config/arm/iterators.md (qhs_extenddi_cstr, qhs_zextenddi_cstr):
	Adjust constraints to add new alternatives.
	* config/arm/neon.md: Add splitters for zero- and sign-extend.

	gcc/testsuite/
	* gcc.target/arm/neon-extend-1.c: New file.
	* gcc.target/arm/neon-extend-2.c: New file.

Co-Authored-By: Ulrich Weigand <ulrich.weigand@linaro.org>

From-SVN: r194558
parent 55ebe5ab
2012-12-17 Andrew Stubbs <ams@codesourcery.com>
Ulrich Weigand <ulrich.weigand@linaro.org>
* config/arm/arm.md (zero_extend<mode>di2): Add extra alternatives
for NEON registers.
Add alternative for one-instruction extend-in-place.
(extend<mode>di2): Likewise.
Add constraints for Thumb-mode memory loads.
Prevent extend splitters doing NEON alternatives.
* config/arm/iterators.md (qhs_extenddi_cstr, qhs_zextenddi_cstr):
Adjust constraints to add new alternatives.
* config/arm/neon.md: Add splitters for zero- and sign-extend.
2012-12-17 Greta Yorsh <Greta.Yorsh@arm.com> 2012-12-17 Greta Yorsh <Greta.Yorsh@arm.com>
* config/arm/arm.md (type): Add "simple_alu_shift" to attribute "type". * config/arm/arm.md (type): Add "simple_alu_shift" to attribute "type".
...@@ -4488,33 +4488,36 @@ ...@@ -4488,33 +4488,36 @@
;; Zero and sign extension instructions. ;; Zero and sign extension instructions.
(define_insn "zero_extend<mode>di2" (define_insn "zero_extend<mode>di2"
[(set (match_operand:DI 0 "s_register_operand" "=r") [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r")
(zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>" (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
"<qhs_zextenddi_cstr>")))] "<qhs_zextenddi_cstr>")))]
"TARGET_32BIT <qhs_zextenddi_cond>" "TARGET_32BIT <qhs_zextenddi_cond>"
"#" "#"
[(set_attr "length" "8") [(set_attr "length" "8,4,8")
(set_attr "ce_count" "2") (set_attr "ce_count" "2")
(set_attr "predicable" "yes")] (set_attr "predicable" "yes")]
) )
(define_insn "extend<mode>di2" (define_insn "extend<mode>di2"
[(set (match_operand:DI 0 "s_register_operand" "=r") [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r")
(sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>" (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
"<qhs_extenddi_cstr>")))] "<qhs_extenddi_cstr>")))]
"TARGET_32BIT <qhs_sextenddi_cond>" "TARGET_32BIT <qhs_sextenddi_cond>"
"#" "#"
[(set_attr "length" "8") [(set_attr "length" "8,4,8,8")
(set_attr "ce_count" "2") (set_attr "ce_count" "2")
(set_attr "shift" "1") (set_attr "shift" "1")
(set_attr "predicable" "yes")] (set_attr "predicable" "yes")
(set_attr "arch" "*,*,a,t")]
) )
;; Splits for all extensions to DImode ;; Splits for all extensions to DImode
(define_split (define_split
[(set (match_operand:DI 0 "s_register_operand" "") [(set (match_operand:DI 0 "s_register_operand" "")
(zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))] (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
"TARGET_32BIT" "TARGET_32BIT && (!TARGET_NEON
|| (reload_completed
&& !(IS_VFP_REGNUM (REGNO (operands[0])))))"
[(set (match_dup 0) (match_dup 1))] [(set (match_dup 0) (match_dup 1))]
{ {
rtx lo_part = gen_lowpart (SImode, operands[0]); rtx lo_part = gen_lowpart (SImode, operands[0]);
...@@ -4540,7 +4543,9 @@ ...@@ -4540,7 +4543,9 @@
(define_split (define_split
[(set (match_operand:DI 0 "s_register_operand" "") [(set (match_operand:DI 0 "s_register_operand" "")
(sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))] (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
"TARGET_32BIT" "TARGET_32BIT && (!TARGET_NEON
|| (reload_completed
&& !(IS_VFP_REGNUM (REGNO (operands[0])))))"
[(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))] [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
{ {
rtx lo_part = gen_lowpart (SImode, operands[0]); rtx lo_part = gen_lowpart (SImode, operands[0]);
......
...@@ -429,8 +429,8 @@ ...@@ -429,8 +429,8 @@
(define_mode_attr qhs_extenddi_op [(SI "s_register_operand") (define_mode_attr qhs_extenddi_op [(SI "s_register_operand")
(HI "nonimmediate_operand") (HI "nonimmediate_operand")
(QI "arm_reg_or_extendqisi_mem_op")]) (QI "arm_reg_or_extendqisi_mem_op")])
(define_mode_attr qhs_extenddi_cstr [(SI "r") (HI "rm") (QI "rUq")]) (define_mode_attr qhs_extenddi_cstr [(SI "r,0,r,r") (HI "r,0,rm,rm") (QI "r,0,rUq,rm")])
(define_mode_attr qhs_zextenddi_cstr [(SI "r") (HI "rm") (QI "rm")]) (define_mode_attr qhs_zextenddi_cstr [(SI "r,0,r") (HI "r,0,rm") (QI "r,0,rm")])
;; Mode attributes used for fixed-point support. ;; Mode attributes used for fixed-point support.
(define_mode_attr qaddsub_suf [(V4UQQ "8") (V2UHQ "16") (UQQ "8") (UHQ "16") (define_mode_attr qaddsub_suf [(V4UQQ "8") (V2UHQ "16") (UQQ "8") (UHQ "16")
......
...@@ -5932,3 +5932,65 @@ ...@@ -5932,3 +5932,65 @@
(const_string "neon_fp_vadd_qqq_vabs_qq")) (const_string "neon_fp_vadd_qqq_vabs_qq"))
(const_string "neon_int_5")))] (const_string "neon_int_5")))]
) )
;; Copy from core-to-neon regs, then extend, not vice-versa
(define_split
[(set (match_operand:DI 0 "s_register_operand" "")
(sign_extend:DI (match_operand:SI 1 "s_register_operand" "")))]
"TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
[(set (match_dup 2) (vec_duplicate:V2SI (match_dup 1)))
(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 32)))]
{
operands[2] = gen_rtx_REG (V2SImode, REGNO (operands[0]));
})
(define_split
[(set (match_operand:DI 0 "s_register_operand" "")
(sign_extend:DI (match_operand:HI 1 "s_register_operand" "")))]
"TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
[(set (match_dup 2) (vec_duplicate:V4HI (match_dup 1)))
(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
{
operands[2] = gen_rtx_REG (V4HImode, REGNO (operands[0]));
})
(define_split
[(set (match_operand:DI 0 "s_register_operand" "")
(sign_extend:DI (match_operand:QI 1 "s_register_operand" "")))]
"TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
[(set (match_dup 2) (vec_duplicate:V8QI (match_dup 1)))
(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
{
operands[2] = gen_rtx_REG (V8QImode, REGNO (operands[0]));
})
(define_split
[(set (match_operand:DI 0 "s_register_operand" "")
(zero_extend:DI (match_operand:SI 1 "s_register_operand" "")))]
"TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
[(set (match_dup 2) (vec_duplicate:V2SI (match_dup 1)))
(set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 32)))]
{
operands[2] = gen_rtx_REG (V2SImode, REGNO (operands[0]));
})
(define_split
[(set (match_operand:DI 0 "s_register_operand" "")
(zero_extend:DI (match_operand:HI 1 "s_register_operand" "")))]
"TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
[(set (match_dup 2) (vec_duplicate:V4HI (match_dup 1)))
(set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
{
operands[2] = gen_rtx_REG (V4HImode, REGNO (operands[0]));
})
(define_split
[(set (match_operand:DI 0 "s_register_operand" "")
(zero_extend:DI (match_operand:QI 1 "s_register_operand" "")))]
"TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
[(set (match_dup 2) (vec_duplicate:V8QI (match_dup 1)))
(set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
{
operands[2] = gen_rtx_REG (V8QImode, REGNO (operands[0]));
})
2012-12-17 Andrew Stubbs <ams@codesourcery.com>
Ulrich Weigand <ulrich.weigand@linaro.org>
* gcc.target/arm/neon-extend-1.c: New file.
* gcc.target/arm/neon-extend-2.c: New file.
2012-12-17 Kyrylo Tkachov <kyrylo.tkachov@arm.com> 2012-12-17 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* lib/target-supports.exp (add_options_for_arm_v8_neon): * lib/target-supports.exp (add_options_for_arm_v8_neon):
......
/* { dg-require-effective-target arm_neon_hw } */
/* { dg-options "-O2" } */
/* { dg-add-options arm_neon } */
void
f (unsigned int a)
{
unsigned long long b = a;
asm volatile ("@ extended to %0" : : "w" (b));
}
/* { dg-final { scan-assembler "vdup.32" } } */
/* { dg-final { scan-assembler "vshr.u64" } } */
/* { dg-require-effective-target arm_neon_hw } */
/* { dg-options "-O2" } */
/* { dg-add-options arm_neon } */
void
f (int a)
{
long long b = a;
asm volatile ("@ extended to %0" : : "w" (b));
}
/* { dg-final { scan-assembler "vdup.32" } } */
/* { dg-final { scan-assembler "vshr.s64" } } */
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