1#include <stdint.h>
2#include <stdio.h>
3
4typedef struct {
5   uint64_t high;
6   uint64_t low;
7} quad_word;
8
9void
10test(quad_word op1_init, uint64_t op2_init, quad_word op3_init)
11{
12   int cc; // unused
13   quad_word op1 = op1_init;
14   uint64_t  op2 = op2_init;
15   quad_word op3 = op3_init;
16
17   __asm__ volatile (
18                     "lmg     %%r0,%%r1,%1\n\t"
19                     "lmg     %%r2,%%r3,%3\n\t"
20                     "cds     %%r0,%%r2,%2\n\t"  //  cds 1st,3rd,2nd
21                     "stmg    %%r0,%%r1,%1\n"    // store r0,r1 to op1
22                     "stmg    %%r2,%%r3,%3\n"    // store r2,r3 to op3
23                     : "=d" (cc), "+QS" (op1), "+QS" (op2), "+QS" (op3)
24                     :
25                     : "r0", "r1", "r2", "r3", "cc");
26
27}
28
29// Return a quad-word that only bits low[32:63] are undefined
30quad_word
31make_undefined(void)
32{
33   quad_word val;
34
35   val.high = 0;
36   val.low |= 0xFFFFFFFF00000000ull;
37
38   return val;
39}
40
41void op1_undefined(void)
42{
43   quad_word op1, op3;
44   uint64_t op2;
45
46   // op1 undefined
47   op1 = make_undefined();
48   op2 = 42;
49   op3.high = op3.low = 0xdeadbeefdeadbabeull;
50   test(op1, op2, op3);  // complaint
51}
52
53void op2_undefined(void)
54{
55   quad_word op1, op3;
56   uint64_t op2;
57
58   op1.high = op1.low = 42;
59   // op2 undefined
60   op3.high = op3.low = 0xdeadbeefdeadbabeull;
61   test(op1, op2, op3);  // complaint
62}
63
64void op3_undefined(void)
65{
66   quad_word op1, op3;
67   uint64_t op2;
68
69   op1.high = op1.low = 42;
70   op2 = 100;
71   op3 = make_undefined();
72   test(op1, op2, op3);  // no complaint; op3 is just copied around
73}
74
75int main ()
76{
77   op1_undefined();
78   op2_undefined();
79   op3_undefined();
80
81   return 0;
82}
83