[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:
parent
e210b51b58
commit
bf1e3646d1
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
35
gcc/testsuite/gcc.target/aarch64/floatdihf2_1.c
Normal file
35
gcc/testsuite/gcc.target/aarch64/floatdihf2_1.c
Normal 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" } } */
|
Loading…
x
Reference in New Issue
Block a user