14 |
|
* take care of this. |
15 |
|
* |
16 |
|
* Copyright 1995, 1996 Bernd Schmidt |
17 |
+ |
* |
18 |
+ |
* This program is free software; you can redistribute it and/or modify |
19 |
+ |
* it under the terms of the GNU General Public License as published by |
20 |
+ |
* the Free Software Foundation; either version 2 of the License, or |
21 |
+ |
* (at your option) any later version. |
22 |
+ |
* |
23 |
+ |
* This program is distributed in the hope that it will be useful, |
24 |
+ |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
25 |
+ |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
26 |
+ |
* GNU General Public License for more details. |
27 |
+ |
* |
28 |
+ |
* You should have received a copy of the GNU General Public License |
29 |
+ |
* along with this program; if not, write to the Free Software |
30 |
+ |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
31 |
+ |
* |
32 |
|
*/ |
33 |
|
|
34 |
|
#include <ctype.h> |
45 |
|
|
46 |
|
#define BOOL_TYPE "int" |
47 |
|
|
48 |
+ |
/* Define the minimal 680x0 where NV flags are not affected by xBCD instructions. */ |
49 |
+ |
#define xBCD_KEEPS_NV_FLAGS 4 |
50 |
+ |
|
51 |
|
static FILE *headerfile; |
52 |
|
static FILE *stblfile; |
53 |
|
|
586 |
|
} |
587 |
|
|
588 |
|
typedef enum { |
589 |
< |
flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_zn, |
589 |
> |
flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_z, flag_zn, |
590 |
|
flag_av, flag_sv |
591 |
|
} flagtypes; |
592 |
|
|
640 |
|
switch (type) { |
641 |
|
case flag_logical_noclobber: |
642 |
|
case flag_logical: |
643 |
+ |
case flag_z: |
644 |
|
case flag_zn: |
645 |
|
case flag_av: |
646 |
|
case flag_sv: |
662 |
|
switch (type) { |
663 |
|
case flag_logical_noclobber: |
664 |
|
case flag_logical: |
665 |
+ |
case flag_z: |
666 |
|
case flag_zn: |
667 |
|
break; |
668 |
|
|
696 |
|
case flag_sv: |
697 |
|
printf ("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n"); |
698 |
|
break; |
699 |
+ |
case flag_z: |
700 |
+ |
printf ("\tSET_ZFLG (GET_ZFLG & (%s == 0));\n", vstr); |
701 |
+ |
break; |
702 |
|
case flag_zn: |
703 |
|
printf ("\tSET_ZFLG (GET_ZFLG & (%s == 0));\n", vstr); |
704 |
|
printf ("\tSET_NFLG (%s < 0);\n", vstr); |
944 |
|
printf ("\tif ((((dst & 0xFF) - (src & 0xFF) - (GET_XFLG ? 1 : 0)) & 0x100) > 0xFF) { newv -= 0x60; }\n"); |
945 |
|
printf ("\tSET_CFLG ((((dst & 0xFF) - (src & 0xFF) - bcd - (GET_XFLG ? 1 : 0)) & 0x300) > 0xFF);\n"); |
946 |
|
duplicate_carry (); |
947 |
< |
genflags (flag_zn, curi->size, "newv", "", ""); |
948 |
< |
printf ("\tSET_VFLG ((tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n"); |
947 |
> |
/* Manual says bits NV are undefined though a real 68040 don't change them */ |
948 |
> |
if (cpu_level >= xBCD_KEEPS_NV_FLAGS) { |
949 |
> |
if (next_cpu_level < xBCD_KEEPS_NV_FLAGS) |
950 |
> |
next_cpu_level = xBCD_KEEPS_NV_FLAGS - 1; |
951 |
> |
genflags (flag_z, curi->size, "newv", "", ""); |
952 |
> |
} |
953 |
> |
else { |
954 |
> |
genflags (flag_zn, curi->size, "newv", "", ""); |
955 |
> |
printf ("\tSET_VFLG ((tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n"); |
956 |
> |
} |
957 |
|
genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); |
958 |
|
break; |
959 |
|
case i_ADD: |
993 |
|
printf ("\tif (cflg) newv += 0x60;\n"); |
994 |
|
printf ("\tSET_CFLG (cflg);\n"); |
995 |
|
duplicate_carry (); |
996 |
< |
genflags (flag_zn, curi->size, "newv", "", ""); |
997 |
< |
printf ("\tSET_VFLG ((tmp_newv & 0x80) == 0 && (newv & 0x80) != 0);\n"); |
996 |
> |
/* Manual says bits NV are undefined though a real 68040 don't change them */ |
997 |
> |
if (cpu_level >= xBCD_KEEPS_NV_FLAGS) { |
998 |
> |
if (next_cpu_level < xBCD_KEEPS_NV_FLAGS) |
999 |
> |
next_cpu_level = xBCD_KEEPS_NV_FLAGS - 1; |
1000 |
> |
genflags (flag_z, curi->size, "newv", "", ""); |
1001 |
> |
} |
1002 |
> |
else { |
1003 |
> |
genflags (flag_zn, curi->size, "newv", "", ""); |
1004 |
> |
printf ("\tSET_VFLG ((tmp_newv & 0x80) == 0 && (newv & 0x80) != 0);\n"); |
1005 |
> |
} |
1006 |
|
genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); |
1007 |
|
break; |
1008 |
|
case i_NEG: |
1032 |
|
printf ("\tif (cflg) newv -= 0x60;\n"); |
1033 |
|
printf ("\tSET_CFLG (cflg);\n"); |
1034 |
|
duplicate_carry(); |
1035 |
< |
genflags (flag_zn, curi->size, "newv", "", ""); |
1035 |
> |
/* Manual says bits NV are undefined though a real 68040 don't change them */ |
1036 |
> |
if (cpu_level >= xBCD_KEEPS_NV_FLAGS) { |
1037 |
> |
if (next_cpu_level < xBCD_KEEPS_NV_FLAGS) |
1038 |
> |
next_cpu_level = xBCD_KEEPS_NV_FLAGS - 1; |
1039 |
> |
genflags (flag_z, curi->size, "newv", "", ""); |
1040 |
> |
} |
1041 |
> |
else { |
1042 |
> |
genflags (flag_zn, curi->size, "newv", "", ""); |
1043 |
> |
} |
1044 |
|
genastore ("newv", curi->smode, "srcreg", curi->size, "src"); |
1045 |
|
break; |
1046 |
|
case i_CLR: |
2281 |
|
|
2282 |
|
static void generate_one_opcode (int rp) |
2283 |
|
{ |
2237 |
– |
int i; |
2284 |
|
uae_u16 smsk, dmsk; |
2285 |
|
long int opcode = opcode_map[rp]; |
2286 |
+ |
const char *opcode_str; |
2287 |
|
|
2288 |
|
if (table68k[opcode].mnemo == i_ILLG |
2289 |
|
|| table68k[opcode].clev > cpu_level) |
2290 |
|
return; |
2291 |
|
|
2245 |
– |
for (i = 0; lookuptab[i].name[0]; i++) { |
2246 |
– |
if (table68k[opcode].mnemo == lookuptab[i].mnemo) |
2247 |
– |
break; |
2248 |
– |
} |
2249 |
– |
|
2292 |
|
if (table68k[opcode].handler != -1) |
2293 |
|
return; |
2294 |
|
|
2295 |
+ |
opcode_str = get_instruction_string (opcode); |
2296 |
+ |
|
2297 |
|
if (opcode_next_clev[rp] != cpu_level) { |
2298 |
|
if (table68k[opcode].flagdead == 0) |
2299 |
|
/* force to the "ff" variant since the instruction doesn't set at all the condition codes */ |
2300 |
|
fprintf (stblfile, "{ CPUFUNC_FF(op_%lx_%d), 0, %ld }, /* %s */\n", opcode, opcode_last_postfix[rp], |
2301 |
< |
opcode, lookuptab[i].name); |
2301 |
> |
opcode, opcode_str); |
2302 |
|
else |
2303 |
|
fprintf (stblfile, "{ CPUFUNC(op_%lx_%d), 0, %ld }, /* %s */\n", opcode, opcode_last_postfix[rp], |
2304 |
< |
opcode, lookuptab[i].name); |
2304 |
> |
opcode, opcode_str); |
2305 |
|
return; |
2306 |
|
} |
2307 |
|
|
2308 |
|
if (table68k[opcode].flagdead == 0) |
2309 |
|
/* force to the "ff" variant since the instruction doesn't set at all the condition codes */ |
2310 |
< |
fprintf (stblfile, "{ CPUFUNC_FF(op_%lx_%d), 0, %ld }, /* %s */\n", opcode, postfix, opcode, lookuptab[i].name); |
2310 |
> |
fprintf (stblfile, "{ CPUFUNC_FF(op_%lx_%d), 0, %ld }, /* %s */\n", opcode, postfix, opcode, opcode_str); |
2311 |
|
else |
2312 |
< |
fprintf (stblfile, "{ CPUFUNC(op_%lx_%d), 0, %ld }, /* %s */\n", opcode, postfix, opcode, lookuptab[i].name); |
2312 |
> |
fprintf (stblfile, "{ CPUFUNC(op_%lx_%d), 0, %ld }, /* %s */\n", opcode, postfix, opcode, opcode_str); |
2313 |
|
|
2314 |
|
fprintf (headerfile, "extern cpuop_func op_%lx_%d_nf;\n", opcode, postfix); |
2315 |
|
fprintf (headerfile, "extern cpuop_func op_%lx_%d_ff;\n", opcode, postfix); |
2321 |
|
if (table68k[opcode].flagdead == 0) |
2322 |
|
printf ("#ifndef NOFLAGS\n"); |
2323 |
|
|
2324 |
< |
printf ("void REGPARAM2 CPUFUNC(op_%lx_%d)(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, lookuptab[i].name); |
2324 |
> |
printf ("void REGPARAM2 CPUFUNC(op_%lx_%d)(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, opcode_str); |
2325 |
|
printf ("\tcpuop_begin();\n"); |
2326 |
|
|
2327 |
|
switch (table68k[opcode].stype) { |