Mercurial > repos > blastem
comparison gen_x86.c @ 51:937b47c9b79b
Implement shift instructions (asl, lsl, asr, lsr). Add flags to register printout. Fix minor bug in shift/rotate instruction decoding.
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 15 Dec 2012 23:01:32 -0800 |
parents | d2e43d64e999 |
children | 918468c623e9 |
comparison
equal
deleted
inserted
replaced
50:4836d1f3841a | 51:937b47c9b79b |
---|---|
30 #define OP_MOV_IR 0xB8 | 30 #define OP_MOV_IR 0xB8 |
31 #define OP_SHIFTROT_IR 0xC0 | 31 #define OP_SHIFTROT_IR 0xC0 |
32 #define OP_RETN 0xC3 | 32 #define OP_RETN 0xC3 |
33 #define OP_MOV_IEA 0xC6 | 33 #define OP_MOV_IEA 0xC6 |
34 #define OP_SHIFTROT_1 0xD0 | 34 #define OP_SHIFTROT_1 0xD0 |
35 #define OP_SHIRTROT_CL 0xD2 | 35 #define OP_SHIFTROT_CL 0xD2 |
36 #define OP_CALL 0xE8 | 36 #define OP_CALL 0xE8 |
37 #define OP_JMP 0xE9 | 37 #define OP_JMP 0xE9 |
38 #define OP_JMP_BYTE 0xEB | 38 #define OP_JMP_BYTE 0xEB |
39 #define OP_CALL_EA 0xFF | 39 #define OP_CALL_EA 0xFF |
40 | 40 |
361 *(out++) = val; | 361 *(out++) = val; |
362 } | 362 } |
363 return out; | 363 return out; |
364 } | 364 } |
365 | 365 |
366 uint8_t * x86_shiftrot_clr(uint8_t * out, uint8_t op_ex, uint8_t dst, uint8_t size) | |
367 { | |
368 if (size == SZ_W) { | |
369 *(out++) = PRE_SIZE; | |
370 } | |
371 if (size == SZ_Q || dst >= R8 || (size == SZ_B && dst >= RSP && dst <= RDI)) { | |
372 *out = PRE_REX; | |
373 if (size == SZ_Q) { | |
374 *out |= REX_QUAD; | |
375 } | |
376 if (dst >= R8) { | |
377 *out |= REX_RM_FIELD; | |
378 dst -= (R8 - X86_R8); | |
379 } | |
380 out++; | |
381 } | |
382 if (dst >= AH && dst <= BH) { | |
383 dst -= (AH-X86_AH); | |
384 } | |
385 | |
386 *(out++) = OP_SHIFTROT_CL | (size == SZ_B ? 0 : BIT_SIZE); | |
387 *(out++) = MODE_REG_DIRECT | dst | (op_ex << 3); | |
388 return out; | |
389 } | |
390 | |
391 uint8_t * x86_shiftrot_clrdisp8(uint8_t * out, uint8_t op_ex, uint8_t dst, int8_t disp, uint8_t size) | |
392 { | |
393 if (size == SZ_W) { | |
394 *(out++) = PRE_SIZE; | |
395 } | |
396 if (size == SZ_Q || dst >= R8 || (size == SZ_B && dst >= RSP && dst <= RDI)) { | |
397 *out = PRE_REX; | |
398 if (size == SZ_Q) { | |
399 *out |= REX_QUAD; | |
400 } | |
401 if (dst >= R8) { | |
402 *out |= REX_RM_FIELD; | |
403 dst -= (R8 - X86_R8); | |
404 } | |
405 out++; | |
406 } | |
407 if (dst >= AH && dst <= BH) { | |
408 dst -= (AH-X86_AH); | |
409 } | |
410 | |
411 *(out++) = OP_SHIFTROT_CL | (size == SZ_B ? 0 : BIT_SIZE); | |
412 *(out++) = MODE_REG_DISPLACE8 | dst | (op_ex << 3); | |
413 *(out++) = disp; | |
414 return out; | |
415 } | |
416 | |
366 uint8_t * rol_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size) | 417 uint8_t * rol_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size) |
367 { | 418 { |
368 return x86_shiftrot_ir(out, OP_EX_ROL, val, dst, size); | 419 return x86_shiftrot_ir(out, OP_EX_ROL, val, dst, size); |
369 } | 420 } |
370 | 421 |
429 } | 480 } |
430 | 481 |
431 uint8_t * sar_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t disp, uint8_t size) | 482 uint8_t * sar_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t disp, uint8_t size) |
432 { | 483 { |
433 return x86_shiftrot_irdisp8(out, OP_EX_SAR, val, dst_base, disp, size); | 484 return x86_shiftrot_irdisp8(out, OP_EX_SAR, val, dst_base, disp, size); |
485 } | |
486 | |
487 uint8_t * rol_clr(uint8_t * out, uint8_t dst, uint8_t size) | |
488 { | |
489 return x86_shiftrot_clr(out, OP_EX_ROL, dst, size); | |
490 } | |
491 | |
492 uint8_t * ror_clr(uint8_t * out, uint8_t dst, uint8_t size) | |
493 { | |
494 return x86_shiftrot_clr(out, OP_EX_ROR, dst, size); | |
495 } | |
496 | |
497 uint8_t * rcl_clr(uint8_t * out, uint8_t dst, uint8_t size) | |
498 { | |
499 return x86_shiftrot_clr(out, OP_EX_RCL, dst, size); | |
500 } | |
501 | |
502 uint8_t * rcr_clr(uint8_t * out, uint8_t dst, uint8_t size) | |
503 { | |
504 return x86_shiftrot_clr(out, OP_EX_RCR, dst, size); | |
505 } | |
506 | |
507 uint8_t * shl_clr(uint8_t * out, uint8_t dst, uint8_t size) | |
508 { | |
509 return x86_shiftrot_clr(out, OP_EX_SHL, dst, size); | |
510 } | |
511 | |
512 uint8_t * shr_clr(uint8_t * out, uint8_t dst, uint8_t size) | |
513 { | |
514 return x86_shiftrot_clr(out, OP_EX_SHR, dst, size); | |
515 } | |
516 | |
517 uint8_t * sar_clr(uint8_t * out, uint8_t dst, uint8_t size) | |
518 { | |
519 return x86_shiftrot_clr(out, OP_EX_SAR, dst, size); | |
520 } | |
521 | |
522 uint8_t * rol_clrdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) | |
523 { | |
524 return x86_shiftrot_clrdisp8(out, OP_EX_ROL, dst_base, disp, size); | |
525 } | |
526 | |
527 uint8_t * ror_clrdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) | |
528 { | |
529 return x86_shiftrot_clrdisp8(out, OP_EX_ROR, dst_base, disp, size); | |
530 } | |
531 | |
532 uint8_t * rcl_clrdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) | |
533 { | |
534 return x86_shiftrot_clrdisp8(out, OP_EX_RCL, dst_base, disp, size); | |
535 } | |
536 | |
537 uint8_t * rcr_clrdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) | |
538 { | |
539 return x86_shiftrot_clrdisp8(out, OP_EX_RCR, dst_base, disp, size); | |
540 } | |
541 | |
542 uint8_t * shl_clrdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) | |
543 { | |
544 return x86_shiftrot_clrdisp8(out, OP_EX_SHL, dst_base, disp, size); | |
545 } | |
546 | |
547 uint8_t * shr_clrdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) | |
548 { | |
549 return x86_shiftrot_clrdisp8(out, OP_EX_SHR, dst_base, disp, size); | |
550 } | |
551 | |
552 uint8_t * sar_clrdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) | |
553 { | |
554 return x86_shiftrot_clrdisp8(out, OP_EX_SAR, dst_base, disp, size); | |
434 } | 555 } |
435 | 556 |
436 uint8_t * add_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) | 557 uint8_t * add_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) |
437 { | 558 { |
438 return x86_rr_sizedir(out, OP_ADD, src, dst, size); | 559 return x86_rr_sizedir(out, OP_ADD, src, dst, size); |