1 /* This testcase is part of GDB, the GNU debugger.
2 
3    Copyright 2017-2020 Free Software Foundation, Inc.
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9 
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17 
18 #include <stdint.h>
19 #include <assert.h>
20 
21 static int again;
22 
23 static volatile struct
24 {
25   uint64_t alignment;
26   union
27     {
28       uint64_t size8[1];
29       uint32_t size4[2];
30       uint16_t size2[4];
31       uint8_t size1[8];
32       uint64_t size8twice[2];
33     }
34   u;
35 } data;
36 
37 static int size = 0;
38 static int offset;
39 
40 static void
write_size8twice(void)41 write_size8twice (void)
42 {
43   static const uint64_t first = 1;
44   static const uint64_t second = 2;
45 
46 #ifdef __aarch64__
47   asm volatile ("stp %1, %2, [%0]"
48 		: /* output */
49 		: "r" (data.u.size8twice), "r" (first), "r" (second) /* input */
50 		: "memory" /* clobber */);
51 #else
52   data.u.size8twice[0] = first;
53   data.u.size8twice[1] = second;
54 #endif
55 }
56 
57 int
main(void)58 main (void)
59 {
60   volatile uint64_t local;
61 
62   assert (sizeof (data) == 8 + 2 * 8);
63 
64   write_size8twice ();
65 
66   while (size)
67     {
68       switch (size)
69 	{
70 /* __s390x__ also defines __s390__ */
71 #ifdef __s390__
72 # define ACCESS(var) var = ~var
73 #else
74 # define ACCESS(var) local = var
75 #endif
76 	case 8:
77 	  ACCESS (data.u.size8[offset]);
78 	  break;
79 	case 4:
80 	  ACCESS (data.u.size4[offset]);
81 	  break;
82 	case 2:
83 	  ACCESS (data.u.size2[offset]);
84 	  break;
85 	case 1:
86 	  ACCESS (data.u.size1[offset]);
87 	  break;
88 #undef ACCESS
89 	default:
90 	  assert (0);
91 	}
92       size = 0;
93       size = size; /* start_again */
94     }
95   return 0; /* final_return */
96 }
97