comparison m68k.cpu @ 2562:595719fe69f2

Implement exg, muls and mulu in new 68K core
author Michael Pavone <pavone@retrodev.com>
date Sat, 25 Jan 2025 21:25:01 -0800
parents ad50530a7c27
children 5f725429d08f
comparison
equal deleted inserted replaced
2561:8dc8eb079584 2562:595719fe69f2
129 ocall read_16 129 ocall read_16
130 xchg scratch1 tmp 130 xchg scratch1 tmp
131 ocall read_16 131 ocall read_16
132 lsl tmp 16 tmp 132 lsl tmp 16 tmp
133 or tmp scratch1 scratch1 133 or tmp scratch1 scratch1
134
135 m68k_trap
136 arg vector 32
137 check_user_mode_swap_ssp_usp
138 #save PC
139 a7 -= 4
140 scratch2 = a7
141 m68k_write32_lowfirst pc
142 #save SR
143 a7 -= 2
144 scratch2 = a7
145 m68k_get_sr
146 ocall write_16
147 #set supervisor bit
148 status |= 0x20
149 #clear trace bit
150 status &= 0x7F
151 trace_pending = 0
152 scratch1 = vector << 2
153 m68k_read32
154 pc = scratch1
155 cycles 10
156 m68k_prefetch
157
158
134 159
135 m68k_interrupt 160 m68k_interrupt
136 cmp int_cycle cycles 161 cmp int_cycle cycles
137 if >=U 162 if >=U
138 163
643 m68k_fetch_src_ea M R Z 668 m68k_fetch_src_ea M R Z
644 669
645 and src dregs.D dregs.D Z 670 and src dregs.D dregs.D Z
646 update_flags NZV0C0 671 update_flags NZV0C0
647 m68k_prefetch 672 m68k_prefetch
673
674 1100XXX101000YYY exg_dn_dn
675 scratch1 = dregs.X
676 dregs.X = dregs.Y
677 dregs.Y = scratch1
678 cycles 2
679 m68k_prefetch
680
681 1100XXX101001YYY exg_an_an
682 scratch1 = aregs.X
683 aregs.X = aregs.Y
684 aregs.Y = scratch1
685 cycles 2
686 m68k_prefetch
687
688 1100XXX110001YYY exg_dn_an
689 scratch1 = dregs.X
690 dregs.X = aregs.Y
691 aregs.Y = scratch1
692 cycles 2
693 m68k_prefetch
694
695 1100DDD011MMMRRR mulu
696 local a 16
697 local b 16
698 invalid M 1
699 invalid M 7 R 5
700 invalid M 7 R 6
701 invalid M 7 R 7
702
703 m68k_fetch_src_ea M R 1
704 #2-cycles per bit x 16, 2 for cleanup
705 cycles 34
706 #popcnt
707 a = src & 0b1010101010101010
708 a >>= 1
709 b = src & 0b0101010101010101
710 b += a
711 a = b & 0b1100110011001100
712 a >>= 2
713 b &= 0b0011001100110011
714 b += a
715 a = b & 0b1111000011110000
716 a >>= 4
717 b &= 0b0000111100001111
718 b += a
719 a = b & 0b1111111100000000
720 a >>= 8
721 b &= 0b0000000011111111
722 b += a
723 #2 cycles per set bit
724 b += b
725 cycles b
726 dregs.D = src * dregs.D
727 update_flags NZV0C0
728 m68k_prefetch
729
730 1100DDD111MMMRRR muls
731 local a 16
732 local b 16
733 invalid M 1
734 invalid M 7 R 5
735 invalid M 7 R 6
736 invalid M 7 R 7
737
738 m68k_fetch_src_ea M R 1
739 #2-cycles per bit x 16, 2 for cleanup
740 cycles 34
741 #muls timing is essentially the same as muls, but it's based on the number of 0/1
742 #transitions rather than the number of 1 bits. xoring the value with itself shifted
743 #by one effectively sets one bit for every transition
744 b = src << 1
745 b ^= src
746 #popcnt
747 a = b & 0b1010101010101010
748 a >>= 1
749 b &= 0b0101010101010101
750 b += a
751 a = b & 0b1100110011001100
752 a >>= 2
753 b &= 0b0011001100110011
754 b += a
755 a = b & 0b1111000011110000
756 a >>= 4
757 b &= 0b0000111100001111
758 b += a
759 a = b & 0b1111111100000000
760 a >>= 8
761 b &= 0b0000000011111111
762 b += a
763 #2 cycles per set bit
764 b += b
765 cycles b
766 dregs.D = src *S dregs.D
767 update_flags NZV0C0
768 m68k_prefetch
648 769
649 1100DDD1ZZMMMRRR and_dn_ea 770 1100DDD1ZZMMMRRR and_dn_ea
650 invalid M 0 771 invalid M 0
651 invalid M 1 772 invalid M 1
652 invalid M 7 R 2 773 invalid M 7 R 2
1873 meta bits 16 1994 meta bits 16
1874 end 1995 end
1875 sext bits dregs.R dregs.R 1996 sext bits dregs.R dregs.R
1876 update_flags NZV0C0 1997 update_flags NZV0C0
1877 m68k_prefetch 1998 m68k_prefetch
1999
2000 010011100100VVVV trap
2001 local vector 32
2002 scratch1 = pc
2003 vector = V + 32
2004 m68k_trap vector
1878 2005
1879 0100111001010RRR link 2006 0100111001010RRR link
1880 a7 -= 4 2007 a7 -= 4
1881 scratch2 = a7 2008 scratch2 = a7
1882 #TODO: confirm order of fetch and write 2009 #TODO: confirm order of fetch and write