aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.target/powerpc/pr103109-2.c
blob: 4b93519ec6508ef02f63860c2181fe7c2f5dd8fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/* { dg-do run } */
/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
/* { dg-require-effective-target int128 } */
/* { dg-require-effective-target p9modulo_hw } */
/* { dg-require-effective-target has_arch_ppc64 } */

#include "pr103109.h"

union U {
  __int128 i128;
  struct {
    long l1;
    long l2;
  } s;
};

__int128
create_i128 (long most_sig, long least_sig)
{
  union U u;

#if __LITTLE_ENDIAN__
  u.s.l1 = least_sig;
  u.s.l2 = most_sig;
#else
  u.s.l1 = most_sig;
  u.s.l2 = least_sig;
#endif
  return u.i128;
}

#define DEBUG 0

#if DEBUG
#include <stdio.h>
#include <stdlib.h>

void print_i128(__int128 val, int unsignedp)
{
  if (unsignedp)
    printf(" %llu ", (unsigned long long)(val >> 64));
  else
    printf(" %lld ", (signed long long)(val >> 64));

  printf("%llu (0x%llx %llx)",
         (unsigned long long)(val & 0xFFFFFFFFFFFFFFFF),
         (unsigned long long)(val >> 64),
         (unsigned long long)(val & 0xFFFFFFFFFFFFFFFF));
}
#endif

void abort (void);

int main ()
{
  long a = 0xFEDCBA9876543210L;
  long b = 0x1000000L;
  long c = 0x123456L;
  __int128 expected_result = create_i128 (0xFFFFFFFFFFFEDCBAL,
                                          0x9876543210123456L);

  __int128 result = multiply_add (a, b, c);

  if (result != expected_result)
    {
#if DEBUG
      printf ("ERROR: multiply_add (%lld, %lld, %lld) = ", a, b, c);
      print_i128 (result, 0);
      printf ("\n does not match expected_result = ");
      print_i128 (expected_result, 0);
      printf ("\n\n");
#else
      abort();
#endif
    }

  unsigned long au = 0xFEDCBA9876543210UL;
  unsigned long bu = 0x1000000UL;
  unsigned long cu = 0x123456UL;
  unsigned __int128 expected_resultu = create_i128 (0x0000000000FEDCBAL,
                                                    0x9876543210123456L);

  unsigned __int128 resultu = multiply_addu (au, bu, cu);
  if (resultu != expected_resultu)
    {
#if DEBUG
      printf ("ERROR: multiply_addu (%llu, %llu, %llu) = ", au, bu, cu);
      print_i128 (resultu, 1);
      printf ("\n does not match expected_result = ");
      print_i128 (expected_resultu, 1);
      printf ("\n\n");
#else
      abort();
#endif
    }
}