(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
powerpc/
ppc64-abi-dfp-1.c
       1  /* { dg-do run { target { powerpc64-*-* && { lp64 && dfprt } } } } */
       2  /* { dg-skip-if "" { powerpc*-*-darwin* } } */
       3  /* { dg-options "-std=gnu99 -O2 -fno-strict-aliasing" } */
       4  
       5  /* Testcase to check for ABI compliance of parameter passing
       6     for the PowerPC64 ELF ABI for decimal float values.  */
       7  
       8  extern void abort (void);
       9  int failcnt = 0;
      10  
      11  /* Support compiling the test to report individual failures; default is
      12     to abort as soon as a check fails.  */
      13  #ifdef DBG
      14  #include <stdio.h>
      15  #define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
      16  #else
      17  #define FAILURE abort ();
      18  #endif
      19  
      20  typedef struct
      21  {
      22    int pad;
      23    _Decimal32 d;
      24  } d32parm_t;
      25  
      26  typedef struct
      27  {
      28    unsigned long gprs[8];
      29    double fprs[13];
      30  } reg_parms_t;
      31  
      32  reg_parms_t gparms;
      33  
      34  
      35  /* Wrapper to save the GPRs and FPRs and then jump to the real function.  */
      36  #if _CALL_ELF != 2
      37  #define FUNC_START(NAME)						\
      38  	"\t.globl\t" NAME "\n\t"					\
      39           ".section \".opd\",\"aw\"\n\t"					\
      40           ".align 3\n"							\
      41           NAME ":\n\t"							\
      42           ".quad .L." NAME ",.TOC.@tocbase,0\n\t"			\
      43           ".text\n\t"							\
      44           ".type " NAME ", @function\n"					\
      45           ".L." NAME ":\n\t"
      46  #else
      47  #define FUNC_START(NAME)						\
      48  	"\t.globl\t" NAME "\n\t"					\
      49           ".text\n\t"							\
      50           NAME ":\n"							\
      51  	"0:\taddis 2,12,(.TOC.-0b)@ha\n\t"				\
      52  	"addi 2,2,(.TOC.-0b)@l\n\t"					\
      53  	".localentry " NAME ",.-" NAME "\n\t"
      54  #endif
      55  #define WRAPPER(NAME)							\
      56  __asm__ (FUNC_START (#NAME "_asm")					\
      57  	 "ld 11,gparms@got(2)\n\t"					\
      58  	 "std 3,0(11)\n\t"						\
      59  	 "std 4,8(11)\n\t"						\
      60  	 "std 5,16(11)\n\t"						\
      61  	 "std 6,24(11)\n\t"						\
      62  	 "std 7,32(11)\n\t"						\
      63  	 "std 8,40(11)\n\t"						\
      64  	 "std 9,48(11)\n\t"						\
      65  	 "std 10,56(11)\n\t"						\
      66  	 "stfd 1,64(11)\n\t"						\
      67  	 "stfd 2,72(11)\n\t"						\
      68  	 "stfd 3,80(11)\n\t"						\
      69  	 "stfd 4,88(11)\n\t"						\
      70  	 "stfd 5,96(11)\n\t"						\
      71  	 "stfd 6,104(11)\n\t"						\
      72  	 "stfd 7,112(11)\n\t"						\
      73  	 "stfd 8,120(11)\n\t"						\
      74  	 "stfd 9,128(11)\n\t"						\
      75  	 "stfd 10,136(11)\n\t"						\
      76  	 "stfd 11,144(11)\n\t"						\
      77  	 "stfd 12,152(11)\n\t"						\
      78  	 "stfd 13,160(11)\n\t"						\
      79  	 "b " #NAME "\n\t"						\
      80  	 ".long 0\n\t"							\
      81  	 ".byte 0,0,0,0,0,0,0,0\n\t"					\
      82  	 ".size " #NAME ",.-" #NAME "\n")
      83  
      84  typedef struct sf
      85  {
      86    struct sf *backchain;
      87    long a1;
      88    long a2;
      89    long a3;
      90  #if _CALL_ELF != 2
      91    long a4;
      92    long a5;
      93  #endif
      94    unsigned long slot[100];
      95  } stack_frame_t;
      96  
      97  extern void func0_asm (double, double, double, double, double, double,
      98  		       double, double, double, double, double, double,
      99  		       double, double, 
     100  		       _Decimal64, _Decimal128, _Decimal64);
     101  
     102  WRAPPER(func0);
     103  
     104  /* Fill up floating point registers with double arguments, forcing
     105     decimal float arguments into the parameter save area.  */
     106  void __attribute__ ((noinline))
     107  func0 (double a1, double a2, double a3, double a4, double a5, double a6,
     108         double a7, double a8, double a9, double a10, double a11, double a12,
     109         double a13, double a14, 
     110         _Decimal64 a15, _Decimal128 a16, _Decimal64 a17)
     111  {
     112    stack_frame_t *sp;
     113  
     114    sp = __builtin_frame_address (0);
     115    sp = sp->backchain;
     116  
     117    if (a1 != gparms.fprs[0]) FAILURE
     118    if (a2 != gparms.fprs[1]) FAILURE
     119    if (a3 != gparms.fprs[2]) FAILURE
     120    if (a4 != gparms.fprs[3]) FAILURE
     121    if (a5 != gparms.fprs[4]) FAILURE
     122    if (a6 != gparms.fprs[5]) FAILURE
     123    if (a7 != gparms.fprs[6]) FAILURE
     124    if (a8 != gparms.fprs[7]) FAILURE
     125    if (a9 != gparms.fprs[8]) FAILURE
     126    if (a10 != gparms.fprs[9]) FAILURE
     127    if (a11 != gparms.fprs[10]) FAILURE
     128    if (a12 != gparms.fprs[11]) FAILURE
     129    if (a13 != gparms.fprs[12]) FAILURE
     130    if (a14 != *(double *)&sp->slot[13]) FAILURE
     131    if (a15 != *(_Decimal64 *)&sp->slot[14]) FAILURE
     132    if (a16 != *(_Decimal128 *)&sp->slot[15]) FAILURE
     133    if (a17 != *(_Decimal64 *)&sp->slot[17]) FAILURE
     134  }
     135  
     136  extern void func1_asm (double, double, double, double, double, double,
     137  		       double, double, double, double, double, double,
     138  		       double, _Decimal128 );
     139  
     140  WRAPPER(func1);
     141  
     142  void __attribute__ ((noinline))
     143  func1 (double a1, double a2, double a3, double a4, double a5, double a6,
     144         double a7, double a8, double a9, double a10, double a11, double a12,
     145         double a13, _Decimal128 a14)
     146  {
     147    stack_frame_t *sp;
     148  
     149    sp = __builtin_frame_address (0);
     150    sp = sp->backchain;
     151  
     152    if (a1 != gparms.fprs[0]) FAILURE
     153    if (a2 != gparms.fprs[1]) FAILURE
     154    if (a3 != gparms.fprs[2]) FAILURE
     155    if (a4 != gparms.fprs[3]) FAILURE
     156    if (a5 != gparms.fprs[4]) FAILURE
     157    if (a6 != gparms.fprs[5]) FAILURE
     158    if (a7 != gparms.fprs[6]) FAILURE
     159    if (a8 != gparms.fprs[7]) FAILURE
     160    if (a9 != gparms.fprs[8]) FAILURE
     161    if (a10 != gparms.fprs[9]) FAILURE
     162    if (a11 != gparms.fprs[10]) FAILURE
     163    if (a12 != gparms.fprs[11]) FAILURE
     164    if (a13 != gparms.fprs[12]) FAILURE
     165    if (a14 != *(_Decimal128 *)&sp->slot[13]) FAILURE
     166  }
     167  
     168  extern void func2_asm (double, double, double, double, double, double,
     169  		       double, double, double, double, double, double,
     170  		       _Decimal128);
     171  
     172  WRAPPER(func2);
     173  
     174  void __attribute__ ((noinline))
     175  func2 (double a1, double a2, double a3, double a4, double a5, double a6,
     176         double a7, double a8, double a9, double a10, double a11, double a12,
     177         _Decimal128 a13)
     178  {
     179    stack_frame_t *sp;
     180  
     181    sp = __builtin_frame_address (0);
     182    sp = sp->backchain;
     183  
     184    if (a1 != gparms.fprs[0]) FAILURE
     185    if (a2 != gparms.fprs[1]) FAILURE
     186    if (a3 != gparms.fprs[2]) FAILURE
     187    if (a4 != gparms.fprs[3]) FAILURE
     188    if (a5 != gparms.fprs[4]) FAILURE
     189    if (a6 != gparms.fprs[5]) FAILURE
     190    if (a7 != gparms.fprs[6]) FAILURE
     191    if (a8 != gparms.fprs[7]) FAILURE
     192    if (a9 != gparms.fprs[8]) FAILURE
     193    if (a10 != gparms.fprs[9]) FAILURE
     194    if (a11 != gparms.fprs[10]) FAILURE
     195    if (a12 != gparms.fprs[11]) FAILURE
     196    if (a13 != *(_Decimal128 *)&sp->slot[12]) FAILURE
     197  }
     198  
     199  extern void func3_asm (_Decimal64, _Decimal128, _Decimal64, _Decimal128,
     200  		       _Decimal64, _Decimal128, _Decimal64, _Decimal128,
     201  		       _Decimal64, _Decimal128);
     202  
     203  WRAPPER(func3);
     204  
     205  void __attribute__ ((noinline))
     206  func3 (_Decimal64 a1, _Decimal128 a2, _Decimal64 a3, _Decimal128 a4,
     207         _Decimal64 a5, _Decimal128 a6, _Decimal64 a7, _Decimal128 a8,
     208         _Decimal64 a9, _Decimal128 a10)
     209  {
     210    stack_frame_t *sp;
     211  
     212    sp = __builtin_frame_address (0);
     213    sp = sp->backchain;
     214  
     215    if (a1 != *(_Decimal64 *)&gparms.fprs[0]) FAILURE	/* f1        */
     216    if (a2 != *(_Decimal128 *)&gparms.fprs[1]) FAILURE	/* f2 & f3   */
     217    if (a3 != *(_Decimal64 *)&gparms.fprs[3]) FAILURE	/* f4        */
     218    if (a4 != *(_Decimal128 *)&gparms.fprs[5]) FAILURE	/* f6 & f7   */
     219    if (a5 != *(_Decimal64 *)&gparms.fprs[7]) FAILURE	/* f8        */
     220    if (a6 != *(_Decimal128 *)&gparms.fprs[9]) FAILURE	/* f10 & f11 */
     221    if (a7 != *(_Decimal64 *)&gparms.fprs[11]) FAILURE	/* f12       */
     222    if (a8 != *(_Decimal128 *)&sp->slot[10]) FAILURE
     223    if (a9 != *(_Decimal64 *)&sp->slot[12]) FAILURE
     224    if (a10 != *(_Decimal128 *)&sp->slot[13]) FAILURE
     225  }
     226  
     227  extern void func4_asm (_Decimal128, _Decimal64, _Decimal128, _Decimal64,
     228  		       _Decimal128, _Decimal64, _Decimal128, _Decimal64);
     229  
     230  WRAPPER(func4);
     231  
     232  void __attribute__ ((noinline))
     233  func4 (_Decimal128 a1, _Decimal64 a2, _Decimal128 a3, _Decimal64 a4,
     234         _Decimal128 a5, _Decimal64 a6, _Decimal128 a7, _Decimal64 a8)
     235  {
     236    stack_frame_t *sp;
     237  
     238    sp = __builtin_frame_address (0);
     239    sp = sp->backchain;
     240  
     241    if (a1 != *(_Decimal128 *)&gparms.fprs[1]) FAILURE	/* f2 & f3   */
     242    if (a2 != *(_Decimal64 *)&gparms.fprs[3]) FAILURE	/* f4        */
     243    if (a3 != *(_Decimal128 *)&gparms.fprs[5]) FAILURE	/* f6 & f7   */
     244    if (a4 != *(_Decimal64 *)&gparms.fprs[7]) FAILURE	/* f8        */
     245    if (a5 != *(_Decimal128 *)&gparms.fprs[9]) FAILURE	/* f10 & f11 */
     246    if (a6 != *(_Decimal64 *)&gparms.fprs[11]) FAILURE	/* f12       */
     247    if (a7 != *(_Decimal128 *)&sp->slot[9]) FAILURE
     248    if (a8 != *(_Decimal64 *)&sp->slot[11]) FAILURE
     249  }
     250  
     251  extern void func5_asm (_Decimal32, _Decimal32, _Decimal32, _Decimal32,
     252  		       _Decimal32, _Decimal32, _Decimal32, _Decimal32,
     253  		       _Decimal32, _Decimal32, _Decimal32, _Decimal32,
     254  		       _Decimal32, _Decimal32, _Decimal32, _Decimal32);
     255  
     256  WRAPPER(func5);
     257  
     258  void __attribute__ ((noinline))
     259  func5 (_Decimal32 a1, _Decimal32 a2, _Decimal32 a3, _Decimal32 a4,
     260         _Decimal32 a5, _Decimal32 a6, _Decimal32 a7, _Decimal32 a8,
     261         _Decimal32 a9, _Decimal32 a10, _Decimal32 a11, _Decimal32 a12,
     262         _Decimal32 a13, _Decimal32 a14, _Decimal32 a15, _Decimal32 a16)
     263  {
     264    stack_frame_t *sp;
     265  
     266    sp = __builtin_frame_address (0);
     267    sp = sp->backchain;
     268  
     269    /* _Decimal32 is passed in the lower half of an FPR or parameter slot.  */
     270    if (a1 != ((d32parm_t *)&gparms.fprs[0])->d) FAILURE		/* f1  */
     271    if (a2 != ((d32parm_t *)&gparms.fprs[1])->d) FAILURE		/* f2  */
     272    if (a3 != ((d32parm_t *)&gparms.fprs[2])->d) FAILURE		/* f3  */
     273    if (a4 != ((d32parm_t *)&gparms.fprs[3])->d) FAILURE		/* f4  */
     274    if (a5 != ((d32parm_t *)&gparms.fprs[4])->d) FAILURE		/* f5  */
     275    if (a6 != ((d32parm_t *)&gparms.fprs[5])->d) FAILURE		/* f6  */
     276    if (a7 != ((d32parm_t *)&gparms.fprs[6])->d) FAILURE		/* f7  */
     277    if (a8 != ((d32parm_t *)&gparms.fprs[7])->d) FAILURE		/* f8  */
     278    if (a9 != ((d32parm_t *)&gparms.fprs[8])->d) FAILURE		/* f9  */
     279    if (a10 != ((d32parm_t *)&gparms.fprs[9])->d) FAILURE		/* f10 */
     280    if (a11 != ((d32parm_t *)&gparms.fprs[10])->d) FAILURE	/* f11 */
     281    if (a12 != ((d32parm_t *)&gparms.fprs[11])->d) FAILURE	/* f12 */
     282    if (a13 != ((d32parm_t *)&gparms.fprs[12])->d) FAILURE	/* f13 */
     283    if (a14 != ((d32parm_t *)&sp->slot[13])->d) FAILURE
     284    if (a15 != ((d32parm_t *)&sp->slot[14])->d) FAILURE
     285    if (a16 != ((d32parm_t *)&sp->slot[15])->d) FAILURE
     286  }
     287  
     288  extern void func6_asm (_Decimal32, _Decimal64, _Decimal128,
     289  		       _Decimal32, _Decimal64, _Decimal128,
     290  		       _Decimal32, _Decimal64, _Decimal128,
     291  		       _Decimal32, _Decimal64, _Decimal128);
     292  
     293  WRAPPER(func6);
     294  
     295  void __attribute__ ((noinline))
     296  func6 (_Decimal32 a1, _Decimal64 a2, _Decimal128 a3,
     297         _Decimal32 a4, _Decimal64 a5, _Decimal128 a6,
     298         _Decimal32 a7, _Decimal64 a8, _Decimal128 a9,
     299         _Decimal32 a10, _Decimal64 a11, _Decimal128 a12)
     300  {
     301    stack_frame_t *sp;
     302  
     303    sp = __builtin_frame_address (0);
     304    sp = sp->backchain;
     305  
     306    if (a1 != ((d32parm_t *)&gparms.fprs[0])->d) FAILURE		/* f1        */
     307    if (a2 != *(_Decimal64 *)&gparms.fprs[1]) FAILURE		/* f2        */
     308    if (a3 != *(_Decimal128 *)&gparms.fprs[3]) FAILURE		/* f4 & f5   */
     309    if (a4 != ((d32parm_t *)&gparms.fprs[5])->d) FAILURE		/* f6        */
     310    if (a5 != *(_Decimal64 *)&gparms.fprs[6]) FAILURE		/* f7        */
     311    if (a6 != *(_Decimal128 *)&gparms.fprs[7]) FAILURE		/* f8 & f9   */
     312    if (a7 != ((d32parm_t *)&gparms.fprs[9])->d) FAILURE		/* f10       */
     313    if (a8 != *(_Decimal64 *)&gparms.fprs[10]) FAILURE		/* f11       */
     314    if (a9 != *(_Decimal128 *)&gparms.fprs[11]) FAILURE		/* f12 & f13 */
     315    if (a10 != ((d32parm_t *)&sp->slot[12])->d) FAILURE
     316    if (a11 != *(_Decimal64 *)&sp->slot[13]) FAILURE
     317  }
     318  
     319  int
     320  main (void)
     321  {
     322    func0_asm (1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, 11.5, 12.5, 13.5,
     323  	     14.5, 15.2dd, 16.2dl, 17.2dd);
     324    func1_asm (101.5, 102.5, 103.5, 104.5, 105.5, 106.5, 107.5, 108.5, 109.5,
     325  	     110.5, 111.5, 112.5, 113.5, 114.2dd);
     326    func2_asm (201.5, 202.5, 203.5, 204.5, 205.5, 206.5, 207.5, 208.5, 209.5,
     327  	     210.5, 211.5, 212.5, 213.2dd);
     328    func3_asm (301.2dd, 302.2dl, 303.2dd, 304.2dl, 305.2dd, 306.2dl, 307.2dd,
     329  	     308.2dl, 309.2dd, 310.2dl);
     330    func4_asm (401.2dl, 402.2dd, 403.2dl, 404.2dd, 405.2dl, 406.2dd, 407.2dl,
     331  	     408.2dd);
     332  #if 0
     333    /* _Decimal32 doesn't yet follow the ABI; enable this when it does.  */
     334    func5_asm (501.2df, 502.2df, 503.2df, 504.2df, 505.2df, 506.2df, 507.2df,
     335  	     508.2df, 509.2df, 510.2df, 511.2df, 512.2df, 513.2df, 514.2df,
     336  	     515.2df, 516.2df);
     337    func6_asm (601.2df, 602.2dd, 603.2dl, 604.2df, 605.2dd, 606.2dl,
     338  	     607.2df, 608.2dd, 609.2dl, 610.2df, 611.2dd, 612.2dl);
     339  #endif
     340  
     341    if (failcnt != 0)
     342      abort ();
     343  
     344    return 0;
     345  }