Commit acf930aaa3763be08a41f2478b3e0b252f545cd0

Authored by pbrook
1 parent 2b8bdefc

ColdFire EMAC support.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2895 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-exec.c
... ... @@ -196,7 +196,9 @@ static inline TranslationBlock *tb_find_fast(void)
196 196 cs_base = 0;
197 197 pc = env->PC;
198 198 #elif defined(TARGET_M68K)
199   - flags = (env->fpcr & M68K_FPCR_PREC) | (env->sr & SR_S);
  199 + flags = (env->fpcr & M68K_FPCR_PREC) /* Bit 6 */
  200 + | (env->sr & SR_S) /* Bit 13 */
  201 + | ((env->macsr >> 4) & 0xf); /* Bits 0-3 */
200 202 cs_base = 0;
201 203 pc = env->pc;
202 204 #elif defined(TARGET_SH4)
... ...
target-m68k/cpu.h
... ... @@ -71,6 +71,14 @@ typedef struct CPUM68KState {
71 71 uint32_t fpsr;
72 72 float_status fp_status;
73 73  
  74 + uint64_t mactmp;
  75 + /* EMAC Hardware deals with 48-bit values composed of one 32-bit and
  76 + two 8-bit parts. We store a single 64-bit value and
  77 + rearrange/extend this when changing modes. */
  78 + uint64_t macc[4];
  79 + uint32_t macsr;
  80 + uint32_t mac_mask;
  81 +
74 82 /* Temporary storage for DIV helpers. */
75 83 uint32_t div1;
76 84 uint32_t div2;
... ... @@ -143,11 +151,22 @@ enum {
143 151 #define SR_S 0x2000
144 152 #define SR_T 0x8000
145 153  
  154 +#define MACSR_PAV0 0x100
  155 +#define MACSR_OMC 0x080
  156 +#define MACSR_SU 0x040
  157 +#define MACSR_FI 0x020
  158 +#define MACSR_RT 0x010
  159 +#define MACSR_N 0x008
  160 +#define MACSR_Z 0x004
  161 +#define MACSR_V 0x002
  162 +#define MACSR_EV 0x001
  163 +
146 164 typedef struct m68k_def_t m68k_def_t;
147 165  
148 166 int cpu_m68k_set_model(CPUM68KState *env, const char * name);
149 167  
150 168 void m68k_set_irq_level(CPUM68KState *env, int level, uint8_t vector);
  169 +void m68k_set_macsr(CPUM68KState *env, uint32_t val);
151 170  
152 171 #define M68K_FPCR_PREC (1 << 6)
153 172  
... ...
target-m68k/helper.c
... ... @@ -69,7 +69,6 @@ int cpu_m68k_set_model(CPUM68KState *env, const char * name)
69 69 m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
70 70 m68k_set_feature(env, M68K_FEATURE_CF_ISA_C);
71 71 m68k_set_feature(env, M68K_FEATURE_CF_FPU);
72   - m68k_set_feature(env, M68K_FEATURE_CF_MAC);
73 72 m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
74 73 break;
75 74 case M68K_CPUID_ANY:
... ... @@ -77,7 +76,8 @@ int cpu_m68k_set_model(CPUM68KState *env, const char * name)
77 76 m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
78 77 m68k_set_feature(env, M68K_FEATURE_CF_ISA_C);
79 78 m68k_set_feature(env, M68K_FEATURE_CF_FPU);
80   - m68k_set_feature(env, M68K_FEATURE_CF_MAC);
  79 + /* MAC and EMAC are mututally exclusive, so pick EMAC.
  80 + It's mostly backwards compatible. */
81 81 m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
82 82 m68k_set_feature(env, M68K_FEATURE_EXT_FULL);
83 83 break;
... ... @@ -227,6 +227,40 @@ void helper_movec(CPUM68KState *env, int reg, uint32_t val)
227 227 }
228 228 }
229 229  
  230 +void m68k_set_macsr(CPUM68KState *env, uint32_t val)
  231 +{
  232 + uint32_t acc;
  233 + int8_t exthigh;
  234 + uint8_t extlow;
  235 + uint64_t regval;
  236 + int i;
  237 + if ((env->macsr ^ val) & (MACSR_FI | MACSR_SU)) {
  238 + for (i = 0; i < 4; i++) {
  239 + regval = env->macc[i];
  240 + exthigh = regval >> 40;
  241 + if (env->macsr & MACSR_FI) {
  242 + acc = regval >> 8;
  243 + extlow = regval;
  244 + } else {
  245 + acc = regval;
  246 + extlow = regval >> 32;
  247 + }
  248 + if (env->macsr & MACSR_FI) {
  249 + regval = (((uint64_t)acc) << 8) | extlow;
  250 + regval |= ((int64_t)exthigh) << 40;
  251 + } else if (env->macsr & MACSR_SU) {
  252 + regval = acc | (((int64_t)extlow) << 32);
  253 + regval |= ((int64_t)exthigh) << 40;
  254 + } else {
  255 + regval = acc | (((uint64_t)extlow) << 32);
  256 + regval |= ((uint64_t)(uint8_t)exthigh) << 40;
  257 + }
  258 + env->macc[i] = regval;
  259 + }
  260 + }
  261 + env->macsr = val;
  262 +}
  263 +
230 264 /* MMU */
231 265  
232 266 /* TODO: This will need fixing once the MMU is implemented. */
... ...
target-m68k/op.c
... ... @@ -285,6 +285,16 @@ OP(shr_cc)
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,3 +661,410 @@ OP(movec)
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 +}
... ...
target-m68k/qregs.def
... ... @@ -33,3 +33,5 @@ DEFO32(CC_X, cc_x)
33 33 DEFO32(DIV1, div1)
34 34 DEFO32(DIV2, div2)
35 35 DEFO32(EXCEPTION, exception_index)
  36 +DEFO32(MACSR, macsr)
  37 +DEFO32(MAC_MASK, mac_mask)
... ...
target-m68k/translate.c
... ... @@ -2433,6 +2433,279 @@ DISAS_INSN(fsave)
2433 2433 qemu_assert(0, "FSAVE not implemented");
2434 2434 }
2435 2435  
  2436 +static inline int gen_mac_extract_word(DisasContext *s, int val, int upper)
  2437 +{
  2438 + int tmp = gen_new_qreg(QMODE_I32);
  2439 + if (s->env->macsr & MACSR_FI) {
  2440 + if (upper)
  2441 + gen_op_and32(tmp, val, gen_im32(0xffff0000));
  2442 + else
  2443 + gen_op_shl32(tmp, val, gen_im32(16));
  2444 + } else if (s->env->macsr & MACSR_SU) {
  2445 + if (upper)
  2446 + gen_op_sar32(tmp, val, gen_im32(16));
  2447 + else
  2448 + gen_op_ext16s32(tmp, val);
  2449 + } else {
  2450 + if (upper)
  2451 + gen_op_shr32(tmp, val, gen_im32(16));
  2452 + else
  2453 + gen_op_ext16u32(tmp, val);
  2454 + }
  2455 + return tmp;
  2456 +}
  2457 +
  2458 +DISAS_INSN(mac)
  2459 +{
  2460 + int rx;
  2461 + int ry;
  2462 + uint16_t ext;
  2463 + int acc;
  2464 + int l1;
  2465 + int tmp;
  2466 + int addr;
  2467 + int loadval;
  2468 + int dual;
  2469 + int saved_flags = -1;
  2470 +
  2471 + ext = lduw_code(s->pc);
  2472 + s->pc += 2;
  2473 +
  2474 + acc = ((insn >> 7) & 1) | ((ext >> 3) & 2);
  2475 + dual = ((insn & 0x30) != 0 && (ext & 3) != 0);
  2476 + if (insn & 0x30) {
  2477 + /* MAC with load. */
  2478 + tmp = gen_lea(s, insn, OS_LONG);
  2479 + addr = gen_new_qreg(QMODE_I32);
  2480 + gen_op_and32(addr, tmp, QREG_MAC_MASK);
  2481 + /* Load the value now to ensure correct exception behavior.
  2482 + Perform writeback after reading the MAC inputs. */
  2483 + loadval = gen_load(s, OS_LONG, addr, 0);
  2484 +
  2485 + acc ^= 1;
  2486 + rx = (ext & 0x8000) ? AREG(ext, 12) : DREG(insn, 12);
  2487 + ry = (ext & 8) ? AREG(ext, 0) : DREG(ext, 0);
  2488 + } else {
  2489 + loadval = addr = -1;
  2490 + rx = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
  2491 + ry = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
  2492 + }
  2493 +
  2494 + gen_op_mac_clear_flags();
  2495 + l1 = -1;
  2496 + if ((s->env->macsr & MACSR_OMC) != 0 && !dual) {
  2497 + /* Skip the multiply if we know we will ignore it. */
  2498 + l1 = gen_new_label();
  2499 + tmp = gen_new_qreg(QMODE_I32);
  2500 + gen_op_and32(tmp, QREG_MACSR, gen_im32(1 << (acc + 8)));
  2501 + gen_op_jmp_nz32(tmp, l1);
  2502 + }
  2503 +
  2504 + if ((ext & 0x0800) == 0) {
  2505 + /* Word. */
  2506 + rx = gen_mac_extract_word(s, rx, (ext & 0x80) != 0);
  2507 + ry = gen_mac_extract_word(s, ry, (ext & 0x40) != 0);
  2508 + }
  2509 + if (s->env->macsr & MACSR_FI) {
  2510 + gen_op_macmulf(rx, ry);
  2511 + } else {
  2512 + if (s->env->macsr & MACSR_SU)
  2513 + gen_op_macmuls(rx, ry);
  2514 + else
  2515 + gen_op_macmulu(rx, ry);
  2516 + switch ((ext >> 9) & 3) {
  2517 + case 1:
  2518 + gen_op_macshl();
  2519 + break;
  2520 + case 3:
  2521 + gen_op_macshr();
  2522 + break;
  2523 + }
  2524 + }
  2525 +
  2526 + if (dual) {
  2527 + /* Save the overflow flag from the multiply. */
  2528 + saved_flags = gen_new_qreg(QMODE_I32);
  2529 + gen_op_mov32(saved_flags, QREG_MACSR);
  2530 + }
  2531 +
  2532 + if ((s->env->macsr & MACSR_OMC) != 0 && dual) {
  2533 + /* Skip the accumulate if the value is already saturated. */
  2534 + l1 = gen_new_label();
  2535 + tmp = gen_new_qreg(QMODE_I32);
  2536 + gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));
  2537 + gen_op_jmp_nz32(tmp, l1);
  2538 + }
  2539 +
  2540 + if (insn & 0x100)
  2541 + gen_op_macsub(acc);
  2542 + else
  2543 + gen_op_macadd(acc);
  2544 +
  2545 + if (s->env->macsr & MACSR_FI)
  2546 + gen_op_macsatf(acc);
  2547 + else if (s->env->macsr & MACSR_SU)
  2548 + gen_op_macsats(acc);
  2549 + else
  2550 + gen_op_macsatu(acc);
  2551 +
  2552 + if (l1 != -1)
  2553 + gen_set_label(l1);
  2554 +
  2555 + if (dual) {
  2556 + /* Dual accumulate variant. */
  2557 + acc = (ext >> 2) & 3;
  2558 + /* Restore the overflow flag from the multiplier. */
  2559 + gen_op_mov32(QREG_MACSR, saved_flags);
  2560 + if ((s->env->macsr & MACSR_OMC) != 0) {
  2561 + /* Skip the accumulate if the value is already saturated. */
  2562 + l1 = gen_new_label();
  2563 + tmp = gen_new_qreg(QMODE_I32);
  2564 + gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));
  2565 + gen_op_jmp_nz32(tmp, l1);
  2566 + }
  2567 + if (ext & 2)
  2568 + gen_op_macsub(acc);
  2569 + else
  2570 + gen_op_macadd(acc);
  2571 + if (s->env->macsr & MACSR_FI)
  2572 + gen_op_macsatf(acc);
  2573 + else if (s->env->macsr & MACSR_SU)
  2574 + gen_op_macsats(acc);
  2575 + else
  2576 + gen_op_macsatu(acc);
  2577 + if (l1 != -1)
  2578 + gen_set_label(l1);
  2579 + }
  2580 + gen_op_mac_set_flags(acc);
  2581 +
  2582 + if (insn & 0x30) {
  2583 + int rw;
  2584 + rw = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
  2585 + gen_op_mov32(rw, loadval);
  2586 + /* FIXME: Should address writeback happen with the masked or
  2587 + unmasked value? */
  2588 + switch ((insn >> 3) & 7) {
  2589 + case 3: /* Post-increment. */
  2590 + gen_op_add32(AREG(insn, 0), addr, gen_im32(4));
  2591 + break;
  2592 + case 4: /* Pre-decrement. */
  2593 + gen_op_mov32(AREG(insn, 0), addr);
  2594 + }
  2595 + }
  2596 +}
  2597 +
  2598 +DISAS_INSN(from_mac)
  2599 +{
  2600 + int rx;
  2601 + int acc;
  2602 +
  2603 + rx = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
  2604 + acc = (insn >> 9) & 3;
  2605 + if (s->env->macsr & MACSR_FI) {
  2606 + gen_op_get_macf(rx, acc);
  2607 + } else if ((s->env->macsr & MACSR_OMC) == 0) {
  2608 + gen_op_get_maci(rx, acc);
  2609 + } else if (s->env->macsr & MACSR_SU) {
  2610 + gen_op_get_macs(rx, acc);
  2611 + } else {
  2612 + gen_op_get_macu(rx, acc);
  2613 + }
  2614 + if (insn & 0x40)
  2615 + gen_op_clear_mac(acc);
  2616 +}
  2617 +
  2618 +DISAS_INSN(move_mac)
  2619 +{
  2620 + int src;
  2621 + int dest;
  2622 + src = insn & 3;
  2623 + dest = (insn >> 9) & 3;
  2624 + gen_op_move_mac(dest, src);
  2625 + gen_op_mac_clear_flags();
  2626 + gen_op_mac_set_flags(dest);
  2627 +}
  2628 +
  2629 +DISAS_INSN(from_macsr)
  2630 +{
  2631 + int reg;
  2632 +
  2633 + reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
  2634 + gen_op_mov32(reg, QREG_MACSR);
  2635 +}
  2636 +
  2637 +DISAS_INSN(from_mask)
  2638 +{
  2639 + int reg;
  2640 + reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
  2641 + gen_op_mov32(reg, QREG_MAC_MASK);
  2642 +}
  2643 +
  2644 +DISAS_INSN(from_mext)
  2645 +{
  2646 + int reg;
  2647 + int acc;
  2648 + reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
  2649 + acc = (insn & 0x400) ? 2 : 0;
  2650 + if (s->env->macsr & MACSR_FI)
  2651 + gen_op_get_mac_extf(reg, acc);
  2652 + else
  2653 + gen_op_get_mac_exti(reg, acc);
  2654 +}
  2655 +
  2656 +DISAS_INSN(macsr_to_ccr)
  2657 +{
  2658 + gen_op_mov32(QREG_CC_X, gen_im32(0));
  2659 + gen_op_and32(QREG_CC_DEST, QREG_MACSR, gen_im32(0xf));
  2660 + s->cc_op = CC_OP_FLAGS;
  2661 +}
  2662 +
  2663 +DISAS_INSN(to_mac)
  2664 +{
  2665 + int acc;
  2666 + int val;
  2667 + acc = (insn >>9) & 3;
  2668 + SRC_EA(val, OS_LONG, 0, NULL);
  2669 + if (s->env->macsr & MACSR_FI) {
  2670 + gen_op_set_macf(val, acc);
  2671 + } else if (s->env->macsr & MACSR_SU) {
  2672 + gen_op_set_macs(val, acc);
  2673 + } else {
  2674 + gen_op_set_macu(val, acc);
  2675 + }
  2676 + gen_op_mac_clear_flags();
  2677 + gen_op_mac_set_flags(acc);
  2678 +}
  2679 +
  2680 +DISAS_INSN(to_macsr)
  2681 +{
  2682 + int val;
  2683 + SRC_EA(val, OS_LONG, 0, NULL);
  2684 + gen_op_set_macsr(val);
  2685 + gen_lookup_tb(s);
  2686 +}
  2687 +
  2688 +DISAS_INSN(to_mask)
  2689 +{
  2690 + int val;
  2691 + SRC_EA(val, OS_LONG, 0, NULL);
  2692 + gen_op_or32(QREG_MAC_MASK, val, gen_im32(0xffff0000));
  2693 +}
  2694 +
  2695 +DISAS_INSN(to_mext)
  2696 +{
  2697 + int val;
  2698 + int acc;
  2699 + SRC_EA(val, OS_LONG, 0, NULL);
  2700 + acc = (insn & 0x400) ? 2 : 0;
  2701 + if (s->env->macsr & MACSR_FI)
  2702 + gen_op_set_mac_extf(val, acc);
  2703 + else if (s->env->macsr & MACSR_SU)
  2704 + gen_op_set_mac_exts(val, acc);
  2705 + else
  2706 + gen_op_set_mac_extu(val, acc);
  2707 +}
  2708 +
2436 2709 static disas_proc opcode_table[65536];
2437 2710  
2438 2711 static void
... ... @@ -2545,7 +2818,20 @@ void register_m68k_insns (CPUM68KState *env)
2545 2818 INSN(addsub, 9000, f000, CF_ISA_A);
2546 2819 INSN(subx, 9180, f1f8, CF_ISA_A);
2547 2820 INSN(suba, 91c0, f1c0, CF_ISA_A);
  2821 +
2548 2822 INSN(undef_mac, a000, f000, CF_ISA_A);
  2823 + INSN(mac, a000, f100, CF_EMAC);
  2824 + INSN(from_mac, a180, f9b0, CF_EMAC);
  2825 + INSN(move_mac, a110, f9fc, CF_EMAC);
  2826 + INSN(from_macsr,a980, f9f0, CF_EMAC);
  2827 + INSN(from_mask, ad80, fff0, CF_EMAC);
  2828 + INSN(from_mext, ab80, fbf0, CF_EMAC);
  2829 + INSN(macsr_to_ccr, a9c0, ffff, CF_EMAC);
  2830 + INSN(to_mac, a100, f9c0, CF_EMAC);
  2831 + INSN(to_macsr, a900, ffc0, CF_EMAC);
  2832 + INSN(to_mext, ab00, fbc0, CF_EMAC);
  2833 + INSN(to_mask, ad00, ffc0, CF_EMAC);
  2834 +
2549 2835 INSN(mov3q, a140, f1c0, CF_ISA_B);
2550 2836 INSN(cmp, b000, f1c0, CF_ISA_B); /* cmp.b */
2551 2837 INSN(cmp, b040, f1c0, CF_ISA_B); /* cmp.w */
... ...