+2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm.md (arm_<simd32_op><add_clobber_q_name>_insn):
+ New define_insns.
+ (arm_<simd32_op>): New define_expands.
+ * config/arm/arm_acle.h (__smlad, __smladx, __smlsd, __smlsdx,
+ __smuad, __smuadx): Define.
+ * config/arm/arm_acle_builtins.def: Define builtins for the above.
+ * config/arm/iterators.md (SIMD32_TERNOP_Q): New int_iterator.
+ (SIMD32_BINOP_Q): Likewise.
+ (simd32_op): Handle the above.
+ * config/arm/unspecs.md: Define unspecs for the above.
+
2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/aout.h (REGISTER_NAMES): Add apsrge.
[(set_attr "predicable" "yes")
(set_attr "type" "alu_sreg")])
+(define_insn "arm_<simd32_op><add_clobber_q_name>_insn"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (unspec:SI
+ [(match_operand:SI 1 "s_register_operand" "r")
+ (match_operand:SI 2 "s_register_operand" "r")
+ (match_operand:SI 3 "s_register_operand" "r")] SIMD32_TERNOP_Q))]
+ "TARGET_INT_SIMD && <add_clobber_q_pred>"
+ "<simd32_op>%?\\t%0, %1, %2, %3"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "alu_sreg")])
+
+(define_expand "arm_<simd32_op>"
+ [(set (match_operand:SI 0 "s_register_operand")
+ (unspec:SI
+ [(match_operand:SI 1 "s_register_operand")
+ (match_operand:SI 2 "s_register_operand")
+ (match_operand:SI 3 "s_register_operand")] SIMD32_TERNOP_Q))]
+ "TARGET_INT_SIMD"
+ {
+ if (ARM_Q_BIT_READ)
+ emit_insn (gen_arm_<simd32_op>_setq_insn (operands[0], operands[1],
+ operands[2], operands[3]));
+ else
+ emit_insn (gen_arm_<simd32_op>_insn (operands[0], operands[1],
+ operands[2], operands[3]));
+ DONE;
+ }
+)
+
+(define_insn "arm_<simd32_op><add_clobber_q_name>_insn"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (unspec:SI
+ [(match_operand:SI 1 "s_register_operand" "r")
+ (match_operand:SI 2 "s_register_operand" "r")] SIMD32_BINOP_Q))]
+ "TARGET_INT_SIMD && <add_clobber_q_pred>"
+ "<simd32_op>%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "alu_sreg")])
+
+(define_expand "arm_<simd32_op>"
+ [(set (match_operand:SI 0 "s_register_operand")
+ (unspec:SI
+ [(match_operand:SI 1 "s_register_operand")
+ (match_operand:SI 2 "s_register_operand")] SIMD32_BINOP_Q))]
+ "TARGET_INT_SIMD"
+ {
+ if (ARM_Q_BIT_READ)
+ emit_insn (gen_arm_<simd32_op>_setq_insn (operands[0], operands[1],
+ operands[2]));
+ else
+ emit_insn (gen_arm_<simd32_op>_insn (operands[0], operands[1],
+ operands[2]));
+ DONE;
+ }
+)
+
(define_insn "arm_sel"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(unspec:SI
return __builtin_arm_usub16 (__a, __b);
}
+__extension__ extern __inline int32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__smlad (int16x2_t __a, int16x2_t __b, int32_t __c)
+{
+ return __builtin_arm_smlad (__a, __b, __c);
+}
+
+__extension__ extern __inline int32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__smladx (int16x2_t __a, int16x2_t __b, int32_t __c)
+{
+ return __builtin_arm_smladx (__a, __b, __c);
+}
+
+__extension__ extern __inline int32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__smlsd (int16x2_t __a, int16x2_t __b, int32_t __c)
+{
+ return __builtin_arm_smlsd (__a, __b, __c);
+}
+
+__extension__ extern __inline int32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__smlsdx (int16x2_t __a, int16x2_t __b, int32_t __c)
+{
+ return __builtin_arm_smlsdx (__a, __b, __c);
+}
+
+__extension__ extern __inline int32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__smuad (int16x2_t __a, int16x2_t __b)
+{
+ return __builtin_arm_smuad (__a, __b);
+}
+
+__extension__ extern __inline int32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__smuadx (int16x2_t __a, int16x2_t __b)
+{
+ return __builtin_arm_smuadx (__a, __b);
+}
+
#endif
#ifdef __ARM_FEATURE_SAT
VAR1 (UBINOP, usub16, si)
VAR1 (UBINOP, sel, si)
+
+VAR1 (TERNOP, smlad, si)
+VAR1 (TERNOP, smladx, si)
+VAR1 (TERNOP, smlsd, si)
+VAR1 (TERNOP, smlsdx, si)
+VAR1 (BINOP, smuad, si)
+VAR1 (BINOP, smuadx, si)
UNSPEC_SSAX UNSPEC_SSUB16 UNSPEC_UADD16
UNSPEC_UASX UNSPEC_USAX UNSPEC_USUB16])
+(define_int_iterator SIMD32_TERNOP_Q [UNSPEC_SMLAD UNSPEC_SMLADX UNSPEC_SMLSD
+ UNSPEC_SMLSDX])
+
+(define_int_iterator SIMD32_BINOP_Q [UNSPEC_SMUAD UNSPEC_SMUADX])
+
(define_int_iterator VQRDMLH_AS [UNSPEC_VQRDMLAH UNSPEC_VQRDMLSH])
(define_int_iterator VFM_LANE_AS [UNSPEC_VFMA_LANE UNSPEC_VFMS_LANE])
(UNSPEC_SASX "sasx") (UNSPEC_SSAX "ssax")
(UNSPEC_SSUB16 "ssub16") (UNSPEC_UADD16 "uadd16")
(UNSPEC_UASX "uasx") (UNSPEC_USAX "usax")
- (UNSPEC_USUB16 "usub16")])
+ (UNSPEC_USUB16 "usub16") (UNSPEC_SMLAD "smlad")
+ (UNSPEC_SMLADX "smladx") (UNSPEC_SMLSD "smlsd")
+ (UNSPEC_SMLSDX "smlsdx") (UNSPEC_SMUAD "smuad")
+ (UNSPEC_SMUADX "smuadx")])
;; Both kinds of return insn.
(define_code_iterator RETURNS [return simple_return])
UNSPEC_UASX ; Represent the UASX operation.
UNSPEC_USAX ; Represent the USAX operation.
UNSPEC_USUB16 ; Represent the USUB16 operation.
+ UNSPEC_SMLAD ; Represent the SMLAD operation.
+ UNSPEC_SMLADX ; Represent the SMLADX operation.
+ UNSPEC_SMLSD ; Represent the SMLSD operation.
+ UNSPEC_SMLSDX ; Represent the SMLSDX operation.
+ UNSPEC_SMUAD ; Represent the SMUAD operation.
+ UNSPEC_SMUADX ; Represent the SMUADX operation.
])
+2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * gcc.target/arm/acle/simd32.c: Update test.
+
2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* gcc.target/arm/acle/simd32.c: Update test.
}
/* { dg-final { scan-assembler-times "\tusub16\t...?, ...?, ...?" 1 } } */
+
+int32_t
+test_smlad (int16x2_t a, int16x2_t b, int32_t c)
+{
+ return __smlad (a, b, c);
+}
+
+/* { dg-final { scan-assembler-times "\tsmlad\t...?, ...?, ...?, ...?" 1 } } */
+
+int32_t
+test_smladx (int16x2_t a, int16x2_t b, int32_t c)
+{
+ return __smladx (a, b, c);
+}
+
+/* { dg-final { scan-assembler-times "\tsmladx\t...?, ...?, ...?, ...?" 1 } } */
+
+int32_t
+test_smlsd (int16x2_t a, int16x2_t b, int32_t c)
+{
+ return __smlsd (a, b, c);
+}
+
+/* { dg-final { scan-assembler-times "\tsmlsd\t...?, ...?, ...?, ...?" 1 } } */
+
+int32_t
+test_smlsdx (int16x2_t a, int16x2_t b, int32_t c)
+{
+ return __smlsdx (a, b, c);
+}
+
+/* { dg-final { scan-assembler-times "\tsmlsdx\t...?, ...?, ...?, ...?" 1 } } */
+
+int32_t
+test_smuad (int16x2_t a, int16x2_t b)
+{
+ return __smuad (a, b);
+}
+
+/* { dg-final { scan-assembler-times "\tsmuad\t...?, ...?, ...?" 1 } } */
+
+int32_t
+test_smuadx (int16x2_t a, int16x2_t b)
+{
+ return __smuadx (a, b);
+}
+
+/* { dg-final { scan-assembler-times "\tsmuadx\t...?, ...?, ...?" 1 } } */