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