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