[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
This commit is contained in:
James Greenhalgh 2016-11-24 18:14:36 +00:00 committed by James Greenhalgh
parent e210b51b58
commit bf1e3646d1
4 changed files with 100 additions and 1 deletions

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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" } } */