1 #include <stdint.h>
2 #include <stdio.h>
3
4 typedef struct {
5 uint64_t high;
6 uint64_t low;
7 } quad_word;
8
9 void
test(quad_word op1_init,uint64_t op2_init,quad_word op3_init)10 test(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
30 quad_word
make_undefined(void)31 make_undefined(void)
32 {
33 quad_word val;
34
35 val.high = 0;
36 val.low |= 0xFFFFFFFF00000000ull;
37
38 return val;
39 }
40
op1_undefined(void)41 void 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
op2_undefined(void)53 void 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
op3_undefined(void)64 void 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
main()75 int main ()
76 {
77 op1_undefined();
78 op2_undefined();
79 op3_undefined();
80
81 return 0;
82 }
83