Mercurial > repos > blastem
comparison m68k_core_x86.c @ 1584:e01adbe1a75b
Fix instruction timing for a number of instructions with only a single operand
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 17 May 2018 00:43:16 -0700 |
parents | 5eb954b76e65 |
children | 15116d4fdf40 |
comparison
equal
deleted
inserted
replaced
1583:430dd12e4010 | 1584:e01adbe1a75b |
---|---|
740 | 740 |
741 //add cycles for prefetch | 741 //add cycles for prefetch |
742 cycles(&opts->gen, BUS); | 742 cycles(&opts->gen, BUS); |
743 } | 743 } |
744 | 744 |
745 void translate_m68k_clr(m68k_options * opts, m68kinst * inst) | |
746 { | |
747 code_info *code = &opts->gen.code; | |
748 update_flags(opts, N0|V0|C0|Z1); | |
749 int8_t reg = native_reg(&(inst->dst), opts); | |
750 if (reg >= 0) { | |
751 cycles(&opts->gen, (inst->extra.size == OPSIZE_LONG ? 6 : 4)); | |
752 xor_rr(code, reg, reg, inst->extra.size); | |
753 return; | |
754 } | |
755 host_ea dst_op; | |
756 //TODO: fix timing | |
757 translate_m68k_op(inst, &dst_op, opts, 1); | |
758 if (dst_op.mode == MODE_REG_DIRECT) { | |
759 xor_rr(code, dst_op.base, dst_op.base, inst->extra.size); | |
760 } else { | |
761 mov_irdisp(code, 0, dst_op.base, dst_op.disp, inst->extra.size); | |
762 } | |
763 m68k_save_result(inst, opts); | |
764 } | |
765 | |
766 void translate_m68k_ext(m68k_options * opts, m68kinst * inst) | 745 void translate_m68k_ext(m68k_options * opts, m68kinst * inst) |
767 { | 746 { |
768 code_info *code = &opts->gen.code; | 747 code_info *code = &opts->gen.code; |
769 host_ea dst_op; | 748 host_ea dst_op; |
770 uint8_t dst_size = inst->extra.size; | 749 uint8_t dst_size = inst->extra.size; |
778 cmp_ir(code, 0, opts->gen.scratch1, dst_size); | 757 cmp_ir(code, 0, opts->gen.scratch1, dst_size); |
779 mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, dst_size); | 758 mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, dst_size); |
780 } | 759 } |
781 inst->extra.size = dst_size; | 760 inst->extra.size = dst_size; |
782 update_flags(opts, N|V0|C0|Z); | 761 update_flags(opts, N|V0|C0|Z); |
762 cycles(&opts->gen, BUS); | |
783 //M68K EXT only operates on registers so no need for a call to save result here | 763 //M68K EXT only operates on registers so no need for a call to save result here |
784 } | 764 } |
785 | 765 |
786 uint8_t m68k_eval_cond(m68k_options * opts, uint8_t cc) | 766 uint8_t m68k_eval_cond(m68k_options * opts, uint8_t cc) |
787 { | 767 { |
1435 | 1415 |
1436 void op_r(code_info *code, m68kinst *inst, uint8_t dst, uint8_t size) | 1416 void op_r(code_info *code, m68kinst *inst, uint8_t dst, uint8_t size) |
1437 { | 1417 { |
1438 switch(inst->op) | 1418 switch(inst->op) |
1439 { | 1419 { |
1420 case M68K_CLR: xor_rr(code, dst, dst, size); break; | |
1440 case M68K_NEG: neg_r(code, dst, size); break; | 1421 case M68K_NEG: neg_r(code, dst, size); break; |
1441 case M68K_NOT: not_r(code, dst, size); cmp_ir(code, 0, dst, size); break; | 1422 case M68K_NOT: not_r(code, dst, size); cmp_ir(code, 0, dst, size); break; |
1442 case M68K_ROL: rol_clr(code, dst, size); break; | 1423 case M68K_ROL: rol_clr(code, dst, size); break; |
1443 case M68K_ROR: ror_clr(code, dst, size); break; | 1424 case M68K_ROR: ror_clr(code, dst, size); break; |
1444 case M68K_ROXL: rcl_clr(code, dst, size); break; | 1425 case M68K_ROXL: rcl_clr(code, dst, size); break; |
1450 | 1431 |
1451 void op_rdisp(code_info *code, m68kinst *inst, uint8_t dst, int32_t disp, uint8_t size) | 1432 void op_rdisp(code_info *code, m68kinst *inst, uint8_t dst, int32_t disp, uint8_t size) |
1452 { | 1433 { |
1453 switch(inst->op) | 1434 switch(inst->op) |
1454 { | 1435 { |
1436 case M68K_CLR: mov_irdisp(code, 0, dst, disp, size); break; | |
1455 case M68K_NEG: neg_rdisp(code, dst, disp, size); break; | 1437 case M68K_NEG: neg_rdisp(code, dst, disp, size); break; |
1456 case M68K_NOT: not_rdisp(code, dst, disp, size); cmp_irdisp(code, 0, dst, disp, size); break; | 1438 case M68K_NOT: not_rdisp(code, dst, disp, size); cmp_irdisp(code, 0, dst, disp, size); break; |
1457 case M68K_ROL: rol_clrdisp(code, dst, disp, size); break; | 1439 case M68K_ROL: rol_clrdisp(code, dst, disp, size); break; |
1458 case M68K_ROR: ror_clrdisp(code, dst, disp, size); break; | 1440 case M68K_ROR: ror_clrdisp(code, dst, disp, size); break; |
1459 case M68K_ROXL: rcl_clrdisp(code, dst, disp, size); break; | 1441 case M68K_ROXL: rcl_clrdisp(code, dst, disp, size); break; |
1464 } | 1446 } |
1465 | 1447 |
1466 void translate_m68k_unary(m68k_options *opts, m68kinst *inst, uint32_t flag_mask, host_ea *dst_op) | 1448 void translate_m68k_unary(m68k_options *opts, m68kinst *inst, uint32_t flag_mask, host_ea *dst_op) |
1467 { | 1449 { |
1468 code_info *code = &opts->gen.code; | 1450 code_info *code = &opts->gen.code; |
1469 cycles(&opts->gen, BUS); | 1451 uint32_t num_cycles = BUS; |
1452 if (inst->extra.size == OPSIZE_LONG && (inst->dst.addr_mode == MODE_REG || inst->dst.addr_mode == MODE_AREG)) { | |
1453 num_cycles += 2; | |
1454 } | |
1455 cycles(&opts->gen, num_cycles); | |
1470 if (dst_op->mode == MODE_REG_DIRECT) { | 1456 if (dst_op->mode == MODE_REG_DIRECT) { |
1471 op_r(code, inst, dst_op->base, inst->extra.size); | 1457 op_r(code, inst, dst_op->base, inst->extra.size); |
1472 } else { | 1458 } else { |
1473 op_rdisp(code, inst, dst_op->base, dst_op->disp, inst->extra.size); | 1459 op_rdisp(code, inst, dst_op->base, dst_op->disp, inst->extra.size); |
1474 } | 1460 } |