Revision 9de5e440 op-i386.c
b/op-i386.c | ||
---|---|---|
119 | 119 |
return x >> (-n); |
120 | 120 |
} |
121 | 121 |
|
122 |
/* exception support */ |
|
123 |
/* NOTE: not static to force relocation generation by GCC */ |
|
124 |
void raise_exception(int exception_index) |
|
125 |
{ |
|
126 |
/* NOTE: the register at this point must be saved by hand because |
|
127 |
longjmp restore them */ |
|
128 |
#ifdef reg_EAX |
|
129 |
env->regs[R_EAX] = EAX; |
|
130 |
#endif |
|
131 |
#ifdef reg_ECX |
|
132 |
env->regs[R_ECX] = ECX; |
|
133 |
#endif |
|
134 |
#ifdef reg_EDX |
|
135 |
env->regs[R_EDX] = EDX; |
|
136 |
#endif |
|
137 |
#ifdef reg_EBX |
|
138 |
env->regs[R_EBX] = EBX; |
|
139 |
#endif |
|
140 |
#ifdef reg_ESP |
|
141 |
env->regs[R_ESP] = ESP; |
|
142 |
#endif |
|
143 |
#ifdef reg_EBP |
|
144 |
env->regs[R_EBP] = EBP; |
|
145 |
#endif |
|
146 |
#ifdef reg_ESI |
|
147 |
env->regs[R_ESI] = ESI; |
|
148 |
#endif |
|
149 |
#ifdef reg_EDI |
|
150 |
env->regs[R_EDI] = EDI; |
|
151 |
#endif |
|
152 |
env->exception_index = exception_index; |
|
153 |
longjmp(env->jmp_env, 1); |
|
154 |
} |
|
155 |
|
|
156 | 122 |
/* we define the various pieces of code used by the JIT */ |
157 | 123 |
|
158 | 124 |
#define REG EAX |
... | ... | |
391 | 357 |
} |
392 | 358 |
|
393 | 359 |
/* division, flags are undefined */ |
394 |
/* XXX: add exceptions for overflow & div by zero */
|
|
360 |
/* XXX: add exceptions for overflow */ |
|
395 | 361 |
void OPPROTO op_divb_AL_T0(void) |
396 | 362 |
{ |
397 | 363 |
unsigned int num, den, q, r; |
398 | 364 |
|
399 | 365 |
num = (EAX & 0xffff); |
400 | 366 |
den = (T0 & 0xff); |
367 |
if (den == 0) |
|
368 |
raise_exception(EXCP00_DIVZ); |
|
401 | 369 |
q = (num / den) & 0xff; |
402 | 370 |
r = (num % den) & 0xff; |
403 | 371 |
EAX = (EAX & 0xffff0000) | (r << 8) | q; |
... | ... | |
409 | 377 |
|
410 | 378 |
num = (int16_t)EAX; |
411 | 379 |
den = (int8_t)T0; |
380 |
if (den == 0) |
|
381 |
raise_exception(EXCP00_DIVZ); |
|
412 | 382 |
q = (num / den) & 0xff; |
413 | 383 |
r = (num % den) & 0xff; |
414 | 384 |
EAX = (EAX & 0xffff0000) | (r << 8) | q; |
... | ... | |
420 | 390 |
|
421 | 391 |
num = (EAX & 0xffff) | ((EDX & 0xffff) << 16); |
422 | 392 |
den = (T0 & 0xffff); |
393 |
if (den == 0) |
|
394 |
raise_exception(EXCP00_DIVZ); |
|
423 | 395 |
q = (num / den) & 0xffff; |
424 | 396 |
r = (num % den) & 0xffff; |
425 | 397 |
EAX = (EAX & 0xffff0000) | q; |
... | ... | |
432 | 404 |
|
433 | 405 |
num = (EAX & 0xffff) | ((EDX & 0xffff) << 16); |
434 | 406 |
den = (int16_t)T0; |
407 |
if (den == 0) |
|
408 |
raise_exception(EXCP00_DIVZ); |
|
435 | 409 |
q = (num / den) & 0xffff; |
436 | 410 |
r = (num % den) & 0xffff; |
437 | 411 |
EAX = (EAX & 0xffff0000) | q; |
... | ... | |
445 | 419 |
|
446 | 420 |
num = EAX | ((uint64_t)EDX << 32); |
447 | 421 |
den = T0; |
422 |
if (den == 0) |
|
423 |
raise_exception(EXCP00_DIVZ); |
|
448 | 424 |
q = (num / den); |
449 | 425 |
r = (num % den); |
450 | 426 |
EAX = q; |
... | ... | |
458 | 434 |
|
459 | 435 |
num = EAX | ((uint64_t)EDX << 32); |
460 | 436 |
den = T0; |
437 |
if (den == 0) |
|
438 |
raise_exception(EXCP00_DIVZ); |
|
461 | 439 |
q = (num / den); |
462 | 440 |
r = (num % den); |
463 | 441 |
EAX = q; |
Also available in: Unified diff