comparison m68k_core.c @ 588:963d5901f583

Move translate_m68k_movem to m68k_core.c
author Michael Pavone <pavone@retrodev.com>
date Sat, 08 Mar 2014 00:15:09 -0800
parents 55c5b0f913ce
children 60a06c025103
comparison
equal deleted inserted replaced
587:55c5b0f913ce 588:963d5901f583
345 reg = opts->gen.scratch1; 345 reg = opts->gen.scratch1;
346 areg_to_native(opts, inst->src.params.regs.pri, reg); 346 areg_to_native(opts, inst->src.params.regs.pri, reg);
347 } 347 }
348 native_to_areg(opts, reg, 8); 348 native_to_areg(opts, reg, 8);
349 } 349 }
350 }
351
352 void translate_m68k_movem(m68k_options * opts, m68kinst * inst)
353 {
354 code_info *code = &opts->gen.code;
355 int8_t bit,reg,sec_reg;
356 uint8_t early_cycles;
357 if(inst->src.addr_mode == MODE_REG) {
358 //reg to mem
359 early_cycles = 8;
360 int8_t dir;
361 switch (inst->dst.addr_mode)
362 {
363 case MODE_AREG_INDIRECT:
364 case MODE_AREG_PREDEC:
365 areg_to_native(opts, inst->dst.params.regs.pri, opts->gen.scratch2);
366 break;
367 case MODE_AREG_DISPLACE:
368 early_cycles += BUS;
369 calc_areg_displace(opts, &inst->dst, opts->gen.scratch2);
370 break;
371 case MODE_AREG_INDEX_DISP8:
372 early_cycles += 6;
373 calc_areg_index_disp8(opts, &inst->dst, opts->gen.scratch2);
374 break;
375 case MODE_PC_DISPLACE:
376 early_cycles += BUS;
377 ldi_native(opts, inst->dst.params.regs.displacement + inst->address+2, opts->gen.scratch2);
378 break;
379 case MODE_PC_INDEX_DISP8:
380 early_cycles += 6;
381 ldi_native(opts, inst->address+2, opts->gen.scratch2);
382 calc_index_disp8(opts, &inst->dst, opts->gen.scratch2);
383 case MODE_ABSOLUTE:
384 early_cycles += 4;
385 case MODE_ABSOLUTE_SHORT:
386 early_cycles += 4;
387 ldi_native(opts, inst->dst.params.immed, opts->gen.scratch2);
388 break;
389 default:
390 m68k_disasm(inst, disasm_buf);
391 printf("%X: %s\naddress mode %d not implemented (movem dst)\n", inst->address, disasm_buf, inst->dst.addr_mode);
392 exit(1);
393 }
394 if (inst->dst.addr_mode == MODE_AREG_PREDEC) {
395 reg = 15;
396 dir = -1;
397 } else {
398 reg = 0;
399 dir = 1;
400 }
401 cycles(&opts->gen, early_cycles);
402 for(bit=0; reg < 16 && reg >= 0; reg += dir, bit++) {
403 if (inst->src.params.immed & (1 << bit)) {
404 if (inst->dst.addr_mode == MODE_AREG_PREDEC) {
405 subi_native(opts, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, opts->gen.scratch2);
406 }
407 push_native(opts, opts->gen.scratch2);
408 if (reg > 7) {
409 areg_to_native(opts, reg-8, opts->gen.scratch1);
410 } else {
411 dreg_to_native(opts, reg, opts->gen.scratch1);
412 }
413 if (inst->extra.size == OPSIZE_LONG) {
414 call(code, opts->write_32_lowfirst);
415 } else {
416 call(code, opts->write_16);
417 }
418 pop_native(opts, opts->gen.scratch2);
419 if (inst->dst.addr_mode != MODE_AREG_PREDEC) {
420 addi_native(opts, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, opts->gen.scratch2);
421 }
422 }
423 }
424 if (inst->dst.addr_mode == MODE_AREG_PREDEC) {
425 native_to_areg(opts, opts->gen.scratch2, inst->dst.params.regs.pri);
426 }
427 } else {
428 //mem to reg
429 early_cycles = 4;
430 switch (inst->src.addr_mode)
431 {
432 case MODE_AREG_INDIRECT:
433 case MODE_AREG_POSTINC:
434 areg_to_native(opts, inst->src.params.regs.pri, opts->gen.scratch1);
435 break;
436 case MODE_AREG_DISPLACE:
437 early_cycles += BUS;
438 reg = opts->gen.scratch2;
439 calc_areg_displace(opts, &inst->src, opts->gen.scratch1);
440 break;
441 case MODE_AREG_INDEX_DISP8:
442 early_cycles += 6;
443 calc_areg_index_disp8(opts, &inst->src, opts->gen.scratch1);
444 break;
445 case MODE_PC_DISPLACE:
446 early_cycles += BUS;
447 ldi_native(opts, inst->src.params.regs.displacement + inst->address+2, opts->gen.scratch1);
448 break;
449 case MODE_PC_INDEX_DISP8:
450 early_cycles += 6;
451 ldi_native(opts, inst->address+2, opts->gen.scratch1);
452 calc_index_disp8(opts, &inst->src, opts->gen.scratch1);
453 break;
454 case MODE_ABSOLUTE:
455 early_cycles += 4;
456 case MODE_ABSOLUTE_SHORT:
457 early_cycles += 4;
458 ldi_native(opts, inst->src.params.immed, opts->gen.scratch1);
459 break;
460 default:
461 m68k_disasm(inst, disasm_buf);
462 printf("%X: %s\naddress mode %d not implemented (movem src)\n", inst->address, disasm_buf, inst->src.addr_mode);
463 exit(1);
464 }
465 cycles(&opts->gen, early_cycles);
466 for(reg = 0; reg < 16; reg ++) {
467 if (inst->dst.params.immed & (1 << reg)) {
468 push_native(opts, opts->gen.scratch1);
469 if (inst->extra.size == OPSIZE_LONG) {
470 call(code, opts->read_32);
471 } else {
472 call(code, opts->read_16);
473 }
474 if (inst->extra.size == OPSIZE_WORD) {
475 sign_extend16_native(opts, opts->gen.scratch1);
476 }
477 if (reg > 7) {
478 native_to_areg(opts, opts->gen.scratch1, reg-8);
479 } else {
480 native_to_dreg(opts, opts->gen.scratch1, reg);
481 }
482 pop_native(opts, opts->gen.scratch1);
483 addi_native(opts, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, opts->gen.scratch1);
484 }
485 }
486 if (inst->src.addr_mode == MODE_AREG_POSTINC) {
487 native_to_areg(opts, opts->gen.scratch1, inst->src.params.regs.pri);
488 }
489 }
490 //prefetch
491 cycles(&opts->gen, 4);
350 } 492 }
351 493
352 void translate_m68k_nop(m68k_options *opts, m68kinst *inst) 494 void translate_m68k_nop(m68k_options *opts, m68kinst *inst)
353 { 495 {
354 cycles(&opts->gen, BUS); 496 cycles(&opts->gen, BUS);