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