1#include <stdio.h>
2
3/* Dummy variable. Needed to work around GCC code generation bugs */
4volatile long v;
5
6#define ADD_REG_MEM(insn, s1, s2, CARRY)		\
7({							\
8	unsigned long tmp = s1;				\
9	int cc;						\
10	asm volatile(	"lghi 0," #CARRY "\n"		\
11			"aghi 0, 0\n"			\
12			#insn " %0, %3\n"		\
13			"ipm %1\n"			\
14			"srl %1,28\n"			\
15			: "+d" (tmp), "=d" (cc)		\
16			: "d" (tmp), "Q" (s2)		\
17			: "0", "cc");			\
18	printf(#insn " " #CARRY " + %16.16lX + %16.16lX = %16.16lX (cc=%d)\n", s1, s2, tmp, cc); \
19})
20
21#define ADD_REG_REG(insn, s1, s2, CARRY)		\
22({							\
23	unsigned long tmp = s1;				\
24	int cc;						\
25	asm volatile(	"lghi 0," #CARRY "\n"		\
26			"aghi 0, 0\n"			\
27			#insn " %0, %3\n"		\
28			"ipm %1\n"			\
29			"srl %1,28\n"			\
30			: "+d" (tmp), "=d" (cc)		\
31			: "d" (tmp), "d" (s2)		\
32			: "0", "cc");			\
33	printf(#insn " " #CARRY " + %16.16lX + %16.16lX = %16.16lX (cc=%d)\n", s1, s2, tmp, cc); \
34})
35
36#define ADD_REG_IMM(insn, s1, s2, CARRY)		\
37({							\
38	unsigned long tmp = s1;				\
39	int cc;						\
40	asm volatile(	"lghi 0," #CARRY "\n"		\
41			"aghi 0, 0\n"			\
42			#insn " %0," #s2 "\n"		\
43			"ipm %1\n"			\
44			"srl %1,28\n"			\
45			: "+d" (tmp), "=d" (cc)		\
46			: "d" (tmp)			\
47			: "0", "cc");			\
48	printf(#insn " " #CARRY " + %16.16lX + %16.16lX = %16.16lX (cc=%d)\n", s1, (unsigned long) s2, tmp, cc); \
49})
50
51#define ADD_MEM_IMM(insn, s1, s2, CARRY)		\
52({							\
53	unsigned long tmp = s1, v2;			\
54	register unsigned long *addr asm("5") = &tmp;	\
55	int cc;						\
56	asm volatile(	"lghi 0," #CARRY "\n"		\
57			"aghi 0, 0\n"			\
58			insn(s2,5,000,00)		\
59			"ipm %1\n"			\
60			"srl %1,28\n"			\
61			: "+Q" (tmp), "=d" (cc)		\
62			: "Q" (tmp), "d" (addr)		\
63			: "0", "cc");			\
64        v2 =  (((signed long)((unsigned long)0x##s2 << 56)) >> 56); \
65	printf(#insn " " #CARRY " + %16.16lX + %16.16lX = %16.16lX (cc=%d)\n", s1, v2, tmp, cc); \
66})
67
68
69#define memsweep(i, s2, carryset)				\
70({								\
71	ADD_REG_MEM(i, 0ul, s2, carryset);			\
72	ADD_REG_MEM(i, 1ul, s2, carryset);			\
73	ADD_REG_MEM(i, 0xfffful, s2, carryset);			\
74	ADD_REG_MEM(i, 0x7ffful, s2, carryset);			\
75	ADD_REG_MEM(i, 0x8000ul, s2, carryset);			\
76	ADD_REG_MEM(i, 0xfffffffful, s2, carryset);		\
77	ADD_REG_MEM(i, 0x80000000ul, s2, carryset);		\
78	ADD_REG_MEM(i, 0x7ffffffful, s2, carryset);		\
79	ADD_REG_MEM(i, 0xfffffffffffffffful, s2, carryset);	\
80	ADD_REG_MEM(i, 0x8000000000000000ul, s2, carryset);	\
81	ADD_REG_MEM(i, 0x7ffffffffffffffful, s2, carryset);	\
82})
83
84#define regsweep(i, s2, carryset)				\
85({								\
86	ADD_REG_REG(i, 0ul, s2, carryset);			\
87	ADD_REG_REG(i, 1ul, s2, carryset);			\
88	ADD_REG_REG(i, 0xfffful, s2, carryset);			\
89	ADD_REG_REG(i, 0x7ffful, s2, carryset);			\
90	ADD_REG_REG(i, 0x8000ul, s2, carryset);			\
91	ADD_REG_REG(i, 0xfffffffful, s2, carryset);		\
92	ADD_REG_REG(i, 0x80000000ul, s2, carryset);		\
93	ADD_REG_REG(i, 0x7ffffffful, s2, carryset);		\
94	ADD_REG_REG(i, 0xfffffffffffffffful, s2, carryset);	\
95	ADD_REG_REG(i, 0x8000000000000000ul, s2, carryset);	\
96	ADD_REG_REG(i, 0x7ffffffffffffffful, s2, carryset);	\
97})
98
99#define immsweep(i, s2, carryset)				\
100({								\
101	ADD_REG_IMM(i, 0ul, s2, carryset);			\
102	ADD_REG_IMM(i, 1ul, s2, carryset);			\
103	ADD_REG_IMM(i, 0xfffful, s2, carryset);			\
104	ADD_REG_IMM(i, 0x7ffful, s2, carryset);			\
105	ADD_REG_IMM(i, 0x8000ul, s2, carryset);			\
106	ADD_REG_IMM(i, 0xfffffffful, s2, carryset);		\
107	ADD_REG_IMM(i, 0x80000000ul, s2, carryset);		\
108	ADD_REG_IMM(i, 0x7ffffffful, s2, carryset);		\
109	ADD_REG_IMM(i, 0xfffffffffffffffful, s2, carryset);	\
110	ADD_REG_IMM(i, 0x8000000000000000ul, s2, carryset);	\
111	ADD_REG_IMM(i, 0x7ffffffffffffffful, s2, carryset);	\
112})
113
114#define memimmsweep(i, s2, carryset)				\
115({								\
116	ADD_MEM_IMM(i, 0ul, s2, carryset);			\
117	ADD_MEM_IMM(i, 1ul, s2, carryset);			\
118	ADD_MEM_IMM(i, 0xfffful, s2, carryset);			\
119	ADD_MEM_IMM(i, 0x7ffful, s2, carryset);			\
120	ADD_MEM_IMM(i, 0x8000ul, s2, carryset);			\
121	ADD_MEM_IMM(i, 0xfffffffful, s2, carryset);		\
122	ADD_MEM_IMM(i, 0x80000000ul, s2, carryset);		\
123	ADD_MEM_IMM(i, 0x7ffffffful, s2, carryset);		\
124	ADD_MEM_IMM(i, 0xfffffffffffffffful, s2, carryset);	\
125	ADD_MEM_IMM(i, 0x8000000000000000ul, s2, carryset);	\
126	ADD_MEM_IMM(i, 0x7ffffffffffffffful, s2, carryset);	\
127})
128
129#define ahysweep(i, s2, carryset)				\
130({								\
131	ADD_REG_MEM(i, 0ul, s2, carryset);			\
132	ADD_REG_MEM(i, 1ul, s2, carryset);			\
133	ADD_REG_MEM(i, 0xfffful, s2, carryset);			\
134	ADD_REG_MEM(i, 0x7ffful, s2, carryset);			\
135	ADD_REG_MEM(i, 0x8000ul, s2, carryset);			\
136	ADD_REG_MEM(i, 0xfffffffful, s2, carryset);		\
137	ADD_REG_MEM(i, 0x80000000ul, s2, carryset);		\
138	ADD_REG_MEM(i, 0x7ffffffful, s2, carryset);		\
139	ADD_REG_MEM(i, 0xfffffffffffffffful, s2, carryset);	\
140	ADD_REG_MEM(i, 0x8000000000000000ul, s2, carryset);	\
141	ADD_REG_MEM(i, 0x7ffffffffffffffful, s2, carryset);	\
142})
143
144#define ADD_REG_LDISP(insn, s1, s2, CARRY)			\
145({								\
146	register unsigned long tmp asm("2") = s1;		\
147	register unsigned long *addr asm("5") = &s2;		\
148	int cc;							\
149	asm volatile(	"lghi 0," #CARRY "\n"			\
150			"aghi 0, 0\n"				\
151			insn(2,0,5,000,00)			\
152			"ipm %1\n"				\
153			"srl %1,28\n"				\
154			: "+d" (tmp), "=d" (cc)			\
155			: "d" (tmp), "Q" (s2), "d"(addr)	\
156			: "cc");				\
157	v = tmp; /* work around GCC code gen bug */     \
158	printf(#insn " " #CARRY " + %16.16lX + %16.16lX = %16.16lX (cc=%d)\n", s1, s2, v, cc); \
159})
160
161#define ldispsweep(i, s2, carryset)				\
162({								\
163	ADD_REG_LDISP(i, 0ul, s2, carryset);			\
164	ADD_REG_LDISP(i, 1ul, s2, carryset);			\
165	ADD_REG_LDISP(i, 0xfffful, s2, carryset);		\
166	ADD_REG_LDISP(i, 0x7ffful, s2, carryset);		\
167	ADD_REG_LDISP(i, 0x8000ul, s2, carryset);		\
168	ADD_REG_LDISP(i, 0xfffffffful, s2, carryset);		\
169	ADD_REG_LDISP(i, 0x80000000ul, s2, carryset);		\
170	ADD_REG_LDISP(i, 0x7ffffffful, s2, carryset);		\
171	ADD_REG_LDISP(i, 0xfffffffffffffffful, s2, carryset);	\
172	ADD_REG_LDISP(i, 0x8000000000000000ul, s2, carryset);	\
173	ADD_REG_LDISP(i, 0x7ffffffffffffffful, s2, carryset);	\
174})
175
176#define ADD_REG_XIMM(insn, s1, us2,s2, CARRY)		\
177({							\
178	register unsigned long tmp asm("2") = s1;	\
179	int cc;						\
180	asm volatile(	"lghi 0," #CARRY "\n"		\
181			"aghi 0, 0\n"			\
182			insn(2,s2)			\
183			"ipm %1\n"			\
184			"srl %1,28\n"			\
185			: "+d" (tmp), "=d" (cc)		\
186			: "d" (tmp)			\
187			: "0", "cc");			\
188	v = tmp; /* work around GCC code gen bug */     \
189	printf(#insn " " #CARRY " + %16.16lX + %16.16lX = %16.16lX (cc=%d)\n", s1, (unsigned long) 0x##us2##s2, v, cc); \
190})
191
192#define ximmsweep(i, us2, s2, carryset)					\
193({									\
194	ADD_REG_XIMM(i, 0ul, us2, s2, carryset);			\
195	ADD_REG_XIMM(i, 1ul, us2, s2, carryset);			\
196	ADD_REG_XIMM(i, 0xfffful, us2, s2, carryset);			\
197	ADD_REG_XIMM(i, 0x7ffful, us2, s2, carryset);			\
198	ADD_REG_XIMM(i, 0x8000ul, us2, s2, carryset);			\
199	ADD_REG_XIMM(i, 0xfffffffful, us2, s2, carryset);		\
200	ADD_REG_XIMM(i, 0x80000000ul, us2, s2, carryset);		\
201	ADD_REG_XIMM(i, 0x7ffffffful, us2, s2, carryset);		\
202	ADD_REG_XIMM(i, 0xfffffffffffffffful, us2, s2, carryset);	\
203	ADD_REG_XIMM(i, 0x8000000000000000ul, us2, s2, carryset);	\
204	ADD_REG_XIMM(i, 0x7ffffffffffffffful, us2, s2, carryset);	\
205})
206
207