There is an ABI change in how the PPC64 gcc compiler handles 128 bit arguments
are aligned with GCC 5.0.  The compiler generates a "note" about this starting
with GCC 4.9.  To avoid generating the "note", the passing of the arguments
were changed to a pointer to make it pass by reference rather then pass by 
value.

bugzilla 346487.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15136 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/NEWS b/NEWS
index 55ab227..9fdc795 100644
--- a/NEWS
+++ b/NEWS
@@ -164,6 +164,8 @@
 346416  Add support for LL_IOC_PATH2FID and LL_IOC_GETPARENT Lustre ioctls
 n-i-bz  Enable rt_sigpending syscall on ppc64 linux.
 346474  Added support for accessing the PPC64 TEXASRU register
+346487  Change PPC64 function calls with 128-bit values to use a pointer so
+        the compiler will not generate a note about an ABI change.
 
 
 Release 3.10.1 (25 November 2014)
diff --git a/none/tests/ppc32/test_dfp4.c b/none/tests/ppc32/test_dfp4.c
index ebd3963..54ffbb0 100644
--- a/none/tests/ppc32/test_dfp4.c
+++ b/none/tests/ppc32/test_dfp4.c
@@ -93,9 +93,9 @@
  * BF is the condition register bit field which can range from 0-7.  But for
  * testing purposes, we only use BF values of '0' and '5'.
  */
-static void _test_dtstdc(int BF, int DCM, dfp_val_t val1, dfp_val_t x1 __attribute__((unused)))
+static void _test_dtstdc(int BF, int DCM, dfp_val_t *val1, dfp_val_t *x1 __attribute__((unused)))
 {
-   _Decimal64 f14 = val1.dec_val;
+   _Decimal64 f14 = val1->dec_val;
    if (DCM < 0 || DCM > 5 || !(BF == 0 || BF == 5)) {
       fprintf(stderr, "Invalid inputs to asm test: a=%d, b=%d\n", BF, DCM);
       return;
@@ -142,9 +142,9 @@
    }
 }
 
-static void _test_dtstdcq(int BF, int DCM, dfp_val_t val1, dfp_val_t x1 __attribute__((unused)))
+static void _test_dtstdcq(int BF, int DCM, dfp_val_t *val1, dfp_val_t *x1 __attribute__((unused)))
 {
-   _Decimal128 f14 = val1.dec_val128;
+   _Decimal128 f14 = val1->dec_val128;
    if (DCM < 0 || DCM > 5 || !(BF == 0 || BF == 5)) {
       fprintf(stderr, "Invalid inputs to asm test: a=%d, b=%d\n", BF, DCM);
       return;
@@ -197,9 +197,9 @@
  * BF is the condition register bit field which can range from 0-7.  But for
  * testing purposes, we only use BF values of '0' and '5'.
  */
-static void _test_dtstdg(int BF, int DGM, dfp_val_t val1, dfp_val_t x1 __attribute__((unused)))
+static void _test_dtstdg(int BF, int DGM, dfp_val_t *val1, dfp_val_t *x1 __attribute__((unused)))
 {
-   _Decimal64 f14 = val1.dec_val;
+   _Decimal64 f14 = val1->dec_val;
    if (DGM < 0 || DGM > 5 || !(BF == 0 || BF == 5)) {
       fprintf(stderr, "Invalid inputs to asm test: a=%d, b=%d\n", BF, DGM);
       return;
@@ -246,9 +246,9 @@
    }
 }
 
-static void _test_dtstdgq(int BF, int DGM, dfp_val_t val1, dfp_val_t x1 __attribute__((unused)))
+static void _test_dtstdgq(int BF, int DGM, dfp_val_t *val1, dfp_val_t *x1 __attribute__((unused)))
 {
-   _Decimal128 f14 = val1.dec_val128;
+   _Decimal128 f14 = val1->dec_val128;
    if (DGM < 0 || DGM > 5 || !(BF == 0 || BF == 5)) {
       fprintf(stderr, "Invalid inputs to asm test: a=%d, b=%d\n", BF, DGM);
       return;
@@ -300,10 +300,10 @@
  * from 0-7, but for testing purposes, we only use BF values of '4' and '7'.
  */
 static void
-_test_dtstex(int BF, int x __attribute__((unused)), dfp_val_t val1, dfp_val_t val2)
+_test_dtstex(int BF, int x __attribute__((unused)), dfp_val_t *val1, dfp_val_t *val2)
 {
-   _Decimal64 f14 = val1.dec_val;
-   _Decimal64 f16 = val2.dec_val;
+   _Decimal64 f14 = val1->dec_val;
+   _Decimal64 f16 = val2->dec_val;
    if (!(BF == 4 || BF == 7)) {
       fprintf(stderr, "Invalid input to asm test: a=%d\n", BF);
       return;
@@ -320,10 +320,10 @@
    }
 }
 
-static void _test_dtstexq(int BF, int x __attribute__((unused)), dfp_val_t val1, dfp_val_t val2)
+static void _test_dtstexq(int BF, int x __attribute__((unused)), dfp_val_t *val1, dfp_val_t *val2)
 {
-   _Decimal128 f14 = val1.dec_val128;
-   _Decimal128 f16 = val2.dec_val128;
+   _Decimal128 f14 = val1->dec_val128;
+   _Decimal128 f16 = val2->dec_val128;
    if (!(BF == 4 || BF == 7)) {
       fprintf(stderr, "Invalid input to asm test: a=%d\n", BF);
       return;
@@ -342,7 +342,7 @@
 
 
 
-typedef void (*test_func_t)(int a, int b,  dfp_val_t val1,  dfp_val_t val2);
+typedef void (*test_funcp_t)(int a, int b,  dfp_val_t *val1,  dfp_val_t *val2);
 typedef void (*test_driver_func_t)(void);
 typedef struct test_table
 {
@@ -454,7 +454,7 @@
 
 typedef struct dfp_test
 {
-   test_func_t test_func;
+   test_funcp_t test_func;
    const char * name;
    dfp_test_args_t * targs;
    int num_tests;
@@ -464,7 +464,7 @@
 
 typedef struct dfp_one_arg_test
 {
-   test_func_t test_func;
+   test_funcp_t test_func;
    const char * name;
    precision_type_t precision;
    const char * op;
@@ -483,7 +483,7 @@
 
 static void test_dfp_ClassAndGroupTest_ops(void)
 {
-   test_func_t func;
+   test_funcp_t func;
    dfp_val_t test_val, dummy;
 
    int k = 0;
@@ -509,7 +509,13 @@
             unsigned int flags;
             SET_FPSCR_ZERO;
             SET_CR_XER_ZERO;
-            (*func)(BF, data_class_OR_group, test_val, dummy);
+
+	    /* There is an ABI change in how 128 bit arguments are aligned 
+             * with GCC 5.0.  The compiler generates a "note" about this
+             * starting with GCC 4.8.  To avoid generating the "note", pass
+             * the address of the 128-bit arguments rather then the value.
+	     */
+            (*func)(BF, data_class_OR_group, &test_val, &dummy);
             GET_CR(flags);
 
             condreg = ((flags >> (4 * (7-BF)))) & 0xf;
@@ -547,7 +553,7 @@
 static void test_dfp_ExpTest_ops(void)
 {
    dfp_val_t test_val1, test_val2;
-   test_func_t func;
+   test_funcp_t func;
    int k = 0;
 
    while ((func = dfp_ExpTest_tests[k].test_func)) {
@@ -577,7 +583,12 @@
 
          SET_FPSCR_ZERO;
          SET_CR_XER_ZERO;
-         (*func)(BF, 0, test_val1, test_val2);
+         /* There is an ABI change in how 128 bit arguments are aligned 
+          * with GCC 5.0.  The compiler generates a "note" about this
+          * starting with GCC 4.8.  To avoid generating the "note", pass
+          * the address of the 128-bit arguments rather then the value.
+          */
+         (*func)(BF, 0, &test_val1, &test_val2);
          GET_CR(flags);
 
          condreg = ((flags >> (4 * (7-BF)))) & 0xf;
diff --git a/none/tests/ppc32/test_dfp5.c b/none/tests/ppc32/test_dfp5.c
index d8122d8..b00573f 100644
--- a/none/tests/ppc32/test_dfp5.c
+++ b/none/tests/ppc32/test_dfp5.c
@@ -93,9 +93,9 @@
 enum BF_vals { BF_val1 = 0, BF_val2 = 1, BF_val3 =6};
 
 // The assembly-level instructions being tested
-static void _test_dtstsf(unsigned int BF, unsigned int ref_sig, dfp_val_t valB)
+static void _test_dtstsf(unsigned int BF, unsigned int ref_sig, dfp_val_t *valB)
 {
-   _Decimal64 f16 = valB.dec_val;
+   _Decimal64 f16 = valB->dec_val;
    register HWord_t r14 __asm__ ("r14");
    double f14;
    r14 = (HWord_t)&ref_sig;
@@ -117,9 +117,9 @@
    }
 }
 
-static void _test_dtstsfq(unsigned int BF, unsigned int ref_sig, dfp_val_t valB)
+static void _test_dtstsfq(unsigned int BF, unsigned int ref_sig, dfp_val_t *valB)
 {
-   _Decimal128 f16 = valB.dec_val128;
+   _Decimal128 f16 = valB->dec_val128;
    register HWord_t r14 __asm__ ("r14");
    double f14;
    r14 = (HWord_t)&ref_sig;
@@ -141,11 +141,11 @@
    }
 }
 
-static dfp_val_t _test_ddedpd(unsigned int SP, dfp_val_t valB)
+static dfp_val_t _test_ddedpd(unsigned int SP, dfp_val_t *valB)
 {
    _Decimal64 ret = 0;
    dfp_val_t result;
-   _Decimal64 f16 = valB.dec_val;
+   _Decimal64 f16 = valB->dec_val;
    switch (SP) {
       case 0:
          __asm__ __volatile__ ("ddedpd. 0, %0, %1" : "=f" (ret) : "f" (f16));
@@ -168,11 +168,11 @@
 }
 
 
-static dfp_val_t _test_ddedpdq(unsigned int SP, dfp_val_t valB)
+static dfp_val_t _test_ddedpdq(unsigned int SP, dfp_val_t *valB)
 {
    _Decimal128 ret = 0;
    dfp_val_t result;
-   _Decimal128 f16 = valB.dec_val128;
+   _Decimal128 f16 = valB->dec_val128;
    switch (SP) {
       case 0:
          __asm__ __volatile__ ("ddedpdq 0, %0, %1" : "=f" (ret) : "f" (f16));
@@ -194,11 +194,11 @@
    return result;
 }
 
-static dfp_val_t _test_denbcd(unsigned int S, dfp_val_t valB)
+static dfp_val_t _test_denbcd(unsigned int S, dfp_val_t *valB)
 {
    _Decimal64 ret = 0;
    dfp_val_t result;
-   _Decimal64 f16 = valB.dec_val;
+   _Decimal64 f16 = valB->dec_val;
    switch (S) {
       case 0:
          __asm__ __volatile__ ("denbcd. 0, %0, %1" : "=f" (ret) : "f" (f16));
@@ -215,11 +215,11 @@
 }
 
 
-static dfp_val_t _test_denbcdq(unsigned int S, dfp_val_t valB)
+static dfp_val_t _test_denbcdq(unsigned int S, dfp_val_t *valB)
 {
    _Decimal128 ret = 0;
    dfp_val_t result;
-   _Decimal128 f16 = valB.dec_val128;
+   _Decimal128 f16 = valB->dec_val128;
    switch (S) {
       case 0:
          __asm__ __volatile__ ("denbcdq 0, %0, %1" : "=f" (ret) : "f" (f16));
@@ -236,8 +236,8 @@
 }
 
 
-typedef void (*test_func_t)(unsigned int imm, unsigned int imm2,  dfp_val_t valB);
-typedef dfp_val_t (*test_func_bcd_t)(unsigned int imm, dfp_val_t valB);
+typedef void (*test_funcp_t)(unsigned int imm, unsigned int imm2,  dfp_val_t *valB);
+typedef dfp_val_t (*test_func_bcdp_t)(unsigned int imm, dfp_val_t *valB);
 typedef void (*test_driver_func_t)(void);
 typedef struct test_table
 {
@@ -384,7 +384,7 @@
 
 typedef struct dfp_one_arg_test
 {
-   test_func_t test_func;
+   test_funcp_t test_func;
    const char * name;
    precision_type_t precision;
    const char * op;
@@ -392,7 +392,7 @@
 
 typedef struct dfp_one_arg_bcd_test
 {
-   test_func_bcd_t test_func;
+   test_func_bcdp_t test_func;
    const char * name;
    precision_type_t precision;
    const char * op;
@@ -407,7 +407,7 @@
 
 static void test_dfp_ddedpd_ops(void)
 {
-   test_func_bcd_t func;
+   test_func_bcdp_t func;
    dfp_val_t test_val;
 
    int k = 0;
@@ -428,7 +428,13 @@
 
          for (SP = 0; SP < 4; SP++) {
             dfp_val_t result;
-            result = (*func)(SP, test_val);
+
+	    /* There is an ABI change in how 128 bit arguments are aligned 
+             * with GCC 5.0.  The compiler generates a "note" about this
+             * starting with GCC 4.8.  To avoid generating the "note", pass
+             * the address of the 128-bit arguments rather then the value.
+	     */
+            result = (*func)(SP, &test_val);
             printf("%s (SP=%d) %s", test_def.name, SP, test_def.op);
             if (test_def.precision == LONG_TEST) {
                printf("%016llx ==> %016llx\n", test_val.u64_val, result.u64_val);
@@ -453,7 +459,7 @@
 
 static void test_dfp_denbcd_ops(void)
 {
-   test_func_bcd_t func;
+   test_func_bcdp_t func;
    dfp_val_t test_val;
    int num_test_vals;
 
@@ -490,7 +496,12 @@
                test_val.u128.vall = bcd128_vals[(i * 2) + 1];
             }
 
-            result = (*func)(S, test_val);
+	    /* There is an API change in how 128 bit arguments are aligned 
+             * with GCC 5.0.  The compiler generates a "note" about this
+             * starting with GCC 4.8.  To avoid generating the "note", pass
+             * the address of the 128-bit arguments rather then the value.
+	     */
+            result = (*func)(S, &test_val);
             printf("%s (S=%d) %s", test_def.name, S, test_def.op);
             if (test_def.precision == LONG_TEST) {
                printf("%016llx ==> %016llx\n", test_val.u64_val, result.u64_val);
@@ -516,7 +527,7 @@
 
 static void test_dfp_test_significance_ops(void)
 {
-   test_func_t func;
+   test_funcp_t func;
    dfp_val_t test_valB;
    int k = 0;
    unsigned int BF_vals[] = {BF_val1, BF_val2, BF_val3};
@@ -545,7 +556,12 @@
                BF = BF_vals[bf_idx];
                SET_FPSCR_ZERO;
                SET_CR_XER_ZERO;
-               (*func)(BF, reference_sig, test_valB);
+               /* There is an ABI change in how 128 bit arguments are aligned 
+                * with GCC 5.0.  The compiler generates a "note" about this
+                * starting with GCC 4.9.  To avoid generating the "note", pass
+                * the address of the 128-bit arguments rather then the value.
+                */
+               (*func)(BF, reference_sig, &test_valB);
                GET_CR(flags);
 
                condreg = ((flags >> (4 * (7-BF)))) & 0xf;