1 
2 #define exec_op glue(exec_, OP)
3 #define exec_opq glue(glue(exec_, OP), q)
4 #define exec_opl glue(glue(exec_, OP), l)
5 #define exec_opw glue(glue(exec_, OP), w)
6 #define exec_opb glue(glue(exec_, OP), b)
7 
8 #ifndef OP_SHIFTD
9 
10 #ifdef OP_NOBYTE
11 #define EXECSHIFT(size, res, s1, s2, flags) \
12     asm ("pushq %4\n\t"\
13          "popfq\n\t"\
14          stringify(OP) size " %" size "2, %" size "0\n\t" \
15          "pushfq\n\t"\
16          "popq %1\n\t"\
17          : "=g" (res), "=g" (flags)\
18          : "r" (s1), "0" (res), "1" (flags));
19 #else
20 #define EXECSHIFT(size, res, s1, s2, flags) \
21     asm ("pushq %4\n\t"\
22          "popfq\n\t"\
23          stringify(OP) size " %%cl, %" size "0\n\t" \
24          "pushfq\n\t"\
25          "popq %1\n\t"\
26          : "=q" (res), "=g" (flags)\
27          : "c" (s1), "0" (res), "1" (flags));
28 #endif
29 
exec_opq(int64 s2,int64 s0,int64 s1,int64 iflags)30 void exec_opq(int64 s2, int64 s0, int64 s1, int64 iflags)
31 {
32     int64 res, flags;
33     res = s0;
34     flags = iflags;
35     EXECSHIFT("q", res, s1, s2, flags);
36     /* overflow is undefined if count != 1 */
37     if (s1 != 1)
38       flags &= ~CC_O;
39     printf("%-10s A=%016llx B=%016llx R=%016llx CCIN=%04llx CC=%04llx\n",
40            stringify(OP) "q", s0, s1, res, iflags, flags & CC_MASK);
41 }
42 
exec_opl(int64 s2,int64 s0,int64 s1,int64 iflags)43 void exec_opl(int64 s2, int64 s0, int64 s1, int64 iflags)
44 {
45     int64 res, flags;
46     res = s0;
47     flags = iflags;
48     EXECSHIFT("", res, s1, s2, flags);
49     /* overflow is undefined if count != 1 */
50     if (s1 != 1)
51       flags &= ~CC_O;
52     printf("%-10s A=%016llx B=%016llx R=%016llx CCIN=%04llx CC=%04llx\n",
53            stringify(OP) "l", s0, s1, res, iflags, flags & CC_MASK);
54 }
55 
exec_opw(int64 s2,int64 s0,int64 s1,int64 iflags)56 void exec_opw(int64 s2, int64 s0, int64 s1, int64 iflags)
57 {
58     int64 res, flags;
59     res = s0;
60     flags = iflags;
61     EXECSHIFT("w", res, s1, s2, flags);
62     /* overflow is undefined if count != 1 */
63     if (s1 != 1)
64       flags &= ~CC_O;
65     printf("%-10s A=%016llx B=%016llx R=%016llx CCIN=%04llx CC=%04llx\n",
66            stringify(OP) "w", s0, s1, res, iflags, flags & CC_MASK);
67 }
68 
69 #else
70 #define EXECSHIFT(size, res, s1, s2, flags) \
71     asm ("pushq %4\n\t"\
72          "popfq\n\t"\
73          stringify(OP) size " %%cl, %" size "5, %" size "0\n\t" \
74          "pushfq\n\t"\
75          "popq %1\n\t"\
76          : "=g" (res), "=g" (flags)\
77          : "c" (s1), "0" (res), "1" (flags), "r" (s2));
78 
exec_opl(int64 s2,int64 s0,int64 s1,int64 iflags)79 void exec_opl(int64 s2, int64 s0, int64 s1, int64 iflags)
80 {
81     int64 res, flags;
82     res = s0;
83     flags = iflags;
84     EXECSHIFT("", res, s1, s2, flags);
85     /* overflow is undefined if count != 1 */
86     if (s1 != 1)
87       flags &= ~CC_O;
88     printf("%-10s A=%016llx B=%016llx C=%016llx R=%016llx CCIN=%04llx CC=%04llx\n",
89            stringify(OP) "l", s0, s2, s1, res, iflags, flags & CC_MASK);
90 }
91 
exec_opw(int64 s2,int64 s0,int64 s1,int64 iflags)92 void exec_opw(int64 s2, int64 s0, int64 s1, int64 iflags)
93 {
94     int64 res, flags;
95     res = s0;
96     flags = iflags;
97     EXECSHIFT("w", res, s1, s2, flags);
98     /* overflow is undefined if count != 1 */
99     if (s1 != 1)
100       flags &= ~CC_O;
101     printf("%-10s A=%016llx B=%016llx C=%016llx R=%016llx CCIN=%04llx CC=%04llx\n",
102            stringify(OP) "w", s0, s2, s1, res, iflags, flags & CC_MASK);
103 }
104 
105 #endif
106 
107 #ifndef OP_NOBYTE
exec_opb(int64 s0,int64 s1,int64 iflags)108 void exec_opb(int64 s0, int64 s1, int64 iflags)
109 {
110     int64 res, flags;
111     res = s0;
112     flags = iflags;
113     EXECSHIFT("b", res, s1, 0, flags);
114     /* overflow is undefined if count != 1 */
115     if (s1 != 1)
116       flags &= ~CC_O;
117     printf("%-10s A=%016llx B=%016llx R=%016llx CCIN=%04llx CC=%04llx\n",
118            stringify(OP) "b", s0, s1, res, iflags, flags & CC_MASK);
119 }
120 #endif
121 
exec_op(int64 s2,int64 s0,int64 s1)122 void exec_op(int64 s2, int64 s0, int64 s1)
123 {
124   int64 o,s,z,a,c,p,flags_in;
125   for (o = 0; o < 2; o++) {
126   for (s = 0; s < 2; s++) {
127   for (z = 0; z < 2; z++) {
128   for (a = 0; a < 2; a++) {
129   for (c = 0; c < 2; c++) {
130   for (p = 0; p < 2; p++) {
131 
132     flags_in = (o ? CC_O : 0)
133              | (s ? CC_S : 0)
134              | (z ? CC_Z : 0)
135              | (a ? CC_A : 0)
136              | (c ? CC_C : 0)
137              | (p ? CC_P : 0);
138 
139     exec_opq(s2, s0, s1, flags_in);
140     if (s1 <= 31)
141        exec_opl(s2, s0, s1, flags_in);
142 #ifdef OP_SHIFTD
143     if (s1 <= 15)
144         exec_opw(s2, s0, s1, flags_in);
145 #else
146     exec_opw(s2, s0, s1, flags_in);
147 #endif
148 #ifndef OP_NOBYTE
149     exec_opb(s0, s1, flags_in);
150 #endif
151 #ifdef OP_CC
152     exec_opq(s2, s0, s1, flags_in);
153     exec_opl(s2, s0, s1, flags_in);
154     exec_opw(s2, s0, s1, flags_in);
155     exec_opb(s0, s1, flags_in);
156 #endif
157 
158   }}}}}}
159 
160 }
161 
glue(test_,OP)162 void glue(test_, OP)(void)
163 {
164     int64 i;
165     for(i = 0; i < 64; i++)
166         exec_op(0x3141592721ad3d34, 0x2718284612345678, i);
167     for(i = 0; i < 64; i++)
168         exec_op(0x31415927813f3421, 0x2718284682345678, i);
169 }
170 
171 void *glue(_test_, OP) __init_call = glue(test_, OP);
172 
173 #undef OP
174 #undef OP_CC
175 #undef OP_SHIFTD
176 #undef OP_NOBYTE
177 #undef EXECSHIFT
178 
179