1#include <stdio.h>
2
3/* Dummy variable. Needed to work around GCC code generation bugs */
4volatile long v;
5
6#define SUB_REG_MEM(insn, s1, s2, NOBORROW)		\
7({							\
8	unsigned long tmp = s1;				\
9	int cc;						\
10	asm volatile(	"lghi 0," #NOBORROW "\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 " %16.16lX - %16.16lX - %d = %16.16lX (cc=%d)\n", s1, s2, !NOBORROW, tmp, cc); \
19})
20
21#define SUB_REG_REG(insn, s1, s2, NOBORROW)		\
22({							\
23	unsigned long tmp = s1;				\
24	int cc;						\
25	asm volatile(	"lghi 0," #NOBORROW "\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 " %16.16lX - %16.16lX - %d = %16.16lX (cc=%d)\n", s1, s2, !NOBORROW, tmp, cc); \
34})
35
36#define SUB_REG_IMM(insn, s1, s2, NOBORROW)		\
37({							\
38	register unsigned long tmp asm("2") = s1;	\
39	int cc;						\
40	asm volatile(	"lghi 0," #NOBORROW "\n"		\
41			"aghi 0, 0\n"			\
42                        insn(2,s2)			\
43			"ipm %1\n"			\
44			"srl %1,28\n"			\
45			: "+d" (tmp), "=d" (cc)		\
46			: "d" (tmp)			\
47			: "0", "cc");			\
48	v = tmp;					\
49	printf(#insn " %16.16lX - %16.16lX - %d = %16.16lX (cc=%d)\n", s1, (unsigned long) 0x00000000##s2, !NOBORROW, v, cc); \
50})
51
52#define memsweep(i, s2, carryset)				\
53({								\
54	SUB_REG_MEM(i, 0ul, s2, carryset);			\
55	SUB_REG_MEM(i, 1ul, s2, carryset);			\
56	SUB_REG_MEM(i, 0xfffful, s2, carryset);			\
57	SUB_REG_MEM(i, 0x7ffful, s2, carryset);			\
58	SUB_REG_MEM(i, 0x8000ul, s2, carryset);			\
59	SUB_REG_MEM(i, 0xfffffffful, s2, carryset);		\
60	SUB_REG_MEM(i, 0x80000000ul, s2, carryset);		\
61	SUB_REG_MEM(i, 0x7ffffffful, s2, carryset);		\
62	SUB_REG_MEM(i, 0xfffffffffffffffful, s2, carryset);	\
63	SUB_REG_MEM(i, 0x8000000000000000ul, s2, carryset);	\
64	SUB_REG_MEM(i, 0x7ffffffffffffffful, s2, carryset);	\
65})
66
67#define regsweep(i, s2, carryset)				\
68({								\
69	SUB_REG_REG(i, 0ul, s2, carryset);			\
70	SUB_REG_REG(i, 1ul, s2, carryset);			\
71	SUB_REG_REG(i, 0xfffful, s2, carryset);			\
72	SUB_REG_REG(i, 0x7ffful, s2, carryset);			\
73	SUB_REG_REG(i, 0x8000ul, s2, carryset);			\
74	SUB_REG_REG(i, 0xfffffffful, s2, carryset);		\
75	SUB_REG_REG(i, 0x80000000ul, s2, carryset);		\
76	SUB_REG_REG(i, 0x7ffffffful, s2, carryset);		\
77	SUB_REG_REG(i, 0xfffffffffffffffful, s2, carryset);	\
78	SUB_REG_REG(i, 0x8000000000000000ul, s2, carryset);	\
79	SUB_REG_REG(i, 0x7ffffffffffffffful, s2, carryset);	\
80})
81
82#define immsweep(i, s2, carryset)				\
83({								\
84	SUB_REG_IMM(i, 0ul, s2, carryset);			\
85	SUB_REG_IMM(i, 1ul, s2, carryset);			\
86	SUB_REG_IMM(i, 0xfffful, s2, carryset);			\
87	SUB_REG_IMM(i, 0x7ffful, s2, carryset);			\
88	SUB_REG_IMM(i, 0x8000ul, s2, carryset);			\
89	SUB_REG_IMM(i, 0xfffffffful, s2, carryset);		\
90	SUB_REG_IMM(i, 0x80000000ul, s2, carryset);		\
91	SUB_REG_IMM(i, 0x7ffffffful, s2, carryset);		\
92	SUB_REG_IMM(i, 0xfffffffffffffffful, s2, carryset);	\
93	SUB_REG_IMM(i, 0x8000000000000000ul, s2, carryset);	\
94	SUB_REG_IMM(i, 0x7ffffffffffffffful, s2, carryset);	\
95})
96
97#define SUB_REG_LDISP(insn, s1, s2, NOBORROW)			\
98({								\
99	register unsigned long tmp asm("2") = s1;		\
100	register unsigned long *addr asm("5") = &s2;		\
101	int cc;							\
102	asm volatile(	"lghi 0," #NOBORROW "\n"		\
103			"aghi 0, 0\n"				\
104			insn(2,0,5,000,00)			\
105			"ipm %1\n"				\
106			"srl %1,28\n"				\
107			: "+d" (tmp), "=d" (cc)			\
108			: "d" (tmp), "Q" (s2), "d"(addr)	\
109			: "cc");				\
110	v = tmp; /* work around GCC code gen bug */     \
111	printf(#insn " %16.16lX - %16.16lX - %d = %16.16lX (cc=%d)\n", s1, s2, !NOBORROW, v, cc); \
112})
113
114#define ldispsweep(i, s2, carryset)				\
115({								\
116	SUB_REG_LDISP(i, 0ul, s2, carryset);			\
117	SUB_REG_LDISP(i, 1ul, s2, carryset);			\
118	SUB_REG_LDISP(i, 0xfffful, s2, carryset);		\
119	SUB_REG_LDISP(i, 0x7ffful, s2, carryset);		\
120	SUB_REG_LDISP(i, 0x8000ul, s2, carryset);		\
121	SUB_REG_LDISP(i, 0xfffffffful, s2, carryset);		\
122	SUB_REG_LDISP(i, 0x80000000ul, s2, carryset);		\
123	SUB_REG_LDISP(i, 0x7ffffffful, s2, carryset);		\
124	SUB_REG_LDISP(i, 0xfffffffffffffffful, s2, carryset);	\
125	SUB_REG_LDISP(i, 0x8000000000000000ul, s2, carryset);	\
126	SUB_REG_LDISP(i, 0x7ffffffffffffffful, s2, carryset);	\
127})
128