Revision acf930aa target-m68k/op.c
b/target-m68k/op.c | ||
---|---|---|
285 | 285 |
FORCE_RET(); |
286 | 286 |
} |
287 | 287 |
|
288 |
OP(sar32) |
|
289 |
{ |
|
290 |
int32_t op2 = get_op(PARAM2); |
|
291 |
uint32_t op3 = get_op(PARAM3); |
|
292 |
uint32_t result; |
|
293 |
result = op2 >> op3; |
|
294 |
set_op(PARAM1, result); |
|
295 |
FORCE_RET(); |
|
296 |
} |
|
297 |
|
|
288 | 298 |
OP(sar_cc) |
289 | 299 |
{ |
290 | 300 |
int32_t op1 = get_op(PARAM1); |
... | ... | |
651 | 661 |
#define MEMSUFFIX _kernel |
652 | 662 |
#include "op_mem.h" |
653 | 663 |
#endif |
664 |
|
|
665 |
/* MAC unit. */ |
|
666 |
/* TODO: The MAC instructions use 64-bit arithmetic fairly extensively. |
|
667 |
This results in fairly large ops (and sometimes other issues) on 32-bit |
|
668 |
hosts. Maybe move most of them into helpers. */ |
|
669 |
OP(macmuls) |
|
670 |
{ |
|
671 |
uint32_t op1 = get_op(PARAM1); |
|
672 |
uint32_t op2 = get_op(PARAM2); |
|
673 |
int64_t product; |
|
674 |
int64_t res; |
|
675 |
|
|
676 |
product = (uint64_t)op1 * op2; |
|
677 |
res = (product << 24) >> 24; |
|
678 |
if (res != product) { |
|
679 |
env->macsr |= MACSR_V; |
|
680 |
if (env->macsr & MACSR_OMC) { |
|
681 |
/* Make sure the accumulate operation overflows. */ |
|
682 |
if (product < 0) |
|
683 |
res = ~(1ll << 50); |
|
684 |
else |
|
685 |
res = 1ll << 50; |
|
686 |
} |
|
687 |
} |
|
688 |
env->mactmp = res; |
|
689 |
FORCE_RET(); |
|
690 |
} |
|
691 |
|
|
692 |
OP(macmulu) |
|
693 |
{ |
|
694 |
uint32_t op1 = get_op(PARAM1); |
|
695 |
uint32_t op2 = get_op(PARAM2); |
|
696 |
uint64_t product; |
|
697 |
|
|
698 |
product = (uint64_t)op1 * op2; |
|
699 |
if (product & (0xffffffull << 40)) { |
|
700 |
env->macsr |= MACSR_V; |
|
701 |
if (env->macsr & MACSR_OMC) { |
|
702 |
/* Make sure the accumulate operation overflows. */ |
|
703 |
product = 1ll << 50; |
|
704 |
} else { |
|
705 |
product &= ((1ull << 40) - 1); |
|
706 |
} |
|
707 |
} |
|
708 |
env->mactmp = product; |
|
709 |
FORCE_RET(); |
|
710 |
} |
|
711 |
|
|
712 |
OP(macmulf) |
|
713 |
{ |
|
714 |
int32_t op1 = get_op(PARAM1); |
|
715 |
int32_t op2 = get_op(PARAM2); |
|
716 |
uint64_t product; |
|
717 |
uint32_t remainder; |
|
718 |
|
|
719 |
product = (uint64_t)op1 * op2; |
|
720 |
if (env->macsr & MACSR_RT) { |
|
721 |
remainder = product & 0xffffff; |
|
722 |
product >>= 24; |
|
723 |
if (remainder > 0x800000) |
|
724 |
product++; |
|
725 |
else if (remainder == 0x800000) |
|
726 |
product += (product & 1); |
|
727 |
} else { |
|
728 |
product >>= 24; |
|
729 |
} |
|
730 |
env->mactmp = product; |
|
731 |
FORCE_RET(); |
|
732 |
} |
|
733 |
|
|
734 |
OP(macshl) |
|
735 |
{ |
|
736 |
env->mactmp <<= 1; |
|
737 |
} |
|
738 |
|
|
739 |
OP(macshr) |
|
740 |
{ |
|
741 |
env->mactmp >>= 1; |
|
742 |
} |
|
743 |
|
|
744 |
OP(macadd) |
|
745 |
{ |
|
746 |
int acc = PARAM1; |
|
747 |
env->macc[acc] += env->mactmp; |
|
748 |
FORCE_RET(); |
|
749 |
} |
|
750 |
|
|
751 |
OP(macsub) |
|
752 |
{ |
|
753 |
int acc = PARAM1; |
|
754 |
env->macc[acc] -= env->mactmp; |
|
755 |
FORCE_RET(); |
|
756 |
} |
|
757 |
|
|
758 |
OP(macsats) |
|
759 |
{ |
|
760 |
int acc = PARAM1; |
|
761 |
int64_t sum; |
|
762 |
int64_t result; |
|
763 |
|
|
764 |
sum = env->macc[acc]; |
|
765 |
result = (sum << 16) >> 16; |
|
766 |
if (result != sum) { |
|
767 |
env->macsr |= MACSR_V; |
|
768 |
} |
|
769 |
if (env->macsr & MACSR_V) { |
|
770 |
env->macsr |= MACSR_PAV0 << acc; |
|
771 |
if (env->macsr & MACSR_OMC) { |
|
772 |
/* The result is saturated to 32 bits, despite overflow occuring |
|
773 |
at 48 bits. Seems weird, but that's what the hardware docs |
|
774 |
say. */ |
|
775 |
result = (result >> 63) ^ 0x7fffffff; |
|
776 |
} |
|
777 |
} |
|
778 |
env->macc[acc] = result; |
|
779 |
FORCE_RET(); |
|
780 |
} |
|
781 |
|
|
782 |
OP(macsatu) |
|
783 |
{ |
|
784 |
int acc = PARAM1; |
|
785 |
uint64_t sum; |
|
786 |
|
|
787 |
sum = env->macc[acc]; |
|
788 |
if (sum & (0xffffull << 48)) { |
|
789 |
env->macsr |= MACSR_V; |
|
790 |
} |
|
791 |
if (env->macsr & MACSR_V) { |
|
792 |
env->macsr |= MACSR_PAV0 << acc; |
|
793 |
if (env->macsr & MACSR_OMC) { |
|
794 |
if (sum > (1ull << 53)) |
|
795 |
sum = 0; |
|
796 |
else |
|
797 |
sum = (1ull << 48) - 1; |
|
798 |
} else { |
|
799 |
sum &= ((1ull << 48) - 1); |
|
800 |
} |
|
801 |
} |
|
802 |
FORCE_RET(); |
|
803 |
} |
|
804 |
|
|
805 |
OP(macsatf) |
|
806 |
{ |
|
807 |
int acc = PARAM1; |
|
808 |
int64_t sum; |
|
809 |
int64_t result; |
|
810 |
|
|
811 |
sum = env->macc[acc]; |
|
812 |
result = (sum << 16) >> 16; |
|
813 |
if (result != sum) { |
|
814 |
env->macsr |= MACSR_V; |
|
815 |
} |
|
816 |
if (env->macsr & MACSR_V) { |
|
817 |
env->macsr |= MACSR_PAV0 << acc; |
|
818 |
if (env->macsr & MACSR_OMC) { |
|
819 |
result = (result >> 63) ^ 0x7fffffffffffll; |
|
820 |
} |
|
821 |
} |
|
822 |
env->macc[acc] = result; |
|
823 |
FORCE_RET(); |
|
824 |
} |
|
825 |
|
|
826 |
OP(mac_clear_flags) |
|
827 |
{ |
|
828 |
env->macsr &= ~(MACSR_V | MACSR_Z | MACSR_N | MACSR_EV); |
|
829 |
} |
|
830 |
|
|
831 |
OP(mac_set_flags) |
|
832 |
{ |
|
833 |
int acc = PARAM1; |
|
834 |
uint64_t val; |
|
835 |
val = env->macc[acc]; |
|
836 |
if (val == 0) |
|
837 |
env->macsr |= MACSR_Z; |
|
838 |
else if (val & (1ull << 47)); |
|
839 |
env->macsr |= MACSR_N; |
|
840 |
if (env->macsr & (MACSR_PAV0 << acc)) { |
|
841 |
env->macsr |= MACSR_V; |
|
842 |
} |
|
843 |
if (env->macsr & MACSR_FI) { |
|
844 |
val = ((int64_t)val) >> 40; |
|
845 |
if (val != 0 && val != -1) |
|
846 |
env->macsr |= MACSR_EV; |
|
847 |
} else if (env->macsr & MACSR_SU) { |
|
848 |
val = ((int64_t)val) >> 32; |
|
849 |
if (val != 0 && val != -1) |
|
850 |
env->macsr |= MACSR_EV; |
|
851 |
} else { |
|
852 |
if ((val >> 32) != 0) |
|
853 |
env->macsr |= MACSR_EV; |
|
854 |
} |
|
855 |
FORCE_RET(); |
|
856 |
} |
|
857 |
|
|
858 |
OP(get_macf) |
|
859 |
{ |
|
860 |
int acc = PARAM2; |
|
861 |
int64_t val; |
|
862 |
int rem; |
|
863 |
uint32_t result; |
|
864 |
|
|
865 |
val = env->macc[acc]; |
|
866 |
if (env->macsr & MACSR_SU) { |
|
867 |
/* 16-bit rounding. */ |
|
868 |
rem = val & 0xffffff; |
|
869 |
val = (val >> 24) & 0xffffu; |
|
870 |
if (rem > 0x800000) |
|
871 |
val++; |
|
872 |
else if (rem == 0x800000) |
|
873 |
val += (val & 1); |
|
874 |
} else if (env->macsr & MACSR_RT) { |
|
875 |
/* 32-bit rounding. */ |
|
876 |
rem = val & 0xff; |
|
877 |
val >>= 8; |
|
878 |
if (rem > 0x80) |
|
879 |
val++; |
|
880 |
else if (rem == 0x80) |
|
881 |
val += (val & 1); |
|
882 |
} else { |
|
883 |
/* No rounding. */ |
|
884 |
val >>= 8; |
|
885 |
} |
|
886 |
if (env->macsr & MACSR_OMC) { |
|
887 |
/* Saturate. */ |
|
888 |
if (env->macsr & MACSR_SU) { |
|
889 |
if (val != (uint16_t) val) { |
|
890 |
result = ((val >> 63) ^ 0x7fff) & 0xffff; |
|
891 |
} else { |
|
892 |
result = val & 0xffff; |
|
893 |
} |
|
894 |
} else { |
|
895 |
if (val != (uint32_t)val) { |
|
896 |
result = ((uint32_t)(val >> 63) & 0x7fffffff); |
|
897 |
} else { |
|
898 |
result = (uint32_t)val; |
|
899 |
} |
|
900 |
} |
|
901 |
} else { |
|
902 |
/* No saturation. */ |
|
903 |
if (env->macsr & MACSR_SU) { |
|
904 |
result = val & 0xffff; |
|
905 |
} else { |
|
906 |
result = (uint32_t)val; |
|
907 |
} |
|
908 |
} |
|
909 |
set_op(PARAM1, result); |
|
910 |
FORCE_RET(); |
|
911 |
} |
|
912 |
|
|
913 |
OP(get_maci) |
|
914 |
{ |
|
915 |
int acc = PARAM2; |
|
916 |
set_op(PARAM1, (uint32_t)env->macc[acc]); |
|
917 |
FORCE_RET(); |
|
918 |
} |
|
919 |
|
|
920 |
OP(get_macs) |
|
921 |
{ |
|
922 |
int acc = PARAM2; |
|
923 |
int64_t val = env->macc[acc]; |
|
924 |
uint32_t result; |
|
925 |
if (val == (int32_t)val) { |
|
926 |
result = (int32_t)val; |
|
927 |
} else { |
|
928 |
result = (val >> 61) ^ 0x7fffffff; |
|
929 |
} |
|
930 |
set_op(PARAM1, result); |
|
931 |
FORCE_RET(); |
|
932 |
} |
|
933 |
|
|
934 |
OP(get_macu) |
|
935 |
{ |
|
936 |
int acc = PARAM2; |
|
937 |
uint64_t val = env->macc[acc]; |
|
938 |
uint32_t result; |
|
939 |
if ((val >> 32) == 0) { |
|
940 |
result = (uint32_t)val; |
|
941 |
} else { |
|
942 |
result = 0xffffffffu; |
|
943 |
} |
|
944 |
set_op(PARAM1, result); |
|
945 |
FORCE_RET(); |
|
946 |
} |
|
947 |
|
|
948 |
OP(clear_mac) |
|
949 |
{ |
|
950 |
int acc = PARAM1; |
|
951 |
|
|
952 |
env->macc[acc] = 0; |
|
953 |
env->macsr &= ~(MACSR_PAV0 << acc); |
|
954 |
FORCE_RET(); |
|
955 |
} |
|
956 |
|
|
957 |
OP(move_mac) |
|
958 |
{ |
|
959 |
int dest = PARAM1; |
|
960 |
int src = PARAM2; |
|
961 |
uint32_t mask; |
|
962 |
env->macc[dest] = env->macc[src]; |
|
963 |
mask = MACSR_PAV0 << dest; |
|
964 |
if (env->macsr & (MACSR_PAV0 << src)) |
|
965 |
env->macsr |= mask; |
|
966 |
else |
|
967 |
env->macsr &= ~mask; |
|
968 |
FORCE_RET(); |
|
969 |
} |
|
970 |
|
|
971 |
OP(get_mac_extf) |
|
972 |
{ |
|
973 |
uint32_t val; |
|
974 |
int acc = PARAM2; |
|
975 |
val = env->macc[acc] & 0x00ff; |
|
976 |
val = (env->macc[acc] >> 32) & 0xff00; |
|
977 |
val |= (env->macc[acc + 1] << 16) & 0x00ff0000; |
|
978 |
val |= (env->macc[acc + 1] >> 16) & 0xff000000; |
|
979 |
set_op(PARAM1, val); |
|
980 |
FORCE_RET(); |
|
981 |
} |
|
982 |
|
|
983 |
OP(get_mac_exti) |
|
984 |
{ |
|
985 |
uint32_t val; |
|
986 |
int acc = PARAM2; |
|
987 |
val = (env->macc[acc] >> 32) & 0xffff; |
|
988 |
val |= (env->macc[acc + 1] >> 16) & 0xffff0000; |
|
989 |
set_op(PARAM1, val); |
|
990 |
FORCE_RET(); |
|
991 |
} |
|
992 |
|
|
993 |
OP(set_macf) |
|
994 |
{ |
|
995 |
int acc = PARAM2; |
|
996 |
int32_t val = get_op(PARAM1); |
|
997 |
env->macc[acc] = ((int64_t)val) << 8; |
|
998 |
env->macsr &= ~(MACSR_PAV0 << acc); |
|
999 |
FORCE_RET(); |
|
1000 |
} |
|
1001 |
|
|
1002 |
OP(set_macs) |
|
1003 |
{ |
|
1004 |
int acc = PARAM2; |
|
1005 |
int32_t val = get_op(PARAM1); |
|
1006 |
env->macc[acc] = val; |
|
1007 |
env->macsr &= ~(MACSR_PAV0 << acc); |
|
1008 |
FORCE_RET(); |
|
1009 |
} |
|
1010 |
|
|
1011 |
OP(set_macu) |
|
1012 |
{ |
|
1013 |
int acc = PARAM2; |
|
1014 |
uint32_t val = get_op(PARAM1); |
|
1015 |
env->macc[acc] = val; |
|
1016 |
env->macsr &= ~(MACSR_PAV0 << acc); |
|
1017 |
FORCE_RET(); |
|
1018 |
} |
|
1019 |
|
|
1020 |
OP(set_mac_extf) |
|
1021 |
{ |
|
1022 |
int acc = PARAM2; |
|
1023 |
int32_t val = get_op(PARAM1); |
|
1024 |
int64_t res; |
|
1025 |
int32_t tmp; |
|
1026 |
res = env->macc[acc] & 0xffffffff00ull; |
|
1027 |
tmp = (int16_t)(val & 0xff00); |
|
1028 |
res |= ((int64_t)tmp) << 32; |
|
1029 |
res |= val & 0xff; |
|
1030 |
env->macc[acc] = res; |
|
1031 |
res = env->macc[acc + 1] & 0xffffffff00ull; |
|
1032 |
tmp = (val & 0xff000000); |
|
1033 |
res |= ((int64_t)tmp) << 16; |
|
1034 |
res |= (val >> 16) & 0xff; |
|
1035 |
env->macc[acc + 1] = res; |
|
1036 |
} |
|
1037 |
|
|
1038 |
OP(set_mac_exts) |
|
1039 |
{ |
|
1040 |
int acc = PARAM2; |
|
1041 |
int32_t val = get_op(PARAM1); |
|
1042 |
int64_t res; |
|
1043 |
int32_t tmp; |
|
1044 |
res = (uint32_t)env->macc[acc]; |
|
1045 |
tmp = (int16_t)val; |
|
1046 |
res |= ((int64_t)tmp) << 32; |
|
1047 |
env->macc[acc] = res; |
|
1048 |
res = (uint32_t)env->macc[acc + 1]; |
|
1049 |
tmp = val & 0xffff0000; |
|
1050 |
res |= (int64_t)tmp << 16; |
|
1051 |
env->macc[acc + 1] = res; |
|
1052 |
} |
|
1053 |
|
|
1054 |
OP(set_mac_extu) |
|
1055 |
{ |
|
1056 |
int acc = PARAM2; |
|
1057 |
int32_t val = get_op(PARAM1); |
|
1058 |
uint64_t res; |
|
1059 |
res = (uint32_t)env->macc[acc]; |
|
1060 |
res |= ((uint64_t)(val & 0xffff)) << 32; |
|
1061 |
env->macc[acc] = res; |
|
1062 |
res = (uint32_t)env->macc[acc + 1]; |
|
1063 |
res |= (uint64_t)(val & 0xffff0000) << 16; |
|
1064 |
env->macc[acc + 1] = res; |
|
1065 |
} |
|
1066 |
|
|
1067 |
OP(set_macsr) |
|
1068 |
{ |
|
1069 |
m68k_set_macsr(env, get_op(PARAM1)); |
|
1070 |
} |
Also available in: Unified diff