1  /* { dg-do compile { target { powerpc*-*-linux* } } } */
       2  /* { dg-require-effective-target powerpc_float128_hw_ok } */
       3  /* { dg-options "-O2 -mpower9-vector -mfloat128-hardware" } */
       4  
       5  #ifndef NO_FLOAT
       6  typedef _Complex float	float_complex;
       7  extern float_complex cfloat1 (void);
       8  extern float_complex cfloat2 (void);
       9  
      10  #define FLOAT_ARG(NAME, OP)	ARG_OP(float, float_complex, NAME, OP)
      11  #define FLOAT_PTR(NAME, OP)	PTR_OP(float, float_complex, NAME, OP)
      12  #define FLOAT_CALL()		CALL_OP(float, float_complex, cfloat1, cfloat2)
      13  
      14  #else
      15  #define FLOAT_ARG(NAME, OP)
      16  #define FLOAT_PTR(NAME, OP)
      17  #define FLOAT_CALL()
      18  #endif
      19  
      20  #ifndef NO_DOUBLE
      21  typedef _Complex double	double_complex;
      22  extern double_complex cdouble1 (void);
      23  extern double_complex cdouble2 (void);
      24  
      25  #define DOUBLE_ARG(NAME, OP)	ARG_OP(double, double_complex, NAME, OP)
      26  #define DOUBLE_PTR(NAME, OP)	PTR_OP(double, double_complex, NAME, OP)
      27  #define DOUBLE_CALL()		CALL_OP(double, double_complex, cdouble1, cdouble2)
      28  
      29  #else
      30  #define DOUBLE_ARG(NAME, OP)
      31  #define DOUBLE_PTR(NAME, OP)
      32  #define DOUBLE_CALL()
      33  #endif
      34  
      35  #ifndef NO_FLOAT128
      36  #ifdef __VSX__
      37  typedef _Complex float __attribute__((mode(KC)))	float128_complex;
      38  #else
      39  typedef _Complex float __attribute__((mode(TC)))	float128_complex;
      40  #endif
      41  
      42  extern float128_complex cfloat128_1 (void);
      43  extern float128_complex cfloat128_2 (void);
      44  
      45  #define FLOAT128_ARG(NAME, OP)	ARG_OP(float128, float128_complex, NAME, OP)
      46  #define FLOAT128_PTR(NAME, OP)	PTR_OP(float128, float128_complex, NAME, OP)
      47  #define FLOAT128_CALL()		CALL_OP(float128, float128_complex, cfloat128_1, cfloat128_2)
      48  
      49  #else
      50  #define FLOAT128_ARG(NAME, OP)
      51  #define FLOAT128_PTR(NAME, OP)
      52  #define FLOAT128_CALL()
      53  #endif
      54  
      55  #ifndef NO_LDOUBLE
      56  typedef _Complex long double ldouble_complex;
      57  extern ldouble_complex cldouble1 (void);
      58  extern ldouble_complex cldouble2 (void);
      59  
      60  #define LDOUBLE_ARG(NAME, OP)	ARG_OP(ldouble, ldouble_complex, NAME, OP)
      61  #define LDOUBLE_PTR(NAME, OP)	PTR_OP(ldouble, ldouble_complex, NAME, OP)
      62  #define LDOUBLE_CALL()		CALL_OP(ldouble, ldouble_complex, cldouble1, cldouble2)
      63  
      64  #else
      65  #define LDOUBLE_ARG(NAME, OP)
      66  #define LDOUBLE_PTR(NAME, OP)
      67  #define LDOUBLE_CALL()
      68  #endif
      69  
      70  
      71  #define ARG_OP(SUFFIX, TYPE, NAME, OP)					\
      72  TYPE arg_ ## NAME ## _ ## SUFFIX (TYPE a, TYPE b)			\
      73  {									\
      74    return a OP b;							\
      75  }
      76  
      77  #define PTR_OP(SUFFIX, TYPE, NAME, OP)					\
      78  void ptr_ ## NAME ## _ ## SUFFIX (TYPE *p, TYPE *a, TYPE *b)		\
      79  {									\
      80    *p = *a OP *b;							\
      81  }
      82  
      83  #define CALL_OP(SUFFIX, TYPE, FUNC1, FUNC2)				\
      84  TYPE call_ ## SUFFIX (void)						\
      85  {									\
      86    TYPE value1 = FUNC1 ();						\
      87    TYPE value2 = FUNC2 ();						\
      88    return value1 + value2;						\
      89  }
      90  
      91  #ifndef NO_ARG
      92  #ifndef NO_ADD
      93  FLOAT_ARG    (add, +)
      94  DOUBLE_ARG   (add, +)
      95  FLOAT128_ARG (add, +)
      96  LDOUBLE_ARG  (add, +)
      97  #endif
      98  
      99  #ifndef NO_SUB
     100  FLOAT_ARG    (sub, -)
     101  DOUBLE_ARG   (sub, -)
     102  FLOAT128_ARG (sub, -)
     103  LDOUBLE_ARG  (sub, -)
     104  #endif
     105  
     106  #ifndef NO_MUL
     107  FLOAT_ARG    (mul, *)
     108  DOUBLE_ARG   (mul, *)
     109  FLOAT128_ARG (mul, *)
     110  LDOUBLE_ARG  (mul, *)
     111  #endif
     112  
     113  #ifndef NO_DIV
     114  FLOAT_ARG    (div, /)
     115  DOUBLE_ARG   (div, /)
     116  FLOAT128_ARG (div, /)
     117  LDOUBLE_ARG  (div, /)
     118  #endif
     119  #endif
     120  
     121  #ifndef NO_PTR
     122  #ifndef NO_ADD
     123  FLOAT_PTR    (add, +)
     124  DOUBLE_PTR   (add, +)
     125  FLOAT128_PTR (add, +)
     126  LDOUBLE_PTR  (add, +)
     127  #endif
     128  
     129  #ifndef NO_SUB
     130  FLOAT_PTR    (sub, -)
     131  DOUBLE_PTR   (sub, -)
     132  FLOAT128_PTR (sub, -)
     133  LDOUBLE_PTR  (sub, -)
     134  #endif
     135  
     136  #ifndef NO_MUL
     137  FLOAT_PTR    (mul, *)
     138  DOUBLE_PTR   (mul, *)
     139  FLOAT128_PTR (mul, *)
     140  LDOUBLE_PTR  (mul, *)
     141  #endif
     142  
     143  #ifndef NO_DIV
     144  FLOAT_PTR    (div, /)
     145  DOUBLE_PTR   (div, /)
     146  FLOAT128_PTR (div, /)
     147  LDOUBLE_PTR  (div, /)
     148  #endif
     149  #endif
     150  
     151  #ifndef NO_CALL
     152  FLOAT_CALL    ()
     153  DOUBLE_CALL   ()
     154  FLOAT128_CALL ()
     155  LDOUBLE_CALL  ()
     156  #endif
     157  
     158  /* { dg-final { scan-assembler "xsaddqp"  } } */
     159  /* { dg-final { scan-assembler "xssubqp"  } } */