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