1 /* This checks the availability of the low-level builtins introduced
2    for transactional execution.  */
3 
4 /* { dg-do compile } */
5 /* { dg-options "-O3 -march=zEC12 -mzarch" } */
6 
7 #include <stdint.h>
8 #include <htmintrin.h>
9 
10 int global = 0;
11 uint64_t g;
12 struct __htm_tdb global_tdb;
13 
14 int
foo(struct __htm_tdb * tdb,int reg,int * mem,uint64_t * mem64)15 foo (struct __htm_tdb* tdb, int reg, int *mem, uint64_t *mem64)
16 {
17 
18   int cc;
19   int n;
20 
21   __builtin_tbegin ((void *)0);
22   __builtin_tbegin ((void *)-99999);
23   __builtin_tbegin ((void *)99999);
24   while (__builtin_tbegin ((void *)0) != 0)
25   {
26   }
27   cc = __builtin_tbegin ((void *)0x12345678);
28   cc = __builtin_tbegin (tdb);
29   cc = __builtin_tbegin (&global_tdb);
30   cc = __builtin_tbegin ((void *)(long)(reg + 0x12345678));
31   cc = __builtin_tbegin ((void *)(long)(reg));
32 
33   __builtin_tbegin_nofloat ((void *)0);
34   __builtin_tbegin_nofloat ((void *)-99999);
35   __builtin_tbegin_nofloat ((void *)99999);
36   cc = __builtin_tbegin_nofloat ((void *)0x12345678);
37   cc = __builtin_tbegin_nofloat (tdb);
38   cc = __builtin_tbegin_nofloat (&global_tdb);
39   cc = __builtin_tbegin_nofloat ((void *)(long)(reg + 0x12345678));
40   cc = __builtin_tbegin_nofloat ((void *)(long)(reg));
41 
42   __builtin_tbegin_retry ((void *)0, 0);
43   cc = __builtin_tbegin_retry ((void *)0, 1);
44   cc = __builtin_tbegin_retry ((void *)0, -1);
45   cc = __builtin_tbegin_retry ((void *)0, 42);
46   cc = __builtin_tbegin_retry ((void *)0, reg);
47   cc = __builtin_tbegin_retry ((void *)0, *mem);
48   cc = __builtin_tbegin_retry ((void *)0, global);
49   cc = __builtin_tbegin_retry (tdb, 42);
50   cc = __builtin_tbegin_retry (&global_tdb, 42);
51   cc = __builtin_tbegin_retry ((void *)0x12345678, global);
52   cc = __builtin_tbegin_retry (
53 	  (void *)(long) (reg + 0x12345678), global + 1);
54   cc = __builtin_tbegin_retry (
55 	  (void *)(long)(reg), global - 1);
56 
57   __builtin_tbegin_retry_nofloat ((void *)0, 0);
58   cc = __builtin_tbegin_retry_nofloat ((void *)0, 1);
59   cc = __builtin_tbegin_retry_nofloat ((void *)0, -1);
60   cc = __builtin_tbegin_retry_nofloat ((void *)0, 42);
61   cc = __builtin_tbegin_retry_nofloat ((void *)0, reg);
62   cc = __builtin_tbegin_retry_nofloat ((void *)0, *mem);
63   cc = __builtin_tbegin_retry_nofloat ((void *)0, global);
64   cc = __builtin_tbegin_retry_nofloat (tdb, 42);
65   cc = __builtin_tbegin_retry_nofloat (&global_tdb, 42);
66   cc = __builtin_tbegin_retry_nofloat ((void *)0x12345678, global);
67   cc = __builtin_tbegin_retry_nofloat (
68 	  (void *)(long) (reg + 0x12345678), global + 1);
69   cc = __builtin_tbegin_retry_nofloat (
70 	  (void *)(long)(reg), global - 1);
71 
72   __builtin_tbeginc ();
73 
74   __builtin_tx_nesting_depth ();
75   n = __builtin_tx_nesting_depth ();
76 
77   __builtin_non_tx_store (mem64, 0);
78   {
79 	  const uint64_t val_var = 0x1122334455667788;
80 
81 	  __builtin_non_tx_store (mem64, val_var);
82   }
83   __builtin_non_tx_store (mem64, (uint64_t)reg);
84   __builtin_non_tx_store (mem64, g);
85   __builtin_non_tx_store ((uint64_t *)0, 0);
86   __builtin_non_tx_store ((uint64_t *)0x12345678, 0);
87   __builtin_non_tx_store (&g, 23);
88   __builtin_non_tx_store (&g, reg);
89   __builtin_non_tx_store (&g, *mem);
90   __builtin_non_tx_store (&g, global);
91 
92   __builtin_tend();
93 
94   __builtin_tx_assist (0);
95   __builtin_tx_assist (1);
96   __builtin_tx_assist (reg);
97   __builtin_tx_assist (*mem);
98   __builtin_tx_assist (global);
99 }
100 
101 /* The taborts must go into separate function since they are
102    "noreturn".  */
103 
104 void
tabort1()105 tabort1 ()
106 {
107   __builtin_tabort (256);
108 }
109 
110 void
tabort2(int reg)111 tabort2 (int reg)
112 {
113   __builtin_tabort (reg);
114 }
115 
116 void
tabort3(int reg)117 tabort3 (int reg)
118 {
119   /* { dg-final { scan-assembler-times "tabort\t255" 1 } } */
120   __builtin_tabort (reg + 255);
121 }
122 
123 void
tabort4(int * mem)124 tabort4 (int *mem)
125 {
126   __builtin_tabort (*mem);
127 }
128 
129 void
tabort5()130 tabort5 ()
131 {
132   __builtin_tabort (global);
133 }
134 
135 void
tabort6(int * mem)136 tabort6 (int *mem)
137 {
138   /* Here global + 255 gets reloaded into a reg.  Better would be to
139      just reload global or *mem and get the +255 for free as address
140      arithmetic.  */
141   __builtin_tabort (*mem + 255);
142 }
143 
144 void
tabort7()145 tabort7 ()
146 {
147   __builtin_tabort (global + 255);
148 }
149 
150 void
tabort8()151 tabort8 ()
152 {
153   __builtin_tabort (-1);
154 }
155 
156 
157 /* Make sure the tdb NULL argument ends up as immediate value in the
158    instruction.  */
159 /* { dg-final { scan-assembler-times "tbegin\t0," 17 } } */
160 /* { dg-final { scan-assembler-times "tbegin\t" 41 } } */
161 /* Check number of occurences of certain instructions.  */
162 /* { dg-final { scan-assembler-times "tbeginc\t" 1 } } */
163 /* { dg-final { scan-assembler-times "tabort\t" 8 } } */
164 /* { dg-final { scan-assembler "ppa\t" } } */
165