From bf1e3646d150a0fcb542c918ad381f9aee583633 Mon Sep 17 00:00:00 2001 From: James Greenhalgh Date: Thu, 24 Nov 2016 18:14:36 +0000 Subject: [PATCH] [Patch AArch64 11/17] Add floatdihf2 and floatunsdihf2 patterns gcc/ * config/aarch64/aarch64.md (sihf2): Convert to expand. (dihf2): Likewise. (aarch64_fp16_hf2): New. gcc/testsuite/ * gcc.target/aarch64/floatdihf2_1.c: New. From-SVN: r242843 --- gcc/ChangeLog | 6 ++ gcc/config/aarch64/aarch64.md | 56 ++++++++++++++++++- gcc/testsuite/ChangeLog | 4 ++ .../gcc.target/aarch64/floatdihf2_1.c | 35 ++++++++++++ 4 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/floatdihf2_1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ca7155d926e..f142c469acb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-11-24 James Greenhalgh + + * config/aarch64/aarch64.md (sihf2): Convert to expand. + (dihf2): Likewise. + (aarch64_fp16_hf2): New. + 2016-11-24 Alexander Monakov PR target/67822 diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 3d212325931..26982f67ee3 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -4652,7 +4652,14 @@ [(set_attr "type" "f_cvti2f")] ) -(define_insn "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_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 "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_sihf2 (operands[0], operands[1])); + else + { + rtx convert_target = gen_reg_rtx (DFmode); + emit_insn (gen_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 "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_dihf2 (operands[0], operands[1])); + else + { + rtx sat_target = gen_reg_rtx (SImode); + emit_insn (gen_aarch64_qmovndi (sat_target, operands[1])); + emit_insn (gen_sihf2 (operands[0], sat_target)); + } + + DONE; +} +) + ;; Convert between fixed-point and floating-point (scalar modes) (define_insn "3" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 96c5957eebf..12a17c9a395 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2016-11-24 James Greenhalgh + + * gcc.target/aarch64/floatdihf2_1.c: New. + 2016-11-24 Kyrylo Tkachov 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 00000000000..9eaa4ba693e --- /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" } } */ -- 2.30.2