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