diff options
author | James Greenhalgh <james.greenhalgh@arm.com> | 2016-11-24 18:14:36 +0000 |
---|---|---|
committer | James Greenhalgh <jgreenhalgh@gcc.gnu.org> | 2016-11-24 18:14:36 +0000 |
commit | bf1e3646d150a0fcb542c918ad381f9aee583633 (patch) | |
tree | dc6f4d854dc0606b3243ce9d9d162180eb0edc5e | |
parent | e210b51b58d1431b7f710e7eac00bd9c128632b3 (diff) | |
download | gcc-bf1e3646d150a0fcb542c918ad381f9aee583633.zip gcc-bf1e3646d150a0fcb542c918ad381f9aee583633.tar.gz gcc-bf1e3646d150a0fcb542c918ad381f9aee583633.tar.bz2 |
[Patch AArch64 11/17] Add floatdihf2 and floatunsdihf2 patterns
gcc/
* config/aarch64/aarch64.md (<optab>sihf2): Convert to expand.
(<optab>dihf2): Likewise.
(aarch64_fp16_<optab><mode>hf2): New.
gcc/testsuite/
* gcc.target/aarch64/floatdihf2_1.c: New.
From-SVN: r242843
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.md | 56 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/floatdihf2_1.c | 35 |
4 files changed, 100 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ca7155d..f142c46 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-11-24 James Greenhalgh <james.greenhalgh@arm.com> + + * config/aarch64/aarch64.md (<optab>sihf2): Convert to expand. + (<optab>dihf2): Likewise. + (aarch64_fp16_<optab><mode>hf2): New. + 2016-11-24 Alexander Monakov <amonakov@ispras.ru> PR target/67822 diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 3d21232..26982f6 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -4652,7 +4652,14 @@ [(set_attr "type" "f_cvti2f")] ) -(define_insn "<optab><mode>hf2" +;; If we do not have ARMv8.2-A 16-bit floating point extensions, the +;; midend will arrange for an SImode conversion to HFmode to first go +;; through DFmode, then to HFmode. But first it will try converting +;; to DImode then down, which would match our DImode pattern below and +;; give very poor code-generation. So, we must provide our own emulation +;; of the mid-end logic. + +(define_insn "aarch64_fp16_<optab><mode>hf2" [(set (match_operand:HF 0 "register_operand" "=w") (FLOATUORS:HF (match_operand:GPI 1 "register_operand" "r")))] "TARGET_FP_F16INST" @@ -4660,6 +4667,53 @@ [(set_attr "type" "f_cvti2f")] ) +(define_expand "<optab>sihf2" + [(set (match_operand:HF 0 "register_operand") + (FLOATUORS:HF (match_operand:SI 1 "register_operand")))] + "TARGET_FLOAT" +{ + if (TARGET_FP_F16INST) + emit_insn (gen_aarch64_fp16_<optab>sihf2 (operands[0], operands[1])); + else + { + rtx convert_target = gen_reg_rtx (DFmode); + emit_insn (gen_<optab>sidf2 (convert_target, operands[1])); + emit_insn (gen_truncdfhf2 (operands[0], convert_target)); + } + DONE; +} +) + +;; For DImode there is no wide enough floating-point mode that we +;; can convert through natively (TFmode would work, but requires a library +;; call). However, we know that any value >= 65504 will be rounded +;; to infinity on conversion. This is well within the range of SImode, so +;; we can: +;; Saturate to SImode. +;; Convert from that to DFmode +;; Convert from that to HFmode (phew!). +;; Note that the saturation to SImode requires the SIMD extensions. If +;; we ever need to provide this pattern where the SIMD extensions are not +;; available, we would need a different approach. + +(define_expand "<optab>dihf2" + [(set (match_operand:HF 0 "register_operand") + (FLOATUORS:HF (match_operand:DI 1 "register_operand")))] + "TARGET_FLOAT && (TARGET_FP_F16INST || TARGET_SIMD)" +{ + if (TARGET_FP_F16INST) + emit_insn (gen_aarch64_fp16_<optab>dihf2 (operands[0], operands[1])); + else + { + rtx sat_target = gen_reg_rtx (SImode); + emit_insn (gen_aarch64_<su_optab>qmovndi (sat_target, operands[1])); + emit_insn (gen_<optab>sihf2 (operands[0], sat_target)); + } + + DONE; +} +) + ;; Convert between fixed-point and floating-point (scalar modes) (define_insn "<FCVT_F2FIXED:fcvt_fixed_insn><GPF:mode>3" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 96c5957..12a17c9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2016-11-24 James Greenhalgh <james.greenhalgh@arm.com> + + * gcc.target/aarch64/floatdihf2_1.c: New. + 2016-11-24 Kyrylo Tkachov <kyrylo.tkachov@arm.com> PR target/48863 diff --git a/gcc/testsuite/gcc.target/aarch64/floatdihf2_1.c b/gcc/testsuite/gcc.target/aarch64/floatdihf2_1.c new file mode 100644 index 0000000..9eaa4ba --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/floatdihf2_1.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +/* Test that conversion from 32-bit and 64-bit integers can be done + without a call to the support library. */ + +#pragma GCC target ("arch=armv8.2-a+nofp16") + +__fp16 +foo (int x) +{ + return x; +} + +__fp16 +bar (unsigned int x) +{ + return x; +} + +__fp16 +fool (long long x) +{ + return x; +} + +__fp16 +barl (unsigned long long x) +{ + return x; +} + + +/* { dg-final { scan-assembler-not "__float\\\[ds\\\]ihf2" } } */ +/* { dg-final { scan-assembler-not "__floatun\\\[ds\\\]ihf2" } } */ |