--- hatari/src/uae-cpu/gencpu.c 2019/04/01 07:09:28 1.1.1.2 +++ hatari/src/uae-cpu/gencpu.c 2019/04/01 07:10:59 1.1.1.5 @@ -19,9 +19,13 @@ * * Adaptation to Hatari and better cpu timings by Thomas Huth * + * This file is distributed under the GNU Public License, version 2 or at + * your option any later version. Read the file gpl.txt for details. */ +static char rcsid[] = "Hatari $Id: gencpu.c,v 1.1.1.5 2019/04/01 07:10:59 root Exp $"; #include +#include #include "sysdeps.h" #include "readcpu.h" @@ -220,7 +224,8 @@ static void sync_m68k_pc (void) } /* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0, - * the calling routine handles Apdi and Aipi modes. */ + * the calling routine handles Apdi and Aipi modes. + * gb-- movem == 2 means the same thing but for a MOVE16 instruction */ static void genamode (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem) { start_brace (); @@ -505,9 +510,10 @@ static void genastore (char *from, amode static void genmovemel (uae_u16 opcode) { char getcode[100]; - int size = table68k[opcode].size == sz_long ? 4 : 2; + int bMovemLong = (table68k[opcode].size == sz_long); + int size = bMovemLong ? 4 : 2; - if (table68k[opcode].size == sz_long) { + if (bMovemLong) { strcpy (getcode, "get_long(srca)"); } else { strcpy (getcode, "(uae_s32)(uae_s16)get_word(srca)"); @@ -515,22 +521,22 @@ static void genmovemel (uae_u16 opcode) printf ("\tuae_u16 mask = %s;\n", gen_nextiword ()); printf ("\tunsigned int dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); - genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1); printf ("\tretcycles = 0;\n"); + genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1); start_brace (); printf ("\twhile (dmask) { m68k_dreg(regs, movem_index1[dmask]) = %s;" - " srca += %d; dmask = movem_next[dmask]; retcycles+=1; }\n", - getcode, size); + " srca += %d; dmask = movem_next[dmask]; retcycles+=%d; }\n", + getcode, size, (bMovemLong ? 8 : 4)); printf ("\twhile (amask) { m68k_areg(regs, movem_index1[amask]) = %s;" - " srca += %d; amask = movem_next[amask]; retcycles+=1; }\n", - getcode, size); + " srca += %d; amask = movem_next[amask]; retcycles+=%d; }\n", + getcode, size, (bMovemLong ? 8 : 4)); if (table68k[opcode].dmode == Aipi) printf ("\tm68k_areg(regs, dstreg) = srca;\n"); /* Better cycles - experimental! (Thothy) */ switch(table68k[opcode].dmode) - { + { case Aind: insn_n_cycles=12; break; case Aipi: insn_n_cycles=12; break; case Ad16: insn_n_cycles=16; break; @@ -539,69 +545,59 @@ static void genmovemel (uae_u16 opcode) case absl: insn_n_cycles=20; break; case PC16: insn_n_cycles=16; break; case PC8r: insn_n_cycles=18; break; - } - /*I had some very stranges crashes when I included following code, so better leave it commented out* */ -#if 1 - if(table68k[opcode].size==sz_long) - sprintf(exactCpuCycles," return (%i+retcycles*8);", insn_n_cycles); - else - sprintf(exactCpuCycles," return (%i+retcycles*4);", insn_n_cycles); -#endif + } + sprintf(exactCpuCycles," return (%i+retcycles);", insn_n_cycles); } static void genmovemle (uae_u16 opcode) { char putcode[100]; - int size = table68k[opcode].size == sz_long ? 4 : 2; - if (table68k[opcode].size == sz_long) { + int bMovemLong = (table68k[opcode].size == sz_long); + int size = bMovemLong ? 4 : 2; + + if (bMovemLong) { strcpy (putcode, "put_long(srca,"); } else { strcpy (putcode, "put_word(srca,"); } printf ("\tuae_u16 mask = %s;\n", gen_nextiword ()); + printf ("\tretcycles = 0;\n"); genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1); if (using_prefetch) sync_m68k_pc (); - printf ("\tretcycles = 0;\n"); start_brace (); if (table68k[opcode].dmode == Apdi) { printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n"); printf ("\twhile (amask) { srca -= %d; %s m68k_areg(regs, movem_index2[amask]));" - " amask = movem_next[amask]; retcycles+=1; }\n", - size, putcode); + " amask = movem_next[amask]; retcycles+=%d; }\n", + size, putcode, (bMovemLong ? 8 : 4)); printf ("\twhile (dmask) { srca -= %d; %s m68k_dreg(regs, movem_index2[dmask]));" - " dmask = movem_next[dmask]; retcycles+=1; }\n", - size, putcode); + " dmask = movem_next[dmask]; retcycles+=%d; }\n", + size, putcode, (bMovemLong ? 8 : 4)); printf ("\tm68k_areg(regs, dstreg) = srca;\n"); } else { printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); printf ("\twhile (dmask) { %s m68k_dreg(regs, movem_index1[dmask])); srca += %d;" - " dmask = movem_next[dmask]; retcycles+=1; }\n", - putcode, size); + " dmask = movem_next[dmask]; retcycles+=%d; }\n", + putcode, size, (bMovemLong ? 8 : 4)); printf ("\twhile (amask) { %s m68k_areg(regs, movem_index1[amask])); srca += %d;" - " amask = movem_next[amask]; retcycles+=1; }\n", - putcode, size); + " amask = movem_next[amask]; retcycles+=%d; }\n", + putcode, size, (bMovemLong ? 8 : 4)); } /* Better cycles - experimental! (Thothy) */ switch(table68k[opcode].dmode) - { + { case Aind: insn_n_cycles=8; break; case Apdi: insn_n_cycles=8; break; case Ad16: insn_n_cycles=12; break; case Ad8r: insn_n_cycles=14; break; case absw: insn_n_cycles=12; break; case absl: insn_n_cycles=16; break; - } - /*I had some very stranges crashes when I included following code, so better leave it commented out* */ -#if 1 - if(table68k[opcode].size==sz_long) - sprintf(exactCpuCycles," return (%i+retcycles*8);", insn_n_cycles); - else - sprintf(exactCpuCycles," return (%i+retcycles*4);", insn_n_cycles); -#endif + } + sprintf(exactCpuCycles," return (%i+retcycles);", insn_n_cycles); } @@ -996,25 +992,23 @@ static void gen_opcode (unsigned long in } break; case i_SBCD: - /* Let's hope this works... */ genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); start_brace (); printf ("\tuae_u16 newv_lo = (dst & 0xF) - (src & 0xF) - (GET_XFLG ? 1 : 0);\n"); printf ("\tuae_u16 newv_hi = (dst & 0xF0) - (src & 0xF0);\n"); - printf ("\tuae_u16 newv;\n"); - printf ("\tint cflg;\n"); - printf ("\tif (newv_lo > 9) { newv_lo-=6; newv_hi-=0x10; }\n"); - printf ("\tnewv = newv_hi + (newv_lo & 0xF);"); - printf ("\tcflg = (newv_hi & 0x1F0) > 0x90;\n"); - printf ("\tSET_CFLG (cflg);\n"); + printf ("\tuae_u16 newv, tmp_newv;\n"); + printf ("\tint bcd = 0;\n"); + printf ("\tnewv = tmp_newv = newv_hi + newv_lo;\n"); + printf ("\tif (newv_lo & 0xF0) { newv -= 6; bcd = 6; };\n"); + printf ("\tif ((((dst & 0xFF) - (src & 0xFF) - (GET_XFLG ? 1 : 0)) & 0x100) > 0xFF) { newv -= 0x60; }\n"); + printf ("\tSET_CFLG ((((dst & 0xFF) - (src & 0xFF) - bcd - (GET_XFLG ? 1 : 0)) & 0x300) > 0xFF);\n"); duplicate_carry (); - printf ("\tif (cflg) newv -= 0x60;\n"); genflags (flag_zn, curi->size, "newv", "", ""); - genflags (flag_sv, curi->size, "newv", "src", "dst"); + printf ("\tSET_VFLG ((tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n"); genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); - if(curi->smode==Dreg) insn_n_cycles=6; - if(curi->smode==Apdi) insn_n_cycles=18; + if(curi->smode==Dreg) insn_n_cycles=6; + if(curi->smode==Apdi) insn_n_cycles=18; break; case i_ADD: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); @@ -1064,19 +1058,19 @@ static void gen_opcode (unsigned long in start_brace (); printf ("\tuae_u16 newv_lo = (src & 0xF) + (dst & 0xF) + (GET_XFLG ? 1 : 0);\n"); printf ("\tuae_u16 newv_hi = (src & 0xF0) + (dst & 0xF0);\n"); - printf ("\tuae_u16 newv;\n"); + printf ("\tuae_u16 newv, tmp_newv;\n"); printf ("\tint cflg;\n"); - printf ("\tif (newv_lo > 9) { newv_lo +=6; }\n"); - printf ("\tnewv = newv_hi + newv_lo;"); - printf ("\tcflg = (newv & 0x1F0) > 0x90;\n"); + printf ("\tnewv = tmp_newv = newv_hi + newv_lo;"); + printf ("\tif (newv_lo > 9) { newv += 6; }\n"); + printf ("\tcflg = (newv & 0x3F0) > 0x90;\n"); + printf ("\tif (cflg) newv += 0x60;\n"); printf ("\tSET_CFLG (cflg);\n"); duplicate_carry (); - printf ("\tif (cflg) newv += 0x60;\n"); genflags (flag_zn, curi->size, "newv", "", ""); - genflags (flag_sv, curi->size, "newv", "src", "dst"); + printf ("\tSET_VFLG ((tmp_newv & 0x80) == 0 && (newv & 0x80) != 0);\n"); genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); - if(curi->smode==Dreg) insn_n_cycles=6; - if(curi->smode==Apdi) insn_n_cycles=18; + if(curi->smode==Dreg) insn_n_cycles=6; + if(curi->smode==Apdi) insn_n_cycles=18; break; case i_NEG: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); @@ -1101,25 +1095,27 @@ static void gen_opcode (unsigned long in printf ("\tuae_u16 newv_hi = - (src & 0xF0);\n"); printf ("\tuae_u16 newv;\n"); printf ("\tint cflg;\n"); - printf ("\tif (newv_lo > 9) { newv_lo-=6; newv_hi-=0x10; }\n"); - printf ("\tnewv = newv_hi + (newv_lo & 0xF);"); - printf ("\tcflg = cflg = (newv_hi & 0x1F0) > 0x90;\n"); + printf ("\tif (newv_lo > 9) { newv_lo -= 6; }\n"); + printf ("\tnewv = newv_hi + newv_lo;"); + printf ("\tcflg = (newv & 0x1F0) > 0x90;\n"); + printf ("\tif (cflg) newv -= 0x60;\n"); printf ("\tSET_CFLG (cflg);\n"); duplicate_carry(); - printf ("\tif (cflg) newv -= 0x60;\n"); genflags (flag_zn, curi->size, "newv", "", ""); genastore ("newv", curi->smode, "srcreg", curi->size, "src"); - if(curi->smode==Dreg) insn_n_cycles += 2; + if(curi->smode==Dreg) insn_n_cycles += 2; break; case i_CLR: genamode (curi->smode, "srcreg", curi->size, "src", 2, 0); genflags (flag_logical, curi->size, "0", "", ""); genastore ("0", curi->smode, "srcreg", curi->size, "src"); if(curi->size==sz_long) + { if(curi->smode==Dreg) insn_n_cycles += 2; else insn_n_cycles += 4; + } if(curi->smode!=Dreg) insn_n_cycles += 4; break; @@ -1355,7 +1351,6 @@ static void gen_opcode (unsigned long in insn_n_cycles = 20; break; case i_RTD: - printf ("\tcompiler_flush_jsr_stack();\n"); genamode (Aipi, "7", sz_long, "pc", 1, 0); genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0); printf ("\tm68k_areg(regs, 7) += offs;\n"); @@ -1390,7 +1385,6 @@ static void gen_opcode (unsigned long in need_endlabel = 1; break; case i_RTR: - printf ("\tcompiler_flush_jsr_stack();\n"); printf ("\tMakeSR();\n"); genamode (Aipi, "7", sz_word, "sr", 1, 0); genamode (Aipi, "7", sz_long, "pc", 1, 0); @@ -1473,11 +1467,7 @@ static void gen_opcode (unsigned long in printf ("\t}\n"); need_endlabel = 1; } -#ifdef USE_COMPILER - printf ("\tm68k_setpc_bcc(m68k_getpc() + 2 + (uae_s32)src);\n"); -#else printf ("\tm68k_incpc ((uae_s32)src + 2);\n"); -#endif fill_prefetch_0 (); printf ("\treturn 10;\n"); printf ("didnt_jump:;\n"); @@ -1522,11 +1512,7 @@ static void gen_opcode (unsigned long in printf ("\t\t}\n"); need_endlabel = 1; } -#ifdef USE_COMPILER - printf ("\t\t\tm68k_setpc_bcc(m68k_getpc() + (uae_s32)offs + 2);\n"); -#else printf ("\t\t\tm68k_incpc((uae_s32)offs + 2);\n"); -#endif fill_prefetch_0 (); printf ("\t\t\treturn 10;\n"); printf ("\t\t} else {\n\t\t\t"); @@ -2241,6 +2227,8 @@ static void gen_opcode (unsigned long in break; case i_BFINS: printf ("\ttmp = m68k_dreg(regs, (extra >> 12) & 7);\n"); + printf ("\tSET_NFLG (tmp & (1 << (width - 1)) ? 1 : 0);\n"); + printf ("\tSET_ZFLG (tmp == 0);\n"); break; default: break; @@ -2357,15 +2345,33 @@ static void gen_opcode (unsigned long in case i_CPUSHA: break; case i_MOVE16: - printf ("\tuaecptr mems = m68k_areg(regs, srcreg) & ~15, memd;\n"); - printf ("\tdstreg = (%s >> 12) & 7;\n", gen_nextiword()); - printf ("\tmemd = m68k_areg(regs, dstreg) & ~15;\n"); - printf ("\tput_long(memd, get_long(mems));\n"); - printf ("\tput_long(memd+4, get_long(mems+4));\n"); - printf ("\tput_long(memd+8, get_long(mems+8));\n"); - printf ("\tput_long(memd+12, get_long(mems+12));\n"); - printf ("\tm68k_areg(regs, srcreg) += 16;\n"); - printf ("\tm68k_areg(regs, dstreg) += 16;\n"); + if ((opcode & 0xfff8) == 0xf620) { + /* MOVE16 (Ax)+,(Ay)+ */ + printf ("\tuaecptr mems = m68k_areg(regs, srcreg) & ~15, memd;\n"); + printf ("\tdstreg = (%s >> 12) & 7;\n", gen_nextiword()); + printf ("\tmemd = m68k_areg(regs, dstreg) & ~15;\n"); + printf ("\tput_long(memd, get_long(mems));\n"); + printf ("\tput_long(memd+4, get_long(mems+4));\n"); + printf ("\tput_long(memd+8, get_long(mems+8));\n"); + printf ("\tput_long(memd+12, get_long(mems+12));\n"); + printf ("\tif (srcreg != dstreg)\n"); + printf ("\tm68k_areg(regs, srcreg) += 16;\n"); + printf ("\tm68k_areg(regs, dstreg) += 16;\n"); + } else { + /* Other variants */ + genamode (curi->smode, "srcreg", curi->size, "mems", 0, 2); + genamode (curi->dmode, "dstreg", curi->size, "memd", 0, 2); + printf ("\tmemsa &= ~15;\n"); + printf ("\tmemda &= ~15;\n"); + printf ("\tput_long(memda, get_long(memsa));\n"); + printf ("\tput_long(memda+4, get_long(memsa+4));\n"); + printf ("\tput_long(memda+8, get_long(memsa+8));\n"); + printf ("\tput_long(memda+12, get_long(memsa+12));\n"); + if ((opcode & 0xfff8) == 0xf600) + printf ("\tm68k_areg(regs, srcreg) += 16;\n"); + else if ((opcode & 0xfff8) == 0xf608) + printf ("\tm68k_areg(regs, dstreg) += 16;\n"); + } break; case i_MMUOP: @@ -2388,7 +2394,6 @@ static void generate_includes (FILE * f) fprintf (f, "#include \"maccess.h\"\n"); fprintf (f, "#include \"memory.h\"\n"); fprintf (f, "#include \"newcpu.h\"\n"); - fprintf (f, "#include \"compiler.h\"\n"); fprintf (f, "#include \"cputbl.h\"\n"); fprintf (f, "#define CPUFUNC(x) x##_ff\n" "#ifdef NOFLAGS\n" @@ -2435,6 +2440,7 @@ static void generate_one_opcode (int rp) case 3: smsk = 7; break; case 4: smsk = 7; break; case 5: smsk = 63; break; + case 7: smsk = 3; break; default: abort (); } dmsk = 7;