13aed4a8bSchristos /* This testcase is part of GDB, the GNU debugger.
23aed4a8bSchristos 
3*56bb7041Schristos    Copyright 2017-2020 Free Software Foundation, Inc.
43aed4a8bSchristos 
53aed4a8bSchristos    This program is free software; you can redistribute it and/or modify
63aed4a8bSchristos    it under the terms of the GNU General Public License as published by
73aed4a8bSchristos    the Free Software Foundation; either version 3 of the License, or
83aed4a8bSchristos    (at your option) any later version.
93aed4a8bSchristos 
103aed4a8bSchristos    This program is distributed in the hope that it will be useful,
113aed4a8bSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
123aed4a8bSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
133aed4a8bSchristos    GNU General Public License for more details.
143aed4a8bSchristos 
153aed4a8bSchristos    You should have received a copy of the GNU General Public License
163aed4a8bSchristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
173aed4a8bSchristos 
183aed4a8bSchristos #include <stdint.h>
193aed4a8bSchristos #include <assert.h>
203aed4a8bSchristos 
213aed4a8bSchristos static int again;
223aed4a8bSchristos 
233aed4a8bSchristos static volatile struct
243aed4a8bSchristos {
253aed4a8bSchristos   uint64_t alignment;
263aed4a8bSchristos   union
273aed4a8bSchristos     {
283aed4a8bSchristos       uint64_t size8[1];
293aed4a8bSchristos       uint32_t size4[2];
303aed4a8bSchristos       uint16_t size2[4];
313aed4a8bSchristos       uint8_t size1[8];
323aed4a8bSchristos       uint64_t size8twice[2];
333aed4a8bSchristos     }
343aed4a8bSchristos   u;
353aed4a8bSchristos } data;
363aed4a8bSchristos 
373aed4a8bSchristos static int size = 0;
383aed4a8bSchristos static int offset;
393aed4a8bSchristos 
403aed4a8bSchristos static void
write_size8twice(void)413aed4a8bSchristos write_size8twice (void)
423aed4a8bSchristos {
433aed4a8bSchristos   static const uint64_t first = 1;
443aed4a8bSchristos   static const uint64_t second = 2;
453aed4a8bSchristos 
463aed4a8bSchristos #ifdef __aarch64__
473aed4a8bSchristos   asm volatile ("stp %1, %2, [%0]"
483aed4a8bSchristos 		: /* output */
493aed4a8bSchristos 		: "r" (data.u.size8twice), "r" (first), "r" (second) /* input */
503aed4a8bSchristos 		: "memory" /* clobber */);
513aed4a8bSchristos #else
523aed4a8bSchristos   data.u.size8twice[0] = first;
533aed4a8bSchristos   data.u.size8twice[1] = second;
543aed4a8bSchristos #endif
553aed4a8bSchristos }
563aed4a8bSchristos 
573aed4a8bSchristos int
main(void)583aed4a8bSchristos main (void)
593aed4a8bSchristos {
603aed4a8bSchristos   volatile uint64_t local;
613aed4a8bSchristos 
623aed4a8bSchristos   assert (sizeof (data) == 8 + 2 * 8);
633aed4a8bSchristos 
643aed4a8bSchristos   write_size8twice ();
653aed4a8bSchristos 
663aed4a8bSchristos   while (size)
673aed4a8bSchristos     {
683aed4a8bSchristos       switch (size)
693aed4a8bSchristos 	{
703aed4a8bSchristos /* __s390x__ also defines __s390__ */
713aed4a8bSchristos #ifdef __s390__
723aed4a8bSchristos # define ACCESS(var) var = ~var
733aed4a8bSchristos #else
743aed4a8bSchristos # define ACCESS(var) local = var
753aed4a8bSchristos #endif
763aed4a8bSchristos 	case 8:
773aed4a8bSchristos 	  ACCESS (data.u.size8[offset]);
783aed4a8bSchristos 	  break;
793aed4a8bSchristos 	case 4:
803aed4a8bSchristos 	  ACCESS (data.u.size4[offset]);
813aed4a8bSchristos 	  break;
823aed4a8bSchristos 	case 2:
833aed4a8bSchristos 	  ACCESS (data.u.size2[offset]);
843aed4a8bSchristos 	  break;
853aed4a8bSchristos 	case 1:
863aed4a8bSchristos 	  ACCESS (data.u.size1[offset]);
873aed4a8bSchristos 	  break;
883aed4a8bSchristos #undef ACCESS
893aed4a8bSchristos 	default:
903aed4a8bSchristos 	  assert (0);
913aed4a8bSchristos 	}
923aed4a8bSchristos       size = 0;
933aed4a8bSchristos       size = size; /* start_again */
943aed4a8bSchristos     }
953aed4a8bSchristos   return 0; /* final_return */
963aed4a8bSchristos }
97