comparison m68k_core.c @ 582:c05fcbfe1b1a

Refactored translate_m68k so that it contains no host-cpu specific code and moved it to m68k_core.c
author Michael Pavone <pavone@retrodev.com>
date Fri, 07 Mar 2014 17:42:29 -0800
parents 9f40aa5243c2
children b6713c1b6f55
comparison
equal deleted inserted replaced
581:9f40aa5243c2 582:c05fcbfe1b1a
324 ldi_native(opts, inst->src.params.immed + VECTOR_TRAP_0, opts->gen.scratch2); 324 ldi_native(opts, inst->src.params.immed + VECTOR_TRAP_0, opts->gen.scratch2);
325 ldi_native(opts, inst->address+2, opts->gen.scratch1); 325 ldi_native(opts, inst->address+2, opts->gen.scratch1);
326 jmp(code, opts->trap); 326 jmp(code, opts->trap);
327 } 327 }
328 328
329 void translate_m68k_move_usp(m68k_options *opts, m68kinst *inst)
330 {
331 cycles(&opts->gen, BUS);
332 int8_t reg;
333 if (inst->src.addr_mode == MODE_UNUSED) {
334 reg = native_reg(&inst->dst, opts);
335 if (reg < 0) {
336 reg = opts->gen.scratch1;
337 }
338 areg_to_native(opts, 8, reg);
339 if (reg == opts->gen.scratch1) {
340 native_to_areg(opts, opts->gen.scratch1, inst->dst.params.regs.pri);
341 }
342 } else {
343 reg = native_reg(&inst->src, opts);
344 if (reg < 0) {
345 reg = opts->gen.scratch1;
346 areg_to_native(opts, inst->src.params.regs.pri, reg);
347 }
348 native_to_areg(opts, reg, 8);
349 }
350 }
351
352 void translate_m68k_nop(m68k_options *opts, m68kinst *inst)
353 {
354 cycles(&opts->gen, BUS);
355 }
356
329 void swap_ssp_usp(m68k_options * opts) 357 void swap_ssp_usp(m68k_options * opts)
330 { 358 {
331 areg_to_native(opts, 7, opts->gen.scratch2); 359 areg_to_native(opts, 7, opts->gen.scratch2);
332 areg_to_native(opts, 8, opts->aregs[7]); 360 areg_to_native(opts, 8, opts->aregs[7]);
333 native_to_areg(opts, opts->gen.scratch2, 8); 361 native_to_areg(opts, opts->gen.scratch2, 8);
430 { 458 {
431 m68k_options * opts = context->options; 459 m68k_options * opts = context->options;
432 process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context); 460 process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context);
433 if (opts->gen.deferred) { 461 if (opts->gen.deferred) {
434 translate_m68k_stream(opts->gen.deferred->address, context); 462 translate_m68k_stream(opts->gen.deferred->address, context);
463 }
464 }
465
466 typedef enum {
467 RAW_FUNC = 1,
468 BINARY_ARITH,
469 UNARY_ARITH,
470 OP_FUNC
471 } impl_type;
472
473 typedef void (*raw_fun)(m68k_options * opts, m68kinst *inst);
474 typedef void (*op_fun)(m68k_options * opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op);
475
476 typedef struct {
477 union {
478 raw_fun raw;
479 uint32_t flag_mask;
480 op_fun op;
481 } impl;
482 impl_type itype;
483 } impl_info;
484
485 #define RAW_IMPL(inst, fun) [inst] = { .impl = { .raw = fun }, .itype = RAW_FUNC }
486 #define OP_IMPL(inst, fun) [inst] = { .impl = { .op = fun }, .itype = OP_FUNC }
487 #define UNARY_IMPL(inst, mask) [inst] = { .impl = { .flag_mask = mask }, .itype = UNARY_ARITH }
488 #define BINARY_IMPL(inst, mask) [inst] = { .impl = { .flag_mask = mask}, .itype = BINARY_ARITH }
489
490 impl_info m68k_impls[] = {
491 //math
492 BINARY_IMPL(M68K_ADD, X|N|Z|V|C),
493 BINARY_IMPL(M68K_SUB, X|N|Z|V|C),
494 //z flag is special cased for ADDX/SUBX
495 BINARY_IMPL(M68K_ADDX, X|N|V|C),
496 BINARY_IMPL(M68K_SUBX, X|N|V|C),
497 OP_IMPL(M68K_ABCD, translate_m68k_abcd_sbcd),
498 OP_IMPL(M68K_SBCD, translate_m68k_abcd_sbcd),
499 BINARY_IMPL(M68K_AND, N|Z|V0|C0),
500 BINARY_IMPL(M68K_EOR, N|Z|V0|C0),
501 BINARY_IMPL(M68K_OR, N|Z|V0|C0),
502 RAW_IMPL(M68K_CMP, translate_m68k_cmp),
503 OP_IMPL(M68K_DIVS, translate_m68k_div),
504 OP_IMPL(M68K_DIVU, translate_m68k_div),
505 OP_IMPL(M68K_MULS, translate_m68k_mul),
506 OP_IMPL(M68K_MULU, translate_m68k_mul),
507 RAW_IMPL(M68K_EXT, translate_m68k_ext),
508 UNARY_IMPL(M68K_NEG, X|N|Z|V|C),
509 OP_IMPL(M68K_NEGX, translate_m68k_negx),
510 UNARY_IMPL(M68K_NOT, X|N|Z|V|C),
511 UNARY_IMPL(M68K_TST, N|Z|V0|C0),
512
513 //shift/rotate
514 OP_IMPL(M68K_ASL, translate_m68k_sl),
515 OP_IMPL(M68K_LSL, translate_m68k_sl),
516 OP_IMPL(M68K_ASR, translate_m68k_asr),
517 OP_IMPL(M68K_LSR, translate_m68k_lsr),
518 OP_IMPL(M68K_ROL, translate_m68k_rot),
519 OP_IMPL(M68K_ROR, translate_m68k_rot),
520 OP_IMPL(M68K_ROXL, translate_m68k_rot),
521 OP_IMPL(M68K_ROXR, translate_m68k_rot),
522 UNARY_IMPL(M68K_SWAP, N|Z|V0|C0),
523
524 //bit
525 OP_IMPL(M68K_BCHG, translate_m68k_bit),
526 OP_IMPL(M68K_BCLR, translate_m68k_bit),
527 OP_IMPL(M68K_BSET, translate_m68k_bit),
528 OP_IMPL(M68K_BTST, translate_m68k_bit),
529
530 //data movement
531 RAW_IMPL(M68K_MOVE, translate_m68k_move),
532 RAW_IMPL(M68K_MOVEM, translate_m68k_movem),
533 RAW_IMPL(M68K_MOVEP, translate_m68k_movep),
534 RAW_IMPL(M68K_MOVE_USP, translate_m68k_move_usp),
535 RAW_IMPL(M68K_LEA, translate_m68k_lea_pea),
536 RAW_IMPL(M68K_PEA, translate_m68k_lea_pea),
537 RAW_IMPL(M68K_CLR, translate_m68k_clr),
538 OP_IMPL(M68K_EXG, translate_m68k_exg),
539 RAW_IMPL(M68K_SCC, translate_m68k_scc),
540
541 //function calls and branches
542 RAW_IMPL(M68K_BCC, translate_m68k_bcc),
543 RAW_IMPL(M68K_BSR, translate_m68k_bsr),
544 RAW_IMPL(M68K_DBCC, translate_m68k_dbcc),
545 RAW_IMPL(M68K_JMP, translate_m68k_jmp_jsr),
546 RAW_IMPL(M68K_JSR, translate_m68k_jmp_jsr),
547 RAW_IMPL(M68K_RTS, translate_m68k_rts),
548 RAW_IMPL(M68K_RTE, translate_m68k_rte),
549 RAW_IMPL(M68K_RTR, translate_m68k_rtr),
550 RAW_IMPL(M68K_LINK, translate_m68k_link),
551 RAW_IMPL(M68K_UNLK, translate_m68k_unlk),
552
553 //SR/CCR stuff
554 RAW_IMPL(M68K_ANDI_CCR, translate_m68k_andi_ccr_sr),
555 RAW_IMPL(M68K_ANDI_SR, translate_m68k_andi_ccr_sr),
556 RAW_IMPL(M68K_EORI_CCR, translate_m68k_eori_ccr_sr),
557 RAW_IMPL(M68K_EORI_SR, translate_m68k_eori_ccr_sr),
558 RAW_IMPL(M68K_ORI_CCR, translate_m68k_ori_ccr_sr),
559 RAW_IMPL(M68K_ORI_SR, translate_m68k_ori_ccr_sr),
560 OP_IMPL(M68K_MOVE_CCR, translate_m68k_move_ccr_sr),
561 OP_IMPL(M68K_MOVE_SR, translate_m68k_move_ccr_sr),
562 OP_IMPL(M68K_MOVE_FROM_SR, translate_m68k_move_from_sr),
563 RAW_IMPL(M68K_STOP, translate_m68k_stop),
564
565 //traps
566 OP_IMPL(M68K_CHK, translate_m68k_chk),
567 RAW_IMPL(M68K_TRAP, translate_m68k_trap),
568 RAW_IMPL(M68K_ILLEGAL, translate_m68k_illegal),
569 RAW_IMPL(M68K_INVALID, translate_m68k_invalid),
570
571 //misc
572 RAW_IMPL(M68K_NOP, translate_m68k_nop),
573 RAW_IMPL(M68K_RESET, translate_m68k_reset),
574
575 //currently unimplemented
576 //M68K_NBCD
577 //M68K_TAS
578 //M68K_TRAPV
579 };
580
581 void translate_m68k(m68k_options * opts, m68kinst * inst)
582 {
583 check_cycles_int(&opts->gen, inst->address);
584 impl_info * info = m68k_impls + inst->op;
585 if (info->itype == RAW_FUNC) {
586 info->impl.raw(opts, inst);
587 return;
588 }
589
590 host_ea src_op, dst_op;
591 if (inst->src.addr_mode != MODE_UNUSED) {
592 translate_m68k_op(inst, &src_op, opts, 0);
593 }
594 if (inst->dst.addr_mode != MODE_UNUSED) {
595 translate_m68k_op(inst, &dst_op, opts, 1);
596 }
597 if (info->itype == OP_FUNC) {
598 info->impl.op(opts, inst, &src_op, &dst_op);
599 } else if (info->itype == BINARY_ARITH) {
600 translate_m68k_arith(opts, inst, info->impl.flag_mask, &src_op, &dst_op);
601 } else if (info->itype == UNARY_ARITH) {
602 translate_m68k_unary(opts, inst, info->impl.flag_mask, inst->dst.addr_mode != MODE_UNUSED ? &dst_op : &src_op);
603 } else {
604 m68k_disasm(inst, disasm_buf);
605 printf("%X: %s\ninstruction %d not yet implemented\n", inst->address, disasm_buf, inst->op);
606 exit(1);
435 } 607 }
436 } 608 }
437 609
438 void translate_m68k_stream(uint32_t address, m68k_context * context) 610 void translate_m68k_stream(uint32_t address, m68k_context * context)
439 { 611 {