Mercurial > repos > blastem
comparison m68k_core_x86.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 | 2dde38c1744f |
comparison
equal
deleted
inserted
replaced
587:55c5b0f913ce | 588:963d5901f583 |
---|---|
262 void ldi_native(m68k_options *opts, int32_t value, uint8_t reg) | 262 void ldi_native(m68k_options *opts, int32_t value, uint8_t reg) |
263 { | 263 { |
264 mov_ir(&opts->gen.code, value, reg, SZ_D); | 264 mov_ir(&opts->gen.code, value, reg, SZ_D); |
265 } | 265 } |
266 | 266 |
267 void addi_native(m68k_options *opts, int32_t value, uint8_t reg) | |
268 { | |
269 add_ir(&opts->gen.code, value, reg, SZ_D); | |
270 } | |
271 | |
272 void subi_native(m68k_options *opts, int32_t value, uint8_t reg) | |
273 { | |
274 sub_ir(&opts->gen.code, value, reg, SZ_D); | |
275 } | |
276 | |
277 void push_native(m68k_options *opts, uint8_t reg) | |
278 { | |
279 push_r(&opts->gen.code, reg); | |
280 } | |
281 | |
282 void pop_native(m68k_options *opts, uint8_t reg) | |
283 { | |
284 pop_r(&opts->gen.code, reg); | |
285 } | |
286 | |
287 void sign_extend16_native(m68k_options *opts, uint8_t reg) | |
288 { | |
289 movsx_rr(&opts->gen.code, reg, reg, SZ_W, SZ_D); | |
290 } | |
291 | |
267 void addi_areg(m68k_options *opts, int32_t val, uint8_t reg) | 292 void addi_areg(m68k_options *opts, int32_t val, uint8_t reg) |
268 { | 293 { |
269 if (opts->aregs[reg] >= 0) { | 294 if (opts->aregs[reg] >= 0) { |
270 add_ir(&opts->gen.code, val, opts->aregs[reg], SZ_D); | 295 add_ir(&opts->gen.code, val, opts->aregs[reg], SZ_D); |
271 } else { | 296 } else { |
695 } | 720 } |
696 } | 721 } |
697 | 722 |
698 //add cycles for prefetch | 723 //add cycles for prefetch |
699 cycles(&opts->gen, BUS); | 724 cycles(&opts->gen, BUS); |
700 } | |
701 | |
702 void translate_m68k_movem(m68k_options * opts, m68kinst * inst) | |
703 { | |
704 code_info *code = &opts->gen.code; | |
705 int8_t bit,reg,sec_reg; | |
706 uint8_t early_cycles; | |
707 if(inst->src.addr_mode == MODE_REG) { | |
708 //reg to mem | |
709 early_cycles = 8; | |
710 int8_t dir; | |
711 switch (inst->dst.addr_mode) | |
712 { | |
713 case MODE_AREG_INDIRECT: | |
714 case MODE_AREG_PREDEC: | |
715 areg_to_native(opts, inst->dst.params.regs.pri, opts->gen.scratch2); | |
716 break; | |
717 case MODE_AREG_DISPLACE: | |
718 early_cycles += BUS; | |
719 calc_areg_displace(opts, &inst->dst, opts->gen.scratch2); | |
720 break; | |
721 case MODE_AREG_INDEX_DISP8: | |
722 early_cycles += 6; | |
723 calc_areg_index_disp8(opts, &inst->dst, opts->gen.scratch2); | |
724 break; | |
725 case MODE_PC_DISPLACE: | |
726 early_cycles += BUS; | |
727 mov_ir(code, inst->dst.params.regs.displacement + inst->address+2, opts->gen.scratch2, SZ_D); | |
728 break; | |
729 case MODE_PC_INDEX_DISP8: | |
730 early_cycles += 6; | |
731 mov_ir(code, inst->address+2, opts->gen.scratch2, SZ_D); | |
732 calc_index_disp8(opts, &inst->dst, opts->gen.scratch2); | |
733 case MODE_ABSOLUTE: | |
734 early_cycles += 4; | |
735 case MODE_ABSOLUTE_SHORT: | |
736 early_cycles += 4; | |
737 mov_ir(code, inst->dst.params.immed, opts->gen.scratch2, SZ_D); | |
738 break; | |
739 default: | |
740 m68k_disasm(inst, disasm_buf); | |
741 printf("%X: %s\naddress mode %d not implemented (movem dst)\n", inst->address, disasm_buf, inst->dst.addr_mode); | |
742 exit(1); | |
743 } | |
744 if (inst->dst.addr_mode == MODE_AREG_PREDEC) { | |
745 reg = 15; | |
746 dir = -1; | |
747 } else { | |
748 reg = 0; | |
749 dir = 1; | |
750 } | |
751 cycles(&opts->gen, early_cycles); | |
752 for(bit=0; reg < 16 && reg >= 0; reg += dir, bit++) { | |
753 if (inst->src.params.immed & (1 << bit)) { | |
754 if (inst->dst.addr_mode == MODE_AREG_PREDEC) { | |
755 sub_ir(code, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, opts->gen.scratch2, SZ_D); | |
756 } | |
757 push_r(code, opts->gen.scratch2); | |
758 if (reg > 7) { | |
759 areg_to_native(opts, reg-8, opts->gen.scratch1); | |
760 } else { | |
761 dreg_to_native(opts, reg, opts->gen.scratch1); | |
762 } | |
763 if (inst->extra.size == OPSIZE_LONG) { | |
764 call(code, opts->write_32_lowfirst); | |
765 } else { | |
766 call(code, opts->write_16); | |
767 } | |
768 pop_r(code, opts->gen.scratch2); | |
769 if (inst->dst.addr_mode != MODE_AREG_PREDEC) { | |
770 add_ir(code, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, opts->gen.scratch2, SZ_D); | |
771 } | |
772 } | |
773 } | |
774 if (inst->dst.addr_mode == MODE_AREG_PREDEC) { | |
775 native_to_areg(opts, opts->gen.scratch2, inst->dst.params.regs.pri); | |
776 } | |
777 } else { | |
778 //mem to reg | |
779 early_cycles = 4; | |
780 switch (inst->src.addr_mode) | |
781 { | |
782 case MODE_AREG_INDIRECT: | |
783 case MODE_AREG_POSTINC: | |
784 areg_to_native(opts, inst->src.params.regs.pri, opts->gen.scratch1); | |
785 break; | |
786 case MODE_AREG_DISPLACE: | |
787 early_cycles += BUS; | |
788 reg = opts->gen.scratch2; | |
789 calc_areg_displace(opts, &inst->src, opts->gen.scratch1); | |
790 break; | |
791 case MODE_AREG_INDEX_DISP8: | |
792 early_cycles += 6; | |
793 calc_areg_index_disp8(opts, &inst->src, opts->gen.scratch1); | |
794 break; | |
795 case MODE_PC_DISPLACE: | |
796 early_cycles += BUS; | |
797 mov_ir(code, inst->src.params.regs.displacement + inst->address+2, opts->gen.scratch1, SZ_D); | |
798 break; | |
799 case MODE_PC_INDEX_DISP8: | |
800 early_cycles += 6; | |
801 mov_ir(code, inst->address+2, opts->gen.scratch1, SZ_D); | |
802 calc_index_disp8(opts, &inst->src, opts->gen.scratch1); | |
803 break; | |
804 case MODE_ABSOLUTE: | |
805 early_cycles += 4; | |
806 case MODE_ABSOLUTE_SHORT: | |
807 early_cycles += 4; | |
808 mov_ir(code, inst->src.params.immed, opts->gen.scratch1, SZ_D); | |
809 break; | |
810 default: | |
811 m68k_disasm(inst, disasm_buf); | |
812 printf("%X: %s\naddress mode %d not implemented (movem src)\n", inst->address, disasm_buf, inst->src.addr_mode); | |
813 exit(1); | |
814 } | |
815 cycles(&opts->gen, early_cycles); | |
816 for(reg = 0; reg < 16; reg ++) { | |
817 if (inst->dst.params.immed & (1 << reg)) { | |
818 push_r(code, opts->gen.scratch1); | |
819 if (inst->extra.size == OPSIZE_LONG) { | |
820 call(code, opts->read_32); | |
821 } else { | |
822 call(code, opts->read_16); | |
823 } | |
824 if (inst->extra.size == OPSIZE_WORD) { | |
825 movsx_rr(code, opts->gen.scratch1, opts->gen.scratch1, SZ_W, SZ_D); | |
826 } | |
827 if (reg > 7) { | |
828 native_to_areg(opts, opts->gen.scratch1, reg-8); | |
829 } else { | |
830 native_to_dreg(opts, opts->gen.scratch1, reg); | |
831 } | |
832 pop_r(code, opts->gen.scratch1); | |
833 add_ir(code, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, opts->gen.scratch1, SZ_D); | |
834 } | |
835 } | |
836 if (inst->src.addr_mode == MODE_AREG_POSTINC) { | |
837 native_to_areg(opts, opts->gen.scratch1, inst->src.params.regs.pri); | |
838 } | |
839 } | |
840 //prefetch | |
841 cycles(&opts->gen, 4); | |
842 } | 725 } |
843 | 726 |
844 void translate_m68k_clr(m68k_options * opts, m68kinst * inst) | 727 void translate_m68k_clr(m68k_options * opts, m68kinst * inst) |
845 { | 728 { |
846 code_info *code = &opts->gen.code; | 729 code_info *code = &opts->gen.code; |