root / ops_template.h @ 367e86e8
History | View | Annotate | Download (13.5 kB)
1 | 367e86e8 | bellard | |
---|---|---|---|
2 | 367e86e8 | bellard | #define DATA_BITS (1 << (3 + SHIFT)) |
3 | 367e86e8 | bellard | #define SHIFT_MASK (DATA_BITS - 1) |
4 | 367e86e8 | bellard | #define SIGN_MASK (1 << (DATA_BITS - 1)) |
5 | 367e86e8 | bellard | |
6 | 367e86e8 | bellard | #if DATA_BITS == 8 |
7 | 367e86e8 | bellard | #define SUFFIX b
|
8 | 367e86e8 | bellard | #define DATA_TYPE uint8_t
|
9 | 367e86e8 | bellard | #define DATA_STYPE int8_t
|
10 | 367e86e8 | bellard | #define DATA_MASK 0xff |
11 | 367e86e8 | bellard | #elif DATA_BITS == 16 |
12 | 367e86e8 | bellard | #define SUFFIX w
|
13 | 367e86e8 | bellard | #define DATA_TYPE uint16_t
|
14 | 367e86e8 | bellard | #define DATA_STYPE int16_t
|
15 | 367e86e8 | bellard | #define DATA_MASK 0xffff |
16 | 367e86e8 | bellard | #elif DATA_BITS == 32 |
17 | 367e86e8 | bellard | #define SUFFIX l
|
18 | 367e86e8 | bellard | #define DATA_TYPE uint32_t
|
19 | 367e86e8 | bellard | #define DATA_STYPE int32_t
|
20 | 367e86e8 | bellard | #define DATA_MASK 0xffffffff |
21 | 367e86e8 | bellard | #else
|
22 | 367e86e8 | bellard | #error unhandled operand size
|
23 | 367e86e8 | bellard | #endif
|
24 | 367e86e8 | bellard | |
25 | 367e86e8 | bellard | /* dynamic flags computation */
|
26 | 367e86e8 | bellard | |
27 | 367e86e8 | bellard | static int glue(compute_all_add, SUFFIX)(void) |
28 | 367e86e8 | bellard | { |
29 | 367e86e8 | bellard | int cf, pf, af, zf, sf, of;
|
30 | 367e86e8 | bellard | int src1, src2;
|
31 | 367e86e8 | bellard | src1 = CC_SRC; |
32 | 367e86e8 | bellard | src2 = CC_DST - CC_SRC; |
33 | 367e86e8 | bellard | cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1; |
34 | 367e86e8 | bellard | pf = parity_table[(uint8_t)CC_DST]; |
35 | 367e86e8 | bellard | af = (CC_DST ^ src1 ^ src2) & 0x10;
|
36 | 367e86e8 | bellard | zf = ((DATA_TYPE)CC_DST != 0) << 6; |
37 | 367e86e8 | bellard | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
38 | 367e86e8 | bellard | of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O; |
39 | 367e86e8 | bellard | return cf | pf | af | zf | sf | of;
|
40 | 367e86e8 | bellard | } |
41 | 367e86e8 | bellard | |
42 | 367e86e8 | bellard | static int glue(compute_c_add, SUFFIX)(void) |
43 | 367e86e8 | bellard | { |
44 | 367e86e8 | bellard | int src1, cf;
|
45 | 367e86e8 | bellard | src1 = CC_SRC; |
46 | 367e86e8 | bellard | cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1; |
47 | 367e86e8 | bellard | return cf;
|
48 | 367e86e8 | bellard | } |
49 | 367e86e8 | bellard | |
50 | 367e86e8 | bellard | static int glue(compute_all_sub, SUFFIX)(void) |
51 | 367e86e8 | bellard | { |
52 | 367e86e8 | bellard | int cf, pf, af, zf, sf, of;
|
53 | 367e86e8 | bellard | int src1, src2;
|
54 | 367e86e8 | bellard | src1 = CC_SRC; |
55 | 367e86e8 | bellard | src2 = CC_SRC - CC_DST; |
56 | 367e86e8 | bellard | cf = (DATA_TYPE)src1 < (DATA_TYPE)src2; |
57 | 367e86e8 | bellard | pf = parity_table[(uint8_t)CC_DST]; |
58 | 367e86e8 | bellard | af = (CC_DST ^ src1 ^ src2) & 0x10;
|
59 | 367e86e8 | bellard | zf = ((DATA_TYPE)CC_DST != 0) << 6; |
60 | 367e86e8 | bellard | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
61 | 367e86e8 | bellard | of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O; |
62 | 367e86e8 | bellard | return cf | pf | af | zf | sf | of;
|
63 | 367e86e8 | bellard | } |
64 | 367e86e8 | bellard | |
65 | 367e86e8 | bellard | static int glue(compute_c_sub, SUFFIX)(void) |
66 | 367e86e8 | bellard | { |
67 | 367e86e8 | bellard | int src1, src2, cf;
|
68 | 367e86e8 | bellard | src1 = CC_SRC; |
69 | 367e86e8 | bellard | src2 = CC_SRC - CC_DST; |
70 | 367e86e8 | bellard | cf = (DATA_TYPE)src1 < (DATA_TYPE)src1; |
71 | 367e86e8 | bellard | return cf;
|
72 | 367e86e8 | bellard | } |
73 | 367e86e8 | bellard | |
74 | 367e86e8 | bellard | static int glue(compute_all_logic, SUFFIX)(void) |
75 | 367e86e8 | bellard | { |
76 | 367e86e8 | bellard | int cf, pf, af, zf, sf, of;
|
77 | 367e86e8 | bellard | cf = 0;
|
78 | 367e86e8 | bellard | pf = parity_table[(uint8_t)CC_DST]; |
79 | 367e86e8 | bellard | af = 0;
|
80 | 367e86e8 | bellard | zf = ((DATA_TYPE)CC_DST != 0) << 6; |
81 | 367e86e8 | bellard | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
82 | 367e86e8 | bellard | of = 0;
|
83 | 367e86e8 | bellard | return cf | pf | af | zf | sf | of;
|
84 | 367e86e8 | bellard | } |
85 | 367e86e8 | bellard | |
86 | 367e86e8 | bellard | static int glue(compute_c_logic, SUFFIX)(void) |
87 | 367e86e8 | bellard | { |
88 | 367e86e8 | bellard | return 0; |
89 | 367e86e8 | bellard | } |
90 | 367e86e8 | bellard | |
91 | 367e86e8 | bellard | static int glue(compute_all_inc, SUFFIX)(void) |
92 | 367e86e8 | bellard | { |
93 | 367e86e8 | bellard | int cf, pf, af, zf, sf, of;
|
94 | 367e86e8 | bellard | int src1, src2;
|
95 | 367e86e8 | bellard | src1 = CC_DST - 1;
|
96 | 367e86e8 | bellard | src2 = 1;
|
97 | 367e86e8 | bellard | cf = CC_SRC; |
98 | 367e86e8 | bellard | pf = parity_table[(uint8_t)CC_DST]; |
99 | 367e86e8 | bellard | af = (CC_DST ^ src1 ^ src2) & 0x10;
|
100 | 367e86e8 | bellard | zf = ((DATA_TYPE)CC_DST != 0) << 6; |
101 | 367e86e8 | bellard | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
102 | 367e86e8 | bellard | of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O; |
103 | 367e86e8 | bellard | return cf | pf | af | zf | sf | of;
|
104 | 367e86e8 | bellard | } |
105 | 367e86e8 | bellard | |
106 | 367e86e8 | bellard | static int glue(compute_c_inc, SUFFIX)(void) |
107 | 367e86e8 | bellard | { |
108 | 367e86e8 | bellard | return CC_SRC;
|
109 | 367e86e8 | bellard | } |
110 | 367e86e8 | bellard | |
111 | 367e86e8 | bellard | static int glue(compute_all_dec, SUFFIX)(void) |
112 | 367e86e8 | bellard | { |
113 | 367e86e8 | bellard | int cf, pf, af, zf, sf, of;
|
114 | 367e86e8 | bellard | int src1, src2;
|
115 | 367e86e8 | bellard | src1 = CC_DST + 1;
|
116 | 367e86e8 | bellard | src2 = 1;
|
117 | 367e86e8 | bellard | cf = CC_SRC; |
118 | 367e86e8 | bellard | pf = parity_table[(uint8_t)CC_DST]; |
119 | 367e86e8 | bellard | af = (CC_DST ^ src1 ^ src2) & 0x10;
|
120 | 367e86e8 | bellard | zf = ((DATA_TYPE)CC_DST != 0) << 6; |
121 | 367e86e8 | bellard | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
122 | 367e86e8 | bellard | of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O; |
123 | 367e86e8 | bellard | return cf | pf | af | zf | sf | of;
|
124 | 367e86e8 | bellard | } |
125 | 367e86e8 | bellard | |
126 | 367e86e8 | bellard | static int glue(compute_all_shl, SUFFIX)(void) |
127 | 367e86e8 | bellard | { |
128 | 367e86e8 | bellard | int cf, pf, af, zf, sf, of;
|
129 | 367e86e8 | bellard | cf = CC_SRC & 1;
|
130 | 367e86e8 | bellard | pf = parity_table[(uint8_t)CC_DST]; |
131 | 367e86e8 | bellard | af = 0; /* undefined */ |
132 | 367e86e8 | bellard | zf = ((DATA_TYPE)CC_DST != 0) << 6; |
133 | 367e86e8 | bellard | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
134 | 367e86e8 | bellard | of = sf << 4; /* only meaniful for shr with count == 1 */ |
135 | 367e86e8 | bellard | return cf | pf | af | zf | sf | of;
|
136 | 367e86e8 | bellard | } |
137 | 367e86e8 | bellard | |
138 | 367e86e8 | bellard | static int glue(compute_c_shl, SUFFIX)(void) |
139 | 367e86e8 | bellard | { |
140 | 367e86e8 | bellard | return CC_SRC & 1; |
141 | 367e86e8 | bellard | } |
142 | 367e86e8 | bellard | |
143 | 367e86e8 | bellard | /* various optimized jumps cases */
|
144 | 367e86e8 | bellard | |
145 | 367e86e8 | bellard | void OPPROTO glue(op_jb_sub, SUFFIX)(void) |
146 | 367e86e8 | bellard | { |
147 | 367e86e8 | bellard | int src1, src2;
|
148 | 367e86e8 | bellard | src1 = CC_SRC; |
149 | 367e86e8 | bellard | src2 = CC_SRC - CC_DST; |
150 | 367e86e8 | bellard | |
151 | 367e86e8 | bellard | if ((DATA_TYPE)src1 < (DATA_TYPE)src2)
|
152 | 367e86e8 | bellard | PC += PARAM1; |
153 | 367e86e8 | bellard | else
|
154 | 367e86e8 | bellard | PC += PARAM2; |
155 | 367e86e8 | bellard | FORCE_RET(); |
156 | 367e86e8 | bellard | } |
157 | 367e86e8 | bellard | |
158 | 367e86e8 | bellard | void OPPROTO glue(op_jz_sub, SUFFIX)(void) |
159 | 367e86e8 | bellard | { |
160 | 367e86e8 | bellard | if ((DATA_TYPE)CC_DST != 0) |
161 | 367e86e8 | bellard | PC += PARAM1; |
162 | 367e86e8 | bellard | else
|
163 | 367e86e8 | bellard | PC += PARAM2; |
164 | 367e86e8 | bellard | FORCE_RET(); |
165 | 367e86e8 | bellard | } |
166 | 367e86e8 | bellard | |
167 | 367e86e8 | bellard | void OPPROTO glue(op_jbe_sub, SUFFIX)(void) |
168 | 367e86e8 | bellard | { |
169 | 367e86e8 | bellard | int src1, src2;
|
170 | 367e86e8 | bellard | src1 = CC_SRC; |
171 | 367e86e8 | bellard | src2 = CC_SRC - CC_DST; |
172 | 367e86e8 | bellard | |
173 | 367e86e8 | bellard | if ((DATA_TYPE)src1 <= (DATA_TYPE)src2)
|
174 | 367e86e8 | bellard | PC += PARAM1; |
175 | 367e86e8 | bellard | else
|
176 | 367e86e8 | bellard | PC += PARAM2; |
177 | 367e86e8 | bellard | FORCE_RET(); |
178 | 367e86e8 | bellard | } |
179 | 367e86e8 | bellard | |
180 | 367e86e8 | bellard | void OPPROTO glue(op_js_sub, SUFFIX)(void) |
181 | 367e86e8 | bellard | { |
182 | 367e86e8 | bellard | if (CC_DST & SIGN_MASK)
|
183 | 367e86e8 | bellard | PC += PARAM1; |
184 | 367e86e8 | bellard | else
|
185 | 367e86e8 | bellard | PC += PARAM2; |
186 | 367e86e8 | bellard | FORCE_RET(); |
187 | 367e86e8 | bellard | } |
188 | 367e86e8 | bellard | |
189 | 367e86e8 | bellard | void OPPROTO glue(op_jl_sub, SUFFIX)(void) |
190 | 367e86e8 | bellard | { |
191 | 367e86e8 | bellard | int src1, src2;
|
192 | 367e86e8 | bellard | src1 = CC_SRC; |
193 | 367e86e8 | bellard | src2 = CC_SRC - CC_DST; |
194 | 367e86e8 | bellard | |
195 | 367e86e8 | bellard | if ((DATA_STYPE)src1 < (DATA_STYPE)src2)
|
196 | 367e86e8 | bellard | PC += PARAM1; |
197 | 367e86e8 | bellard | else
|
198 | 367e86e8 | bellard | PC += PARAM2; |
199 | 367e86e8 | bellard | FORCE_RET(); |
200 | 367e86e8 | bellard | } |
201 | 367e86e8 | bellard | |
202 | 367e86e8 | bellard | void OPPROTO glue(op_jle_sub, SUFFIX)(void) |
203 | 367e86e8 | bellard | { |
204 | 367e86e8 | bellard | int src1, src2;
|
205 | 367e86e8 | bellard | src1 = CC_SRC; |
206 | 367e86e8 | bellard | src2 = CC_SRC - CC_DST; |
207 | 367e86e8 | bellard | |
208 | 367e86e8 | bellard | if ((DATA_STYPE)src1 <= (DATA_STYPE)src2)
|
209 | 367e86e8 | bellard | PC += PARAM1; |
210 | 367e86e8 | bellard | else
|
211 | 367e86e8 | bellard | PC += PARAM2; |
212 | 367e86e8 | bellard | FORCE_RET(); |
213 | 367e86e8 | bellard | } |
214 | 367e86e8 | bellard | |
215 | 367e86e8 | bellard | /* various optimized set cases */
|
216 | 367e86e8 | bellard | |
217 | 367e86e8 | bellard | void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void) |
218 | 367e86e8 | bellard | { |
219 | 367e86e8 | bellard | int src1, src2;
|
220 | 367e86e8 | bellard | src1 = CC_SRC; |
221 | 367e86e8 | bellard | src2 = CC_SRC - CC_DST; |
222 | 367e86e8 | bellard | |
223 | 367e86e8 | bellard | T0 = ((DATA_TYPE)src1 < (DATA_TYPE)src2); |
224 | 367e86e8 | bellard | } |
225 | 367e86e8 | bellard | |
226 | 367e86e8 | bellard | void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void) |
227 | 367e86e8 | bellard | { |
228 | 367e86e8 | bellard | T0 = ((DATA_TYPE)CC_DST != 0);
|
229 | 367e86e8 | bellard | } |
230 | 367e86e8 | bellard | |
231 | 367e86e8 | bellard | void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void) |
232 | 367e86e8 | bellard | { |
233 | 367e86e8 | bellard | int src1, src2;
|
234 | 367e86e8 | bellard | src1 = CC_SRC; |
235 | 367e86e8 | bellard | src2 = CC_SRC - CC_DST; |
236 | 367e86e8 | bellard | |
237 | 367e86e8 | bellard | T0 = ((DATA_TYPE)src1 <= (DATA_TYPE)src2); |
238 | 367e86e8 | bellard | } |
239 | 367e86e8 | bellard | |
240 | 367e86e8 | bellard | void OPPROTO glue(op_sets_T0_sub, SUFFIX)(void) |
241 | 367e86e8 | bellard | { |
242 | 367e86e8 | bellard | T0 = lshift(CC_DST, -(DATA_BITS - 1)) & 1; |
243 | 367e86e8 | bellard | } |
244 | 367e86e8 | bellard | |
245 | 367e86e8 | bellard | void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void) |
246 | 367e86e8 | bellard | { |
247 | 367e86e8 | bellard | int src1, src2;
|
248 | 367e86e8 | bellard | src1 = CC_SRC; |
249 | 367e86e8 | bellard | src2 = CC_SRC - CC_DST; |
250 | 367e86e8 | bellard | |
251 | 367e86e8 | bellard | T0 = ((DATA_STYPE)src1 < (DATA_STYPE)src2); |
252 | 367e86e8 | bellard | } |
253 | 367e86e8 | bellard | |
254 | 367e86e8 | bellard | void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void) |
255 | 367e86e8 | bellard | { |
256 | 367e86e8 | bellard | int src1, src2;
|
257 | 367e86e8 | bellard | src1 = CC_SRC; |
258 | 367e86e8 | bellard | src2 = CC_SRC - CC_DST; |
259 | 367e86e8 | bellard | |
260 | 367e86e8 | bellard | T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2); |
261 | 367e86e8 | bellard | } |
262 | 367e86e8 | bellard | |
263 | 367e86e8 | bellard | /* shifts */
|
264 | 367e86e8 | bellard | |
265 | 367e86e8 | bellard | void OPPROTO glue(glue(op_rol, SUFFIX), _T0_T1_cc)(void) |
266 | 367e86e8 | bellard | { |
267 | 367e86e8 | bellard | int count, src;
|
268 | 367e86e8 | bellard | count = T1 & SHIFT_MASK; |
269 | 367e86e8 | bellard | if (count) {
|
270 | 367e86e8 | bellard | CC_SRC = cc_table[CC_OP].compute_all() & ~(CC_O | CC_C); |
271 | 367e86e8 | bellard | src = T0; |
272 | 367e86e8 | bellard | T0 &= DATA_MASK; |
273 | 367e86e8 | bellard | T0 = (T0 << count) | (T0 >> (DATA_BITS - count)); |
274 | 367e86e8 | bellard | CC_SRC |= (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | |
275 | 367e86e8 | bellard | (T0 & CC_C); |
276 | 367e86e8 | bellard | CC_OP = CC_OP_EFLAGS; |
277 | 367e86e8 | bellard | } |
278 | 367e86e8 | bellard | } |
279 | 367e86e8 | bellard | |
280 | 367e86e8 | bellard | void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1_cc)(void) |
281 | 367e86e8 | bellard | { |
282 | 367e86e8 | bellard | int count, src;
|
283 | 367e86e8 | bellard | count = T1 & SHIFT_MASK; |
284 | 367e86e8 | bellard | if (count) {
|
285 | 367e86e8 | bellard | CC_SRC = cc_table[CC_OP].compute_all() & ~(CC_O | CC_C); |
286 | 367e86e8 | bellard | src = T0; |
287 | 367e86e8 | bellard | T0 &= DATA_MASK; |
288 | 367e86e8 | bellard | T0 = (T0 >> count) | (T0 << (DATA_BITS - count)); |
289 | 367e86e8 | bellard | CC_SRC |= (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | |
290 | 367e86e8 | bellard | ((T0 >> (DATA_BITS - 1)) & CC_C);
|
291 | 367e86e8 | bellard | CC_OP = CC_OP_EFLAGS; |
292 | 367e86e8 | bellard | } |
293 | 367e86e8 | bellard | } |
294 | 367e86e8 | bellard | |
295 | 367e86e8 | bellard | void OPPROTO glue(glue(op_rcl, SUFFIX), _T0_T1_cc)(void) |
296 | 367e86e8 | bellard | { |
297 | 367e86e8 | bellard | int count, res, eflags;
|
298 | 367e86e8 | bellard | unsigned int src; |
299 | 367e86e8 | bellard | |
300 | 367e86e8 | bellard | count = T1 & 0x1f;
|
301 | 367e86e8 | bellard | #if DATA_BITS == 16 |
302 | 367e86e8 | bellard | count = rclw_table[count]; |
303 | 367e86e8 | bellard | #elif DATA_BITS == 8 |
304 | 367e86e8 | bellard | count = rclb_table[count]; |
305 | 367e86e8 | bellard | #endif
|
306 | 367e86e8 | bellard | if (count) {
|
307 | 367e86e8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
308 | 367e86e8 | bellard | src = T0; |
309 | 367e86e8 | bellard | res = (T0 << count) | ((eflags & CC_C) << (count - 1));
|
310 | 367e86e8 | bellard | if (count > 1) |
311 | 367e86e8 | bellard | res |= T0 >> (DATA_BITS + 1 - count);
|
312 | 367e86e8 | bellard | T0 = res; |
313 | 367e86e8 | bellard | CC_SRC = (eflags & ~(CC_C | CC_O)) | |
314 | 367e86e8 | bellard | (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | |
315 | 367e86e8 | bellard | ((src >> (DATA_BITS - count)) & CC_C); |
316 | 367e86e8 | bellard | CC_OP = CC_OP_EFLAGS; |
317 | 367e86e8 | bellard | } |
318 | 367e86e8 | bellard | } |
319 | 367e86e8 | bellard | |
320 | 367e86e8 | bellard | void OPPROTO glue(glue(op_rcr, SUFFIX), _T0_T1_cc)(void) |
321 | 367e86e8 | bellard | { |
322 | 367e86e8 | bellard | int count, res, eflags;
|
323 | 367e86e8 | bellard | unsigned int src; |
324 | 367e86e8 | bellard | |
325 | 367e86e8 | bellard | count = T1 & 0x1f;
|
326 | 367e86e8 | bellard | #if DATA_BITS == 16 |
327 | 367e86e8 | bellard | count = rclw_table[count]; |
328 | 367e86e8 | bellard | #elif DATA_BITS == 8 |
329 | 367e86e8 | bellard | count = rclb_table[count]; |
330 | 367e86e8 | bellard | #endif
|
331 | 367e86e8 | bellard | if (count) {
|
332 | 367e86e8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
333 | 367e86e8 | bellard | src = T0; |
334 | 367e86e8 | bellard | res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count)); |
335 | 367e86e8 | bellard | if (count > 1) |
336 | 367e86e8 | bellard | res |= T0 << (DATA_BITS + 1 - count);
|
337 | 367e86e8 | bellard | T0 = res; |
338 | 367e86e8 | bellard | CC_SRC = (eflags & ~(CC_C | CC_O)) | |
339 | 367e86e8 | bellard | (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | |
340 | 367e86e8 | bellard | ((src >> (count - 1)) & CC_C);
|
341 | 367e86e8 | bellard | CC_OP = CC_OP_EFLAGS; |
342 | 367e86e8 | bellard | } |
343 | 367e86e8 | bellard | } |
344 | 367e86e8 | bellard | |
345 | 367e86e8 | bellard | void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1_cc)(void) |
346 | 367e86e8 | bellard | { |
347 | 367e86e8 | bellard | int count;
|
348 | 367e86e8 | bellard | count = T1 & 0x1f;
|
349 | 367e86e8 | bellard | if (count == 1) { |
350 | 367e86e8 | bellard | CC_SRC = T0; |
351 | 367e86e8 | bellard | T0 = T0 << 1;
|
352 | 367e86e8 | bellard | CC_DST = T0; |
353 | 367e86e8 | bellard | CC_OP = CC_OP_ADDB + SHIFT; |
354 | 367e86e8 | bellard | } else if (count) { |
355 | 367e86e8 | bellard | CC_SRC = T0 >> (DATA_BITS - count); |
356 | 367e86e8 | bellard | T0 = T0 << count; |
357 | 367e86e8 | bellard | CC_DST = T0; |
358 | 367e86e8 | bellard | CC_OP = CC_OP_SHLB + SHIFT; |
359 | 367e86e8 | bellard | } |
360 | 367e86e8 | bellard | } |
361 | 367e86e8 | bellard | |
362 | 367e86e8 | bellard | void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1_cc)(void) |
363 | 367e86e8 | bellard | { |
364 | 367e86e8 | bellard | int count;
|
365 | 367e86e8 | bellard | count = T1 & 0x1f;
|
366 | 367e86e8 | bellard | if (count) {
|
367 | 367e86e8 | bellard | T0 &= DATA_MASK; |
368 | 367e86e8 | bellard | CC_SRC = T0 >> (count - 1);
|
369 | 367e86e8 | bellard | T0 = T0 >> count; |
370 | 367e86e8 | bellard | CC_DST = T0; |
371 | 367e86e8 | bellard | CC_OP = CC_OP_SHLB + SHIFT; |
372 | 367e86e8 | bellard | } |
373 | 367e86e8 | bellard | } |
374 | 367e86e8 | bellard | |
375 | 367e86e8 | bellard | void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1_cc)(void) |
376 | 367e86e8 | bellard | { |
377 | 367e86e8 | bellard | int count, src;
|
378 | 367e86e8 | bellard | count = T1 & 0x1f;
|
379 | 367e86e8 | bellard | if (count) {
|
380 | 367e86e8 | bellard | src = (DATA_STYPE)T0; |
381 | 367e86e8 | bellard | CC_SRC = src >> (count - 1);
|
382 | 367e86e8 | bellard | T0 = src >> count; |
383 | 367e86e8 | bellard | CC_DST = T0; |
384 | 367e86e8 | bellard | CC_OP = CC_OP_SHLB + SHIFT; |
385 | 367e86e8 | bellard | } |
386 | 367e86e8 | bellard | } |
387 | 367e86e8 | bellard | |
388 | 367e86e8 | bellard | /* string operations */
|
389 | 367e86e8 | bellard | /* XXX: maybe use lower level instructions to ease exception handling */
|
390 | 367e86e8 | bellard | |
391 | 367e86e8 | bellard | void OPPROTO glue(op_movs, SUFFIX)(void) |
392 | 367e86e8 | bellard | { |
393 | 367e86e8 | bellard | int v;
|
394 | 367e86e8 | bellard | v = glue(ldu, SUFFIX)((void *)ESI);
|
395 | 367e86e8 | bellard | glue(st, SUFFIX)((void *)EDI, v);
|
396 | 367e86e8 | bellard | ESI += (DF << SHIFT); |
397 | 367e86e8 | bellard | EDI += (DF << SHIFT); |
398 | 367e86e8 | bellard | } |
399 | 367e86e8 | bellard | |
400 | 367e86e8 | bellard | void OPPROTO glue(op_rep_movs, SUFFIX)(void) |
401 | 367e86e8 | bellard | { |
402 | 367e86e8 | bellard | int v, inc;
|
403 | 367e86e8 | bellard | inc = (DF << SHIFT); |
404 | 367e86e8 | bellard | while (ECX != 0) { |
405 | 367e86e8 | bellard | v = glue(ldu, SUFFIX)((void *)ESI);
|
406 | 367e86e8 | bellard | glue(st, SUFFIX)((void *)EDI, v);
|
407 | 367e86e8 | bellard | ESI += inc; |
408 | 367e86e8 | bellard | EDI += inc; |
409 | 367e86e8 | bellard | ECX--; |
410 | 367e86e8 | bellard | } |
411 | 367e86e8 | bellard | } |
412 | 367e86e8 | bellard | |
413 | 367e86e8 | bellard | void OPPROTO glue(op_stos, SUFFIX)(void) |
414 | 367e86e8 | bellard | { |
415 | 367e86e8 | bellard | glue(st, SUFFIX)((void *)EDI, EAX);
|
416 | 367e86e8 | bellard | EDI += (DF << SHIFT); |
417 | 367e86e8 | bellard | } |
418 | 367e86e8 | bellard | |
419 | 367e86e8 | bellard | void OPPROTO glue(op_rep_stos, SUFFIX)(void) |
420 | 367e86e8 | bellard | { |
421 | 367e86e8 | bellard | int inc;
|
422 | 367e86e8 | bellard | inc = (DF << SHIFT); |
423 | 367e86e8 | bellard | while (ECX != 0) { |
424 | 367e86e8 | bellard | glue(st, SUFFIX)((void *)EDI, EAX);
|
425 | 367e86e8 | bellard | EDI += inc; |
426 | 367e86e8 | bellard | ECX--; |
427 | 367e86e8 | bellard | } |
428 | 367e86e8 | bellard | } |
429 | 367e86e8 | bellard | |
430 | 367e86e8 | bellard | void OPPROTO glue(op_lods, SUFFIX)(void) |
431 | 367e86e8 | bellard | { |
432 | 367e86e8 | bellard | int v;
|
433 | 367e86e8 | bellard | v = glue(ldu, SUFFIX)((void *)ESI);
|
434 | 367e86e8 | bellard | #if SHIFT == 0 |
435 | 367e86e8 | bellard | EAX = (EAX & ~0xff) | v;
|
436 | 367e86e8 | bellard | #elif SHIFT == 1 |
437 | 367e86e8 | bellard | EAX = (EAX & ~0xffff) | v;
|
438 | 367e86e8 | bellard | #else
|
439 | 367e86e8 | bellard | EAX = v; |
440 | 367e86e8 | bellard | #endif
|
441 | 367e86e8 | bellard | ESI += (DF << SHIFT); |
442 | 367e86e8 | bellard | } |
443 | 367e86e8 | bellard | |
444 | 367e86e8 | bellard | /* don't know if it is used */
|
445 | 367e86e8 | bellard | void OPPROTO glue(op_rep_lods, SUFFIX)(void) |
446 | 367e86e8 | bellard | { |
447 | 367e86e8 | bellard | int v, inc;
|
448 | 367e86e8 | bellard | inc = (DF << SHIFT); |
449 | 367e86e8 | bellard | while (ECX != 0) { |
450 | 367e86e8 | bellard | v = glue(ldu, SUFFIX)((void *)ESI);
|
451 | 367e86e8 | bellard | #if SHIFT == 0 |
452 | 367e86e8 | bellard | EAX = (EAX & ~0xff) | v;
|
453 | 367e86e8 | bellard | #elif SHIFT == 1 |
454 | 367e86e8 | bellard | EAX = (EAX & ~0xffff) | v;
|
455 | 367e86e8 | bellard | #else
|
456 | 367e86e8 | bellard | EAX = v; |
457 | 367e86e8 | bellard | #endif
|
458 | 367e86e8 | bellard | ESI += inc; |
459 | 367e86e8 | bellard | ECX--; |
460 | 367e86e8 | bellard | } |
461 | 367e86e8 | bellard | } |
462 | 367e86e8 | bellard | |
463 | 367e86e8 | bellard | void OPPROTO glue(op_scas, SUFFIX)(void) |
464 | 367e86e8 | bellard | { |
465 | 367e86e8 | bellard | int v;
|
466 | 367e86e8 | bellard | |
467 | 367e86e8 | bellard | v = glue(ldu, SUFFIX)((void *)ESI);
|
468 | 367e86e8 | bellard | ESI += (DF << SHIFT); |
469 | 367e86e8 | bellard | CC_SRC = EAX; |
470 | 367e86e8 | bellard | CC_DST = EAX - v; |
471 | 367e86e8 | bellard | } |
472 | 367e86e8 | bellard | |
473 | 367e86e8 | bellard | void OPPROTO glue(op_repz_scas, SUFFIX)(void) |
474 | 367e86e8 | bellard | { |
475 | 367e86e8 | bellard | int v1, v2, inc;
|
476 | 367e86e8 | bellard | |
477 | 367e86e8 | bellard | if (ECX != 0) { |
478 | 367e86e8 | bellard | /* NOTE: the flags are not modified if ECX == 0 */
|
479 | 367e86e8 | bellard | #if SHIFT == 0 |
480 | 367e86e8 | bellard | v1 = EAX & 0xff;
|
481 | 367e86e8 | bellard | #elif SHIFT == 1 |
482 | 367e86e8 | bellard | v1 = EAX & 0xffff;
|
483 | 367e86e8 | bellard | #else
|
484 | 367e86e8 | bellard | v1 = EAX; |
485 | 367e86e8 | bellard | #endif
|
486 | 367e86e8 | bellard | inc = (DF << SHIFT); |
487 | 367e86e8 | bellard | do {
|
488 | 367e86e8 | bellard | v2 = glue(ldu, SUFFIX)((void *)ESI);
|
489 | 367e86e8 | bellard | if (v1 != v2)
|
490 | 367e86e8 | bellard | break;
|
491 | 367e86e8 | bellard | ESI += inc; |
492 | 367e86e8 | bellard | ECX--; |
493 | 367e86e8 | bellard | } while (ECX != 0); |
494 | 367e86e8 | bellard | CC_SRC = v1; |
495 | 367e86e8 | bellard | CC_DST = v1 - v2; |
496 | 367e86e8 | bellard | CC_OP = CC_OP_SUBB + SHIFT; |
497 | 367e86e8 | bellard | } |
498 | 367e86e8 | bellard | } |
499 | 367e86e8 | bellard | |
500 | 367e86e8 | bellard | void OPPROTO glue(op_repnz_scas, SUFFIX)(void) |
501 | 367e86e8 | bellard | { |
502 | 367e86e8 | bellard | int v1, v2, inc;
|
503 | 367e86e8 | bellard | |
504 | 367e86e8 | bellard | if (ECX != 0) { |
505 | 367e86e8 | bellard | /* NOTE: the flags are not modified if ECX == 0 */
|
506 | 367e86e8 | bellard | #if SHIFT == 0 |
507 | 367e86e8 | bellard | v1 = EAX & 0xff;
|
508 | 367e86e8 | bellard | #elif SHIFT == 1 |
509 | 367e86e8 | bellard | v1 = EAX & 0xffff;
|
510 | 367e86e8 | bellard | #else
|
511 | 367e86e8 | bellard | v1 = EAX; |
512 | 367e86e8 | bellard | #endif
|
513 | 367e86e8 | bellard | inc = (DF << SHIFT); |
514 | 367e86e8 | bellard | do {
|
515 | 367e86e8 | bellard | v2 = glue(ldu, SUFFIX)((void *)ESI);
|
516 | 367e86e8 | bellard | if (v1 == v2)
|
517 | 367e86e8 | bellard | break;
|
518 | 367e86e8 | bellard | ESI += inc; |
519 | 367e86e8 | bellard | ECX--; |
520 | 367e86e8 | bellard | } while (ECX != 0); |
521 | 367e86e8 | bellard | CC_SRC = v1; |
522 | 367e86e8 | bellard | CC_DST = v1 - v2; |
523 | 367e86e8 | bellard | CC_OP = CC_OP_SUBB + SHIFT; |
524 | 367e86e8 | bellard | } |
525 | 367e86e8 | bellard | } |
526 | 367e86e8 | bellard | |
527 | 367e86e8 | bellard | void OPPROTO glue(op_cmps, SUFFIX)(void) |
528 | 367e86e8 | bellard | { |
529 | 367e86e8 | bellard | int v1, v2;
|
530 | 367e86e8 | bellard | v1 = glue(ldu, SUFFIX)((void *)ESI);
|
531 | 367e86e8 | bellard | v2 = glue(ldu, SUFFIX)((void *)EDI);
|
532 | 367e86e8 | bellard | ESI += (DF << SHIFT); |
533 | 367e86e8 | bellard | EDI += (DF << SHIFT); |
534 | 367e86e8 | bellard | CC_SRC = v1; |
535 | 367e86e8 | bellard | CC_DST = v1 - v2; |
536 | 367e86e8 | bellard | } |
537 | 367e86e8 | bellard | |
538 | 367e86e8 | bellard | void OPPROTO glue(op_repz_cmps, SUFFIX)(void) |
539 | 367e86e8 | bellard | { |
540 | 367e86e8 | bellard | int v1, v2, inc;
|
541 | 367e86e8 | bellard | if (ECX != 0) { |
542 | 367e86e8 | bellard | inc = (DF << SHIFT); |
543 | 367e86e8 | bellard | do {
|
544 | 367e86e8 | bellard | v1 = glue(ldu, SUFFIX)((void *)ESI);
|
545 | 367e86e8 | bellard | v2 = glue(ldu, SUFFIX)((void *)EDI);
|
546 | 367e86e8 | bellard | if (v1 != v2)
|
547 | 367e86e8 | bellard | break;
|
548 | 367e86e8 | bellard | ESI += inc; |
549 | 367e86e8 | bellard | EDI += inc; |
550 | 367e86e8 | bellard | ECX--; |
551 | 367e86e8 | bellard | } while (ECX != 0); |
552 | 367e86e8 | bellard | CC_SRC = v1; |
553 | 367e86e8 | bellard | CC_DST = v1 - v2; |
554 | 367e86e8 | bellard | CC_OP = CC_OP_SUBB + SHIFT; |
555 | 367e86e8 | bellard | } |
556 | 367e86e8 | bellard | } |
557 | 367e86e8 | bellard | |
558 | 367e86e8 | bellard | void OPPROTO glue(op_repnz_cmps, SUFFIX)(void) |
559 | 367e86e8 | bellard | { |
560 | 367e86e8 | bellard | int v1, v2, inc;
|
561 | 367e86e8 | bellard | if (ECX != 0) { |
562 | 367e86e8 | bellard | inc = (DF << SHIFT); |
563 | 367e86e8 | bellard | do {
|
564 | 367e86e8 | bellard | v1 = glue(ldu, SUFFIX)((void *)ESI);
|
565 | 367e86e8 | bellard | v2 = glue(ldu, SUFFIX)((void *)EDI);
|
566 | 367e86e8 | bellard | if (v1 == v2)
|
567 | 367e86e8 | bellard | break;
|
568 | 367e86e8 | bellard | ESI += inc; |
569 | 367e86e8 | bellard | EDI += inc; |
570 | 367e86e8 | bellard | ECX--; |
571 | 367e86e8 | bellard | } while (ECX != 0); |
572 | 367e86e8 | bellard | CC_SRC = v1; |
573 | 367e86e8 | bellard | CC_DST = v1 - v2; |
574 | 367e86e8 | bellard | CC_OP = CC_OP_SUBB + SHIFT; |
575 | 367e86e8 | bellard | } |
576 | 367e86e8 | bellard | } |
577 | 367e86e8 | bellard | |
578 | 367e86e8 | bellard | void OPPROTO glue(op_outs, SUFFIX)(void) |
579 | 367e86e8 | bellard | { |
580 | 367e86e8 | bellard | int v, dx;
|
581 | 367e86e8 | bellard | dx = EDX & 0xffff;
|
582 | 367e86e8 | bellard | v = glue(ldu, SUFFIX)((void *)ESI);
|
583 | 367e86e8 | bellard | glue(port_out, SUFFIX)(dx, v); |
584 | 367e86e8 | bellard | ESI += (DF << SHIFT); |
585 | 367e86e8 | bellard | } |
586 | 367e86e8 | bellard | |
587 | 367e86e8 | bellard | void OPPROTO glue(op_rep_outs, SUFFIX)(void) |
588 | 367e86e8 | bellard | { |
589 | 367e86e8 | bellard | int v, dx, inc;
|
590 | 367e86e8 | bellard | inc = (DF << SHIFT); |
591 | 367e86e8 | bellard | dx = EDX & 0xffff;
|
592 | 367e86e8 | bellard | while (ECX != 0) { |
593 | 367e86e8 | bellard | v = glue(ldu, SUFFIX)((void *)ESI);
|
594 | 367e86e8 | bellard | glue(port_out, SUFFIX)(dx, v); |
595 | 367e86e8 | bellard | ESI += inc; |
596 | 367e86e8 | bellard | ECX--; |
597 | 367e86e8 | bellard | } |
598 | 367e86e8 | bellard | } |
599 | 367e86e8 | bellard | |
600 | 367e86e8 | bellard | void OPPROTO glue(op_ins, SUFFIX)(void) |
601 | 367e86e8 | bellard | { |
602 | 367e86e8 | bellard | int v, dx;
|
603 | 367e86e8 | bellard | dx = EDX & 0xffff;
|
604 | 367e86e8 | bellard | v = glue(port_in, SUFFIX)(dx); |
605 | 367e86e8 | bellard | glue(st, SUFFIX)((void *)EDI, v);
|
606 | 367e86e8 | bellard | EDI += (DF << SHIFT); |
607 | 367e86e8 | bellard | } |
608 | 367e86e8 | bellard | |
609 | 367e86e8 | bellard | void OPPROTO glue(op_rep_ins, SUFFIX)(void) |
610 | 367e86e8 | bellard | { |
611 | 367e86e8 | bellard | int v, dx, inc;
|
612 | 367e86e8 | bellard | inc = (DF << SHIFT); |
613 | 367e86e8 | bellard | dx = EDX & 0xffff;
|
614 | 367e86e8 | bellard | while (ECX != 0) { |
615 | 367e86e8 | bellard | v = glue(port_in, SUFFIX)(dx); |
616 | 367e86e8 | bellard | glue(st, SUFFIX)((void *)EDI, v);
|
617 | 367e86e8 | bellard | EDI += (DF << SHIFT); |
618 | 367e86e8 | bellard | ECX--; |
619 | 367e86e8 | bellard | } |
620 | 367e86e8 | bellard | } |
621 | 367e86e8 | bellard | |
622 | 367e86e8 | bellard | #undef DATA_BITS
|
623 | 367e86e8 | bellard | #undef SHIFT_MASK
|
624 | 367e86e8 | bellard | #undef SIGN_MASK
|
625 | 367e86e8 | bellard | #undef DATA_TYPE
|
626 | 367e86e8 | bellard | #undef DATA_STYPE
|
627 | 367e86e8 | bellard | #undef DATA_MASK
|
628 | 367e86e8 | bellard | #undef SUFFIX |