[arm][2/X] Implement __qadd, __qsub, __qdbl intrinsics
This patch implements some more Q-bit-setting intrinsics from ACLE. With the plumbing from patch 1 in place they are a simple builtin->RTL affair. * config/arm/arm.md (arm_<ss_op>): New define_expand. (arm_<ss_op><add_clobber_q_name>_insn): New define_insn. * config/arm/arm_acle.h (__qadd, __qsub, __qdbl): Define. * config/arm/arm_acle_builtins.def: Add builtins for qadd, qsub. * config/arm/iterators.md (SSPLUSMINUS): New code iterator. (ss_op): New code_attr. * gcc.target/arm/acle/dsp_arith.c: New test. From-SVN: r277915
This commit is contained in:
parent
cf16f980e5
commit
e56d199b04
@ -1,3 +1,12 @@
|
||||
2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||||
|
||||
* config/arm/arm.md (arm_<ss_op>): New define_expand.
|
||||
(arm_<ss_op><add_clobber_q_name>_insn): New define_insn.
|
||||
* config/arm/arm_acle.h (__qadd, __qsub, __qdbl): Define.
|
||||
* config/arm/arm_acle_builtins.def: Add builtins for qadd, qsub.
|
||||
* config/arm/iterators.md (SSPLUSMINUS): New code iterator.
|
||||
(ss_op): New code_attr.
|
||||
|
||||
2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||||
|
||||
* config/arm/aout.h (REGISTER_NAMES): Add apsrq.
|
||||
|
@ -4076,6 +4076,32 @@
|
||||
(set_attr "type" "multiple")]
|
||||
)
|
||||
|
||||
|
||||
(define_expand "arm_<ss_op>"
|
||||
[(set (match_operand:SI 0 "s_register_operand")
|
||||
(SSPLUSMINUS:SI (match_operand:SI 1 "s_register_operand")
|
||||
(match_operand:SI 2 "s_register_operand")))]
|
||||
"TARGET_DSP_MULTIPLY"
|
||||
{
|
||||
if (ARM_Q_BIT_READ)
|
||||
emit_insn (gen_arm_<ss_op>_setq_insn (operands[0],
|
||||
operands[1], operands[2]));
|
||||
else
|
||||
emit_insn (gen_arm_<ss_op>_insn (operands[0], operands[1], operands[2]));
|
||||
DONE;
|
||||
}
|
||||
)
|
||||
|
||||
(define_insn "arm_<ss_op><add_clobber_q_name>_insn"
|
||||
[(set (match_operand:SI 0 "s_register_operand" "=r")
|
||||
(SSPLUSMINUS:SI (match_operand:SI 1 "s_register_operand" "r")
|
||||
(match_operand:SI 2 "s_register_operand" "r")))]
|
||||
"TARGET_DSP_MULTIPLY && <add_clobber_q_pred>"
|
||||
"<ss_op>%?\t%0, %1, %2"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "alu_dsp_reg")]
|
||||
)
|
||||
|
||||
(define_code_iterator SAT [smin smax])
|
||||
(define_code_attr SATrev [(smin "smax") (smax "smin")])
|
||||
(define_code_attr SATlo [(smin "1") (smax "2")])
|
||||
|
@ -478,6 +478,29 @@ __ignore_saturation (void)
|
||||
})
|
||||
#endif
|
||||
|
||||
#ifdef __ARM_FEATURE_DSP
|
||||
__extension__ extern __inline int32_t
|
||||
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
|
||||
__qadd (int32_t __a, int32_t __b)
|
||||
{
|
||||
return __builtin_arm_qadd (__a, __b);
|
||||
}
|
||||
|
||||
__extension__ extern __inline int32_t
|
||||
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
|
||||
__qsub (int32_t __a, int32_t __b)
|
||||
{
|
||||
return __builtin_arm_qsub (__a, __b);
|
||||
}
|
||||
|
||||
__extension__ extern __inline int32_t
|
||||
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
|
||||
__qdbl (int32_t __x)
|
||||
{
|
||||
return __qadd (__x, __x);
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma GCC push_options
|
||||
#ifdef __ARM_FEATURE_CRC32
|
||||
#ifdef __ARM_FP
|
||||
|
@ -84,3 +84,5 @@ VAR1 (SAT_BINOP_UNSIGNED_IMM, ssat, si)
|
||||
VAR1 (UNSIGNED_SAT_BINOP_UNSIGNED_IMM, usat, si)
|
||||
VAR1 (SAT_OCCURRED, saturation_occurred, si)
|
||||
VAR1 (SET_SAT, set_saturation, void)
|
||||
VAR1 (BINOP, qadd, si)
|
||||
VAR1 (BINOP, qsub, si)
|
||||
|
@ -264,6 +264,9 @@
|
||||
;; Conversions.
|
||||
(define_code_iterator FCVT [unsigned_float float])
|
||||
|
||||
;; Saturating addition, subtraction
|
||||
(define_code_iterator SSPLUSMINUS [ss_plus ss_minus])
|
||||
|
||||
;; plus and minus are the only SHIFTABLE_OPS for which Thumb2 allows
|
||||
;; a stack pointer operand. The minus operation is a candidate for an rsub
|
||||
;; and hence only plus is supported.
|
||||
@ -282,6 +285,8 @@
|
||||
|
||||
(define_code_attr vfml_op [(plus "a") (minus "s")])
|
||||
|
||||
(define_code_attr ss_op [(ss_plus "qadd") (ss_minus "qsub")])
|
||||
|
||||
;;----------------------------------------------------------------------------
|
||||
;; Int iterators
|
||||
;;----------------------------------------------------------------------------
|
||||
|
@ -1,3 +1,7 @@
|
||||
2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||||
|
||||
* gcc.target/arm/acle/dsp_arith.c: New test.
|
||||
|
||||
2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||||
|
||||
* gcc.target/arm/acle/saturation.c: New test.
|
||||
|
27
gcc/testsuite/gcc.target/arm/acle/dsp_arith.c
Normal file
27
gcc/testsuite/gcc.target/arm/acle/dsp_arith.c
Normal file
@ -0,0 +1,27 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm_qbit_ok } */
|
||||
/* { dg-add-options arm_qbit } */
|
||||
|
||||
#include <arm_acle.h>
|
||||
|
||||
int32_t
|
||||
test_qadd (int32_t a, int32_t b)
|
||||
{
|
||||
return __qadd (a, b);
|
||||
}
|
||||
|
||||
int32_t
|
||||
test_qdbl (int32_t a)
|
||||
{
|
||||
return __qdbl(a);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-times "qadd\t...?, ...?, ...?" 2 } } */
|
||||
|
||||
int32_t
|
||||
test_qsub (int32_t a, int32_t b)
|
||||
{
|
||||
return __qsub (a, b);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-times "qsub\t...?, ...?, ...?" 1 } } */
|
Loading…
Reference in New Issue
Block a user