diff options
author | Matthew Wahab <mwahab@gcc.gnu.org> | 2016-09-23 09:15:24 +0000 |
---|---|---|
committer | Matthew Wahab <mwahab@gcc.gnu.org> | 2016-09-23 09:15:24 +0000 |
commit | 50df9464b86a58d5c959b10c33c1870c0c4c5e48 (patch) | |
tree | 582fdcac750944cd89464792e4717977ea423288 | |
parent | 536b9f42cef7c74e3c92e5eaeb12b8514582907c (diff) | |
download | gcc-50df9464b86a58d5c959b10c33c1870c0c4c5e48.zip gcc-50df9464b86a58d5c959b10c33c1870c0c4c5e48.tar.gz gcc-50df9464b86a58d5c959b10c33c1870c0c4c5e48.tar.bz2 |
[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
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 5 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 6 | ||||
-rw-r--r-- | gcc/config/arm/vfp.md | 93 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/short-vfp-1.c | 45 |
6 files changed, 161 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 12adfb9..d5b764d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 664c582..04c73d9 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -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) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 4df856a..fe4c6e7 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -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. diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md index 9750ba1..d7c874a 100644 --- a/gcc/config/arm/vfp.md +++ b/gcc/config/arm/vfp.md @@ -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. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f2fb03c..f19e24b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 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. 2016-09-23 Matthew Wahab <matthew.wahab@arm.com> diff --git a/gcc/testsuite/gcc.target/arm/short-vfp-1.c b/gcc/testsuite/gcc.target/arm/short-vfp-1.c new file mode 100644 index 0000000..d96c763 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/short-vfp-1.c @@ -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 }} */ |