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 }