[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:
parent
536b9f42ce
commit
50df9464b8
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
45
gcc/testsuite/gcc.target/arm/short-vfp-1.c
Normal file
45
gcc/testsuite/gcc.target/arm/short-vfp-1.c
Normal 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 }} */
|
Loading…
Reference in New Issue
Block a user