[PATCH 5/17][ARM] Enable HI mode moves for floating point values.

gcc/
2016-09-23  Jiong Wang  <jiong.wang@arm.com>
	    Matthew Wahab  <matthew.wahab@arm.com>

	* config/arm/arm.c (output_move_vfp): Weaken assert to allow
	HImode.
	(arm_hard_regno_mode_ok): Allow HImode values in VFP registers.
	* config/arm/arm.md (*movhi_bytes): Disable when VFP registers are
	available.  Also fix some white-space.
	* config/arm/vfp.md (*arm_movhi_vfp): New.
	(*thumb2_movhi_vfp): New.

testsuite/
2016-09-23  Matthew Wahab  <matthew.wahab@arm.com>

	* gcc.target/arm/short-vfp-1.c: New.

From-SVN: r240403
This commit is contained in:
Matthew Wahab 2016-09-23 09:15:24 +00:00
parent 536b9f42ce
commit 50df9464b8
6 changed files with 161 additions and 3 deletions

View File

@ -1,3 +1,14 @@
2016-09-23 Jiong Wang <jiong.wang@arm.com>
Matthew Wahab <matthew.wahab@arm.com>
* config/arm/arm.c (output_move_vfp): Weaken assert to allow
HImode.
(arm_hard_regno_mode_ok): Allow HImode values in VFP registers.
* config/arm/arm.md (*movhi_bytes): Disable when VFP registers are
available. Also fix some white-space.
* config/arm/vfp.md (*arm_movhi_vfp): New.
(*thumb2_movhi_vfp): New.
2016-09-23 Matthew Wahab <matthew.wahab@arm.com>
* config/arm/arm-c.c (arm_cpu_builtins): Define

View File

@ -18722,6 +18722,7 @@ output_move_vfp (rtx *operands)
gcc_assert ((mode == HFmode && TARGET_HARD_FLOAT && TARGET_VFP)
|| mode == SFmode
|| mode == DFmode
|| mode == HImode
|| mode == SImode
|| mode == DImode
|| (TARGET_NEON && VALID_NEON_DREG_MODE (mode)));
@ -23515,6 +23516,10 @@ arm_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
if (mode == HFmode)
return VFP_REGNO_OK_FOR_SINGLE (regno);
/* VFP registers can hold HImode values. */
if (mode == HImode)
return VFP_REGNO_OK_FOR_SINGLE (regno);
if (TARGET_NEON)
return (VALID_NEON_DREG_MODE (mode) && VFP_REGNO_OK_FOR_DOUBLE (regno))
|| (VALID_NEON_QREG_MODE (mode)

View File

@ -6700,7 +6700,7 @@
[(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
(match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
"TARGET_ARM
&& arm_arch4
&& arm_arch4 && !(TARGET_HARD_FLOAT && TARGET_VFP)
&& (register_operand (operands[0], HImode)
|| register_operand (operands[1], HImode))"
"@
@ -6726,7 +6726,7 @@
(define_insn "*movhi_bytes"
[(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
(match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
"TARGET_ARM"
"TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_VFP)"
"@
mov%?\\t%0, %1\\t%@ movhi
mov%?\\t%0, %1\\t%@ movhi
@ -6734,7 +6734,7 @@
[(set_attr "predicable" "yes")
(set_attr "type" "mov_imm,mov_reg,mvn_imm")]
)
;; We use a DImode scratch because we may occasionally need an additional
;; temporary if the address isn't offsettable -- push_reload doesn't seem
;; to take any notice of the "o" constraints on reload_memory_operand operand.

View File

@ -18,6 +18,99 @@
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>. */
;; Patterns for HI moves which provide more data transfer instructions when VFP
;; support is enabled.
(define_insn "*arm_movhi_vfp"
[(set
(match_operand:HI 0 "nonimmediate_operand"
"=rk, r, r, m, r, *t, r, *t")
(match_operand:HI 1 "general_operand"
"rIk, K, n, r, mi, r, *t, *t"))]
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
&& (register_operand (operands[0], HImode)
|| register_operand (operands[1], HImode))"
{
switch (which_alternative)
{
case 0:
return "mov%?\t%0, %1\t%@ movhi";
case 1:
return "mvn%?\t%0, #%B1\t%@ movhi";
case 2:
return "movw%?\t%0, %L1\t%@ movhi";
case 3:
return "strh%?\t%1, %0\t%@ movhi";
case 4:
return "ldrh%?\t%0, %1\t%@ movhi";
case 5:
case 6:
return "vmov%?\t%0, %1\t%@ int";
case 7:
return "vmov%?.f32\t%0, %1\t%@ int";
default:
gcc_unreachable ();
}
}
[(set_attr "predicable" "yes")
(set_attr_alternative "type"
[(if_then_else
(match_operand 1 "const_int_operand" "")
(const_string "mov_imm")
(const_string "mov_reg"))
(const_string "mvn_imm")
(const_string "mov_imm")
(const_string "store1")
(const_string "load1")
(const_string "f_mcr")
(const_string "f_mrc")
(const_string "fmov")])
(set_attr "pool_range" "*, *, *, *, 256, *, *, *")
(set_attr "neg_pool_range" "*, *, *, *, 244, *, *, *")
(set_attr "length" "4")]
)
(define_insn "*thumb2_movhi_vfp"
[(set
(match_operand:HI 0 "nonimmediate_operand"
"=rk, r, l, r, m, r, *t, r, *t")
(match_operand:HI 1 "general_operand"
"rk, I, Py, n, r, m, r, *t, *t"))]
"TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP
&& (register_operand (operands[0], HImode)
|| register_operand (operands[1], HImode))"
{
switch (which_alternative)
{
case 0:
case 1:
case 2:
return "mov%?\t%0, %1\t%@ movhi";
case 3:
return "movw%?\t%0, %L1\t%@ movhi";
case 4:
return "strh%?\t%1, %0\t%@ movhi";
case 5:
return "ldrh%?\t%0, %1\t%@ movhi";
case 6:
case 7:
return "vmov%?\t%0, %1\t%@ int";
case 8:
return "vmov%?.f32\t%0, %1\t%@ int";
default:
gcc_unreachable ();
}
}
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it"
"yes, no, yes, no, no, no, no, no, no")
(set_attr "type"
"mov_reg, mov_imm, mov_imm, mov_imm, store1, load1,\
f_mcr, f_mrc, fmov")
(set_attr "pool_range" "*, *, *, *, *, 4094, *, *, *")
(set_attr "neg_pool_range" "*, *, *, *, *, 250, *, *, *")
(set_attr "length" "2, 4, 2, 4, 4, 4, 4, 4, 4")]
)
;; SImode moves
;; ??? For now do not allow loading constants into vfp regs. This causes
;; problems because small constants get converted into adds.

View File

@ -1,3 +1,7 @@
2016-09-23 Matthew Wahab <matthew.wahab@arm.com>
* gcc.target/arm/short-vfp-1.c: New.
2016-09-23 Matthew Wahab <matthew.wahab@arm.com>
* gcc.target/arm/attr-fp16-arith-1.c: New.

View File

@ -0,0 +1,45 @@
/* { dg-do compile } */
/* { dg-require-effective-target arm_vfp_ok }
/* { dg-options "-mfpu=vfp" } */
int
test_sisf (float x)
{
return (int)x;
}
short
test_hisf (float x)
{
return (short)x;
}
float
test_sfsi (int x)
{
return (float)x;
}
float
test_sfhi (short x)
{
return (float)x;
}
short
test_hisi (int x)
{
return (short)x;
}
int
test_sihi (short x)
{
return (int)x;
}
/* {dg-final { scan-assembler-times {vcvt\.s32\.f32\ts[0-9]+,s[0-9]+} 2 }} */
/* {dg-final { scan-assembler-times {vcvt\.f32\.s32\ts[0-9]+,s[0-9]+} 2 }} */
/* {dg-final { scan-assembler-times {vmov\tr[0-9]+,s[0-9]+} 2 }} */
/* {dg-final { scan-assembler-times {vmov\ts[0-9]+,r[0-9]+} 2 }} */
/* {dg-final { scan-assembler-times {sxth\tr[0-9]+,r[0-9]+} 2 }} */