--- BasiliskII/src/uae_cpu/readcpu.cpp 2002/09/01 15:17:13 1.5 +++ BasiliskII/src/uae_cpu/readcpu.cpp 2012/03/30 01:25:46 1.11 @@ -4,6 +4,20 @@ * Read 68000 CPU specs from file "table68k" * * Copyright 1995,1996 Bernd Schmidt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include @@ -255,7 +269,7 @@ static void build_insn (int insn) int pos = 0; int mnp = 0; int bitno = 0; - char mnemonic[10]; + char mnemonic[64]; wordsizes sz = sz_long; int srcgather = 0, dstgather = 0; @@ -332,6 +346,11 @@ static void build_insn (int insn) } } mnp++; + if ((unsigned)mnp >= sizeof(mnemonic) - 1) { + mnemonic[sizeof(mnemonic) - 1] = 0; + fprintf(stderr, "Instruction %s overflow\n", mnemonic); + abort(); + } } pos++; } @@ -749,6 +768,34 @@ static void build_insn (int insn) } #endif + // Fix flags used information for Scc, Bcc, TRAPcc, DBcc instructions + if ( table68k[opc].mnemo == i_Scc + || table68k[opc].mnemo == i_Bcc + || table68k[opc].mnemo == i_DBcc + || table68k[opc].mnemo == i_TRAPcc + ) { + switch (table68k[opc].cc) { + // CC mask: XNZVC + // 8421 + case 0: flags_used = 0x00; break; /* T */ + case 1: flags_used = 0x00; break; /* F */ + case 2: flags_used = 0x05; break; /* HI */ + case 3: flags_used = 0x05; break; /* LS */ + case 4: flags_used = 0x01; break; /* CC */ + case 5: flags_used = 0x01; break; /* CS */ + case 6: flags_used = 0x04; break; /* NE */ + case 7: flags_used = 0x04; break; /* EQ */ + case 8: flags_used = 0x02; break; /* VC */ + case 9: flags_used = 0x02; break; /* VS */ + case 10:flags_used = 0x08; break; /* PL */ + case 11:flags_used = 0x08; break; /* MI */ + case 12:flags_used = 0x0A; break; /* GE */ + case 13:flags_used = 0x0A; break; /* LT */ + case 14:flags_used = 0x0E; break; /* GT */ + case 15:flags_used = 0x0E; break; /* LE */ + } + } + #if 1 /* gb-- flagdead and flaglive would not have correct information */ table68k[opc].flagdead = flags_set; @@ -776,66 +823,6 @@ void read_table68k (void) for (i = 0; i < n_defs68k; i++) { build_insn (i); } - - /* Extra fixes in table68k for control flow information and flag usage */ - for (i = 0; i < 65536; i++) { - instrmnem mnemo = (instrmnem)(table68k[i].mnemo); - -#define IS_CONST_JUMP(opc) \ - ( ((table68k[opc].mnemo == i_Bcc) && (table68k[opc].cc < 2)) \ - || (table68k[opc].mnemo == i_BSR) \ - ) - -#if 0 - // gb-- Don't follow false and true branches as we may not be - // able to determine the whole block length in bytes in order - // to compute the block checksum - - // We can follow unconditional jumps if neither Lazy Flusher - // nor Dynamic Code Patches feature is enabled - - // UPDATE: this is no longer permitted since we can decide - // at runtime whether the JIT compiler is used or not - if (IS_CONST_JUMP(i)) - table68k[i].cflow = fl_normal; -#endif - - // Fix flags used information for Scc, Bcc, TRAPcc, DBcc instructions - int flags_used = table68k[i].flaglive; - if ( (mnemo == i_Scc) - || (mnemo == i_Bcc) - || (mnemo == i_DBcc) - || (mnemo == i_TRAPcc) - ) { - switch (table68k[i].cc) { - // CC mask: XNZVC - // 8421 - case 0: flags_used = 0x00; break; /* T */ - case 1: flags_used = 0x00; break; /* F */ - case 2: flags_used = 0x05; break; /* HI */ - case 3: flags_used = 0x05; break; /* LS */ - case 4: flags_used = 0x01; break; /* CC */ - case 5: flags_used = 0x01; break; /* CS */ - case 6: flags_used = 0x04; break; /* NE */ - case 7: flags_used = 0x04; break; /* EQ */ - case 8: flags_used = 0x02; break; /* VC */ - case 9: flags_used = 0x02; break; /* VS */ - case 10:flags_used = 0x08; break; /* PL */ - case 11:flags_used = 0x08; break; /* MI */ - case 12:flags_used = 0x0A; break; /* GE */ - case 13:flags_used = 0x0A; break; /* LT */ - case 14:flags_used = 0x0E; break; /* GT */ - case 15:flags_used = 0x0E; break; /* LE */ - } - } - - /* Unconditional jumps don't evaluate condition codes, so they - don't actually use any flags themselves */ - if (IS_CONST_JUMP(i)) - flags_used = 0; - - table68k[i].flaglive = flags_used; - } } static int mismatch; @@ -935,3 +922,112 @@ int get_no_mismatches (void) { return mismatch; } + +const char *get_instruction_name (unsigned int opcode) +{ + struct instr *ins = &table68k[opcode]; + for (int i = 0; lookuptab[i].name[0]; i++) { + if (ins->mnemo == lookuptab[i].mnemo) + return lookuptab[i].name; + } + abort(); + return NULL; +} + +static char *get_ea_string (amodes mode, wordsizes size) +{ + static char buffer[80]; + + buffer[0] = 0; + switch (mode){ + case Dreg: + strcpy (buffer,"Dn"); + break; + case Areg: + strcpy (buffer,"An"); + break; + case Aind: + strcpy (buffer,"(An)"); + break; + case Aipi: + strcpy (buffer,"(An)+"); + break; + case Apdi: + strcpy (buffer,"-(An)"); + break; + case Ad16: + strcpy (buffer,"(d16,An)"); + break; + case Ad8r: + strcpy (buffer,"(d8,An,Xn)"); + break; + case PC16: + strcpy (buffer,"(d16,PC)"); + break; + case PC8r: + strcpy (buffer,"(d8,PC,Xn)"); + break; + case absw: + strcpy (buffer,"(xxx).W"); + break; + case absl: + strcpy (buffer,"(xxx).L"); + break; + case imm: + switch (size){ + case sz_byte: + strcpy (buffer,"#.B"); + break; + case sz_word: + strcpy (buffer,"#.W"); + break; + case sz_long: + strcpy (buffer,"#.L"); + break; + default: + break; + } + break; + case imm0: + strcpy (buffer,"#.B"); + break; + case imm1: + strcpy (buffer,"#.W"); + break; + case imm2: + strcpy (buffer,"#.L"); + break; + case immi: + strcpy (buffer,"#"); + break; + + default: + break; + } + return buffer; +} + +const char *get_instruction_string (unsigned int opcode) +{ + static char out[100]; + struct instr *ins; + + strcpy (out, get_instruction_name (opcode)); + + ins = &table68k[opcode]; + if (ins->size == sz_byte) + strcat (out,".B"); + if (ins->size == sz_word) + strcat (out,".W"); + if (ins->size == sz_long) + strcat (out,".L"); + strcat (out," "); + if (ins->suse) + strcat (out, get_ea_string (ins->smode, ins->size)); + if (ins->duse) { + if (ins->suse) + strcat (out,","); + strcat (out, get_ea_string (ins->dmode, ins->size)); + } + return out; +}