/[gxemul]/trunk/src/cpus/cpu_sh.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/cpus/cpu_sh.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 28 by dpavlin, Mon Oct 8 16:20:26 2007 UTC revision 36 by dpavlin, Mon Oct 8 16:21:34 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005-2006  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_sh.c,v 1.17 2006/07/16 13:32:26 debug Exp $   *  $Id: cpu_sh.c,v 1.62 2007/03/08 19:04:09 debug Exp $
29   *   *
30   *  Hitachi SuperH ("SH") CPU emulation.   *  Hitachi SuperH ("SH") CPU emulation.
31   *   *
32   *  TODO   *  TODO: It would be nice if this could encompass both 64-bit SH5, and
33     *        32-bit SH encodings. Right now, it only really supports 32-bit mode.
34   */   */
35    
36  #include <stdio.h>  #include <stdio.h>
37  #include <stdlib.h>  #include <stdlib.h>
38  #include <string.h>  #include <string.h>
39  #include <ctype.h>  #include <ctype.h>
40    #include <unistd.h>
41    
42  #include "cpu.h"  #include "cpu.h"
43    #include "device.h"
44    #include "float_emul.h"
45    #include "interrupt.h"
46  #include "machine.h"  #include "machine.h"
47  #include "memory.h"  #include "memory.h"
48  #include "misc.h"  #include "misc.h"
49    #include "settings.h"
50  #include "symbol.h"  #include "symbol.h"
51    
52    #include "sh4_exception.h"
53    #include "sh4_mmu.h"
54    
55  #define DYNTRANS_DUALMODE_32  
56    #define DYNTRANS_32
57    #define DYNTRANS_DELAYSLOT
58  #include "tmp_sh_head.c"  #include "tmp_sh_head.c"
59    
60    
61    extern int quiet_mode;
62    
63    void sh_pc_to_pointers(struct cpu *);
64    
65    
66  /*  /*
67   *  sh_cpu_new():   *  sh_cpu_new():
68   *   *
# Line 59  Line 74 
74  int sh_cpu_new(struct cpu *cpu, struct memory *mem, struct machine *machine,  int sh_cpu_new(struct cpu *cpu, struct memory *mem, struct machine *machine,
75          int cpu_id, char *cpu_type_name)          int cpu_id, char *cpu_type_name)
76  {  {
77          if (strcasecmp(cpu_type_name, "SH") != 0)          int i = 0;
78            struct sh_cpu_type_def cpu_type_defs[] = SH_CPU_TYPE_DEFS;
79    
80            /*  Scan the cpu_type_defs list for this cpu type:  */
81            while (cpu_type_defs[i].name != NULL) {
82                    if (strcasecmp(cpu_type_defs[i].name, cpu_type_name) == 0) {
83                            break;
84                    }
85                    i++;
86            }
87            if (cpu_type_defs[i].name == NULL)
88                  return 0;                  return 0;
89    
90          cpu->memory_rw = sh_memory_rw;          cpu->memory_rw = sh_memory_rw;
91    
92          /*  TODO: per CPU type?  */          cpu->cd.sh.cpu_type = cpu_type_defs[i];
93          cpu->byte_order = EMUL_LITTLE_ENDIAN;          cpu->byte_order = EMUL_LITTLE_ENDIAN;
94          cpu->is_32bit = 1;          cpu->is_32bit = cpu->cd.sh.cpu_type.bits == 32;
95          cpu->cd.sh.bits = 32;          cpu->cd.sh.compact = 1;         /*  Default to 16-bit opcode mode  */
96          cpu->cd.sh.compact = 1;  
97            if (!cpu->is_32bit) {
98          if (cpu->is_32bit) {                  fatal("SH64 emulation not implemented. Sorry.\n");
99                  cpu->run_instr = sh32_run_instr;                  exit(1);
                 cpu->update_translation_table = sh32_update_translation_table;  
                 cpu->invalidate_translation_caches =  
                     sh32_invalidate_translation_caches;  
                 cpu->invalidate_code_translation =  
                     sh32_invalidate_code_translation;  
         } else {  
                 cpu->run_instr = sh_run_instr;  
                 cpu->update_translation_table = sh_update_translation_table;  
                 cpu->invalidate_translation_caches =  
                     sh_invalidate_translation_caches;  
                 cpu->invalidate_code_translation =  
                     sh_invalidate_code_translation;  
100          }          }
101    
102            cpu->instruction_has_delayslot = sh_cpu_instruction_has_delayslot;
103    
104            cpu->translate_v2p = sh_translate_v2p;
105    
106            cpu->run_instr = sh_run_instr;
107            cpu->update_translation_table = sh_update_translation_table;
108            cpu->invalidate_translation_caches =
109                sh_invalidate_translation_caches;
110            cpu->invalidate_code_translation =
111                sh_invalidate_code_translation;
112    
113          /*  Only show name and caches etc for CPU nr 0 (in SMP machines):  */          /*  Only show name and caches etc for CPU nr 0 (in SMP machines):  */
114          if (cpu_id == 0) {          if (cpu_id == 0) {
115                  debug("%s", cpu->name);                  debug("%s", cpu->name);
116          }          }
117    
118            /*  Initial value of FPSCR (according to the SH4 manual):  */
119            cpu->cd.sh.fpscr = 0x00040001;
120    
121            /*  (Initial value of the program counter on reboot is 0xA0000000.)  */
122    
123            /*  Start in Privileged Mode:  */
124            cpu->cd.sh.sr = SH_SR_MD | SH_SR_IMASK;
125    
126            /*  Stack pointer at end of physical RAM:  */
127            cpu->cd.sh.r[15] = cpu->machine->physical_ram_in_mb * 1048576 - 64;
128    
129            CPU_SETTINGS_ADD_REGISTER64("pc", cpu->pc);
130            CPU_SETTINGS_ADD_REGISTER32("sr", cpu->cd.sh.sr);
131            CPU_SETTINGS_ADD_REGISTER32("pr", cpu->cd.sh.pr);
132            CPU_SETTINGS_ADD_REGISTER32("vbr", cpu->cd.sh.vbr);
133            CPU_SETTINGS_ADD_REGISTER32("gbr", cpu->cd.sh.gbr);
134            CPU_SETTINGS_ADD_REGISTER32("macl", cpu->cd.sh.macl);
135            CPU_SETTINGS_ADD_REGISTER32("mach", cpu->cd.sh.mach);
136            CPU_SETTINGS_ADD_REGISTER32("expevt", cpu->cd.sh.expevt);
137            CPU_SETTINGS_ADD_REGISTER32("intevt", cpu->cd.sh.intevt);
138            CPU_SETTINGS_ADD_REGISTER32("tra", cpu->cd.sh.tra);
139            CPU_SETTINGS_ADD_REGISTER32("fpscr", cpu->cd.sh.fpscr);
140            CPU_SETTINGS_ADD_REGISTER32("fpul", cpu->cd.sh.fpul);
141            for (i=0; i<SH_N_GPRS; i++) {
142                    char tmpstr[5];
143                    snprintf(tmpstr, sizeof(tmpstr), "r%i", i);
144                    CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.r[i]);
145            }
146            for (i=0; i<SH_N_GPRS_BANKED; i++) {
147                    char tmpstr[15];
148                    snprintf(tmpstr, sizeof(tmpstr), "r%i_bank", i);
149                    CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.r_bank[i]);
150            }
151            for (i=0; i<SH_N_FPRS; i++) {
152                    char tmpstr[6];
153                    snprintf(tmpstr, sizeof(tmpstr), "fr%i", i);
154                    CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.fr[i]);
155                    snprintf(tmpstr, sizeof(tmpstr), "xf%i", i);
156                    CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.xf[i]);
157            }
158            for (i=0; i<SH_N_ITLB_ENTRIES; i++) {
159                    char tmpstr[15];
160                    snprintf(tmpstr, sizeof(tmpstr), "itlb_hi_%i", i);
161                    CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.itlb_hi[i]);
162                    snprintf(tmpstr, sizeof(tmpstr), "itlb_lo_%i", i);
163                    CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.itlb_lo[i]);
164            }
165            for (i=0; i<SH_N_UTLB_ENTRIES; i++) {
166                    char tmpstr[15];
167                    snprintf(tmpstr, sizeof(tmpstr), "utlb_hi_%i", i);
168                    CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.utlb_hi[i]);
169                    snprintf(tmpstr, sizeof(tmpstr), "utlb_lo_%i", i);
170                    CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.utlb_lo[i]);
171            }
172    
173            /*  Register the CPU's interrupts:  */
174            for (i=SH_INTEVT_NMI; i<0x1000; i+=0x20) {
175                    struct interrupt template;
176                    char name[100];
177                    snprintf(name, sizeof(name), "%s.irq[0x%x]", cpu->path, i);
178                    memset(&template, 0, sizeof(template));
179                    template.line = i;
180                    template.name = name;
181                    template.extra = cpu;
182                    template.interrupt_assert = sh_cpu_interrupt_assert;
183                    template.interrupt_deassert = sh_cpu_interrupt_deassert;
184                    interrupt_handler_register(&template);
185            }
186    
187            /*  SH4-specific memory mapped registers, TLBs, caches, etc:  */
188            if (cpu->cd.sh.cpu_type.arch == 4)
189                    device_add(machine, "sh4");
190    
191          return 1;          return 1;
192  }  }
193    
194    
195  /*  /*
196     *  sh_cpu_interrupt_assert():
197     */
198    void sh_cpu_interrupt_assert(struct interrupt *interrupt)
199    {
200            struct cpu *cpu = interrupt->extra;
201            int irq_nr = interrupt->line;
202            int word_index, bit_index;
203    
204            /*
205             *  Note: This gives higher interrupt priority to lower number
206             *  interrupts. Hopefully this is correct.
207             */
208    
209            if (cpu->cd.sh.int_to_assert == 0 || irq_nr < cpu->cd.sh.int_to_assert)
210                    cpu->cd.sh.int_to_assert = irq_nr;
211    
212            /*
213             *  TODO: Keep track of all pending interrupts at multiple levels...
214             *
215             *  This is just a quick hack:
216             */
217            cpu->cd.sh.int_level = 1;
218            if (irq_nr == SH_INTEVT_TMU0_TUNI0)
219                    cpu->cd.sh.int_level = (cpu->cd.sh.intc_ipra >> 12) & 0xf;
220            if (irq_nr == SH_INTEVT_TMU1_TUNI1)
221                    cpu->cd.sh.int_level = (cpu->cd.sh.intc_ipra >> 8) & 0xf;
222            if (irq_nr == SH_INTEVT_TMU2_TUNI2)
223                    cpu->cd.sh.int_level = (cpu->cd.sh.intc_ipra >> 4) & 0xf;
224            if (irq_nr >= SH4_INTEVT_SCIF_ERI &&
225                irq_nr <= SH4_INTEVT_SCIF_TXI)
226                    cpu->cd.sh.int_level = (cpu->cd.sh.intc_iprc >> 4) & 0xf;
227    
228            irq_nr /= 0x20;
229            word_index = irq_nr / (sizeof(uint32_t)*8);
230            bit_index = irq_nr & ((sizeof(uint32_t)*8) - 1);
231    
232            cpu->cd.sh.int_pending[word_index] |= (1 << bit_index);
233    }
234    
235    
236    /*
237     *  sh_cpu_interrupt_deassert():
238     */
239    void sh_cpu_interrupt_deassert(struct interrupt *interrupt)
240    {
241            struct cpu *cpu = interrupt->extra;
242            int irq_nr = interrupt->line;
243            int word_index, bit_index;
244    
245            if (cpu->cd.sh.int_to_assert == irq_nr) {
246                    /*
247                     *  Rescan all interrupts to see if any are still asserted.
248                     *
249                     *  Note: The scan only has to go from irq_nr + 0x20 to the max
250                     *        index, since any lower interrupt cannot be asserted
251                     *        at this time.
252                     */
253                    int i, max = 0x1000;
254                    cpu->cd.sh.int_to_assert = 0;
255    
256                    for (i=irq_nr+0x20; i<max; i+=0x20) {
257                            int j = i / 0x20;
258                            int word_index = j / (sizeof(uint32_t)*8);
259                            int bit_index = j & ((sizeof(uint32_t)*8) - 1);
260    
261                            /*  Skip entire word if no bits are set:  */
262                            if (bit_index == 0 &&
263                                cpu->cd.sh.int_pending[word_index] == 0)
264                                    i += (sizeof(uint32_t)*8 - 1) * 0x20;
265                            else if (cpu->cd.sh.int_pending[word_index]
266                                & (1 << bit_index)) {
267                                    cpu->cd.sh.int_to_assert = i;
268    
269    
270    /*  Hack. TODO: Fix.  */
271            cpu->cd.sh.int_level = 1;
272            if (i == SH_INTEVT_TMU0_TUNI0)
273                    cpu->cd.sh.int_level = (cpu->cd.sh.intc_ipra >> 12) & 0xf;
274            if (i == SH_INTEVT_TMU1_TUNI1)
275                    cpu->cd.sh.int_level = (cpu->cd.sh.intc_ipra >> 8) & 0xf;
276            if (i == SH_INTEVT_TMU2_TUNI2)
277                    cpu->cd.sh.int_level = (cpu->cd.sh.intc_ipra >> 4) & 0xf;
278            if (i >= SH4_INTEVT_SCIF_ERI &&
279                i <= SH4_INTEVT_SCIF_TXI)
280                    cpu->cd.sh.int_level = (cpu->cd.sh.intc_iprc >> 4) & 0xf;
281    
282    
283                                    break;
284                            }
285                    }
286            }
287    
288            irq_nr /= 0x20;
289            word_index = irq_nr / (sizeof(uint32_t)*8);
290            bit_index = irq_nr & ((sizeof(uint32_t)*8) - 1);
291    
292            cpu->cd.sh.int_pending[word_index] &= ~(1 << bit_index);
293    }
294    
295    
296    /*
297   *  sh_cpu_list_available_types():   *  sh_cpu_list_available_types():
298   *   *
299   *  Print a list of available SH CPU types.   *  Print a list of available SH CPU types.
300   */   */
301  void sh_cpu_list_available_types(void)  void sh_cpu_list_available_types(void)
302  {  {
303          debug("SH\n");          int i = 0, j;
304          /*  TODO  */          struct sh_cpu_type_def tdefs[] = SH_CPU_TYPE_DEFS;
305    
306            while (tdefs[i].name != NULL) {
307                    debug("%s", tdefs[i].name);
308                    for (j=10 - strlen(tdefs[i].name); j>0; j--)
309                            debug(" ");
310                    i ++;
311                    if ((i % 6) == 0 || tdefs[i].name == NULL)
312                            debug("\n");
313            }
314  }  }
315    
316    
# Line 112  void sh_cpu_list_available_types(void) Line 319  void sh_cpu_list_available_types(void)
319   */   */
320  void sh_cpu_dumpinfo(struct cpu *cpu)  void sh_cpu_dumpinfo(struct cpu *cpu)
321  {  {
322          debug("\n");          debug(" (%s-endian)\n",
323          /*  TODO  */              cpu->byte_order == EMUL_BIG_ENDIAN? "Big" : "Little");
324    }
325    
326    
327    /*
328     *  sh_cpu_instruction_has_delayslot():
329     *
330     *  Return 1 if an opcode is a branch, 0 otherwise.
331     */
332    int sh_cpu_instruction_has_delayslot(struct cpu *cpu, unsigned char *ib)
333    {
334            uint16_t iword = *((uint16_t *)&ib[0]);
335            int hi4, lo4, lo8;
336    
337            if (!cpu->is_32bit)
338                    return 0;
339    
340            if (cpu->byte_order == EMUL_BIG_ENDIAN)
341                    iword = BE16_TO_HOST(iword);
342            else
343                    iword = LE16_TO_HOST(iword);
344    
345            hi4 = iword >> 12; lo4 = iword & 15; lo8 = iword & 255;
346    
347            switch (hi4) {
348            case 0x0:
349                    if (iword == 0x000b)    /*  rts  */
350                            return 1;
351                    if (iword == 0x002b)    /*  rte  */
352                            return 1;
353                    if (lo8 == 0x03)        /*  bsrf  */
354                            return 1;
355                    if (lo8 == 0x23)        /*  braf  */
356                            return 1;
357                    break;
358            case 0x4:
359                    switch (lo8) {
360                    case 0x0b:      /*  jsr  */
361                    case 0x2b:      /*  jmp  */
362                            return 1;
363                    }
364                    break;
365            case 0x8:
366                    switch ((iword >> 8) & 0xf) {
367                    case 0xd:       /*  bt/s  */
368                    case 0xf:       /*  bf/s  */
369                            return 1;
370                    }
371                    break;
372            case 0xa:       /*  bra  */
373            case 0xb:       /*  bsr  */
374                    return 1;
375            }
376    
377            return 0;
378  }  }
379    
380    
# Line 130  void sh_cpu_register_dump(struct cpu *cp Line 391  void sh_cpu_register_dump(struct cpu *cp
391          char *symbol;          char *symbol;
392          uint64_t offset;          uint64_t offset;
393          int i, x = cpu->cpu_id, nregs = cpu->cd.sh.compact? 16 : 64;          int i, x = cpu->cpu_id, nregs = cpu->cd.sh.compact? 16 : 64;
         int bits32 = cpu->cd.sh.bits == 32;  
394    
395          if (gprs) {          if (gprs) {
396                  /*  Special registers (pc, ...) first:  */                  /*  Special registers (pc, ...) first:  */
397                  symbol = get_symbol_name(&cpu->machine->symbol_context,                  symbol = get_symbol_name(&cpu->machine->symbol_context,
398                      cpu->pc, &offset);                      cpu->pc, &offset);
399    
400                  debug("cpu%i: pc  = 0x", x);                  debug("cpu%i: pc  = 0x%08"PRIx32, x, (uint32_t)cpu->pc);
                 if (bits32)  
                         debug("%08x", (int)cpu->pc);  
                 else  
                         debug("%016llx", (long long)cpu->pc);  
401                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");
402    
403                  if (bits32) {                  debug("cpu%i: sr  = 0x%08"PRIx32"  (%s, %s, %s, %s, %s, %s,"
404                          /*  32-bit:  */                      " imask=0x%x, %s, %s)\n", x, (int32_t)cpu->cd.sh.sr,
405                          for (i=0; i<nregs; i++) {                      (cpu->cd.sh.sr & SH_SR_MD)? "MD" : "!md",
406                                  if ((i % 4) == 0)                      (cpu->cd.sh.sr & SH_SR_RB)? "RB" : "!rb",
407                                          debug("cpu%i:", x);                      (cpu->cd.sh.sr & SH_SR_BL)? "BL" : "!bl",
408                                  debug(" r%02i = 0x%08x ", i,                      (cpu->cd.sh.sr & SH_SR_FD)? "FD" : "!fd",
409                                      (int)cpu->cd.sh.r[i]);                      (cpu->cd.sh.sr & SH_SR_M)? "M" : "!m",
410                                  if ((i % 4) == 3)                      (cpu->cd.sh.sr & SH_SR_Q)? "Q" : "!q",
411                                          debug("\n");                      (cpu->cd.sh.sr & SH_SR_IMASK) >> SH_SR_IMASK_SHIFT,
412                          }                      (cpu->cd.sh.sr & SH_SR_S)? "S" : "!s",
413                  } else {                      (cpu->cd.sh.sr & SH_SR_T)? "T" : "!t");
                         /*  64-bit:  */  
                         for (i=0; i<nregs; i++) {  
                                 int r = (i >> 1) + ((i & 1) << 4);  
                                 if ((i % 2) == 0)  
                                         debug("cpu%i:", x);  
                                 debug(" r%02i = 0x%016llx ", r,  
                                     (long long)cpu->cd.sh.r[r]);  
                                 if ((i % 2) == 1)  
                                         debug("\n");  
                         }  
                 }  
         }  
 }  
414    
415                    symbol = get_symbol_name(&cpu->machine->symbol_context,
416                        cpu->cd.sh.pr, &offset);
417                    debug("cpu%i: pr  = 0x%08"PRIx32, x, (uint32_t)cpu->cd.sh.pr);
418                    debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");
419    
420  /*                  debug("cpu%i: mach = 0x%08"PRIx32"  macl = 0x%08"PRIx32
421   *  sh_cpu_register_match():                      "  gbr = 0x%08"PRIx32"\n", x, (uint32_t)cpu->cd.sh.mach,
422   */                      (uint32_t)cpu->cd.sh.macl, (uint32_t)cpu->cd.sh.gbr);
423  void sh_cpu_register_match(struct machine *m, char *name,  
424          int writeflag, uint64_t *valuep, int *match_register)                  for (i=0; i<nregs; i++) {
425  {                          if ((i % 4) == 0)
426          int cpunr = 0;                                  debug("cpu%i:", x);
427                            debug(" r%-2i = 0x%08x ", i, (int)cpu->cd.sh.r[i]);
428                            if ((i % 4) == 3)
429                                    debug("\n");
430                    }
431            }
432    
433          /*  CPU number:  */          if (coprocs & 1) {
434                    /*  Floating point:  */
435                    debug("cpu%i: fpscr = 0x%08"PRIx32"  fpul = 0x%08"PRIx32
436                        "\n", x, cpu->cd.sh.fpscr, cpu->cd.sh.fpul);
437    
438                    for (i=0; i<SH_N_FPRS; i++) {
439                            if ((i % 4) == 0)
440                                    debug("cpu%i:", x);
441                            debug(" fr%-2i=0x%08x ", i, (int)cpu->cd.sh.fr[i]);
442                            if ((i % 4) == 3)
443                                    debug("\n");
444                    }
445    
446          /*  TODO  */                  for (i=0; i<SH_N_FPRS; i++) {
447                            if ((i % 4) == 0)
448                                    debug("cpu%i:", x);
449                            debug(" xf%-2i=0x%08x ", i, (int)cpu->cd.sh.xf[i]);
450                            if ((i % 4) == 3)
451                                    debug("\n");
452                    }
453            }
454    
455          /*  Register name:  */          if (coprocs & 2) {
456          if (strcasecmp(name, "pc") == 0) {                  /*  System registers, etc:  */
457                  if (writeflag) {                  debug("cpu%i: vbr = 0x%08"PRIx32"  sgr = 0x%08"PRIx32
458                          m->cpus[cpunr]->pc = *valuep;                      "\n", x, cpu->cd.sh.vbr, cpu->cd.sh.sgr);
459                  } else                  debug("cpu%i: spc = 0x%08"PRIx32"  ssr = 0x%08"PRIx32"\n",
460                          *valuep = m->cpus[cpunr]->pc;                      x, cpu->cd.sh.spc, cpu->cd.sh.ssr);
461                  *match_register = 1;                  debug("cpu%i: expevt = 0x%"PRIx32"  intevt = 0x%"PRIx32
462                        "  tra = 0x%"PRIx32"\n", x, cpu->cd.sh.expevt,
463                        cpu->cd.sh.intevt, cpu->cd.sh.tra);
464    
465                    for (i=0; i<SH_N_GPRS_BANKED; i++) {
466                            if ((i % 2) == 0)
467                                    debug("cpu%i:", x);
468                            debug(" r%i_bank = 0x%08x ", i,
469                                (int)cpu->cd.sh.r_bank[i]);
470                            if ((i % 2) == 1)
471                                    debug("\n");
472                    }
473          }          }
474  }  }
475    
# Line 204  void sh_cpu_register_match(struct machin Line 485  void sh_cpu_register_match(struct machin
485   */   */
486  void sh_cpu_tlbdump(struct machine *m, int x, int rawflag)  void sh_cpu_tlbdump(struct machine *m, int x, int rawflag)
487  {  {
488            int i, j;
489    
490            for (j=0; j<m->ncpus; j++) {
491                    struct cpu *cpu = m->cpus[j];
492    
493                    if (x >= 0 && j != x)
494                            continue;
495    
496                    for (i=0; i<SH_N_ITLB_ENTRIES; i++)
497                            printf("cpu%i: itlb_hi_%-2i = 0x%08"PRIx32"  "
498                                "itlb_lo_%-2i = 0x%08"PRIx32"\n", j, i,
499                                (uint32_t) cpu->cd.sh.itlb_hi[i], i,
500                                (uint32_t) cpu->cd.sh.itlb_lo[i]);
501                    for (i=0; i<SH_N_UTLB_ENTRIES; i++)
502                            printf("cpu%i: utlb_hi_%-2i = 0x%08"PRIx32"  "
503                                "utlb_lo_%-2i = 0x%08"PRIx32"\n", j, i,
504                                (uint32_t) cpu->cd.sh.utlb_hi[i], i,
505                                (uint32_t) cpu->cd.sh.utlb_lo[i]);
506            }
507  }  }
508    
509    
# Line 221  char *sh_cpu_gdb_stub(struct cpu *cpu, c Line 521  char *sh_cpu_gdb_stub(struct cpu *cpu, c
521    
522    
523  /*  /*
524   *  sh_cpu_interrupt():   *  sh_update_sr():
525     *
526     *  Writes a new value to the status register.
527   */   */
528  int sh_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)  void sh_update_sr(struct cpu *cpu, uint32_t new_sr)
529  {  {
530          fatal("sh_cpu_interrupt(): TODO\n");          uint32_t old_sr = cpu->cd.sh.sr;
531          return 0;  
532            if ((new_sr & SH_SR_RB) != (old_sr & SH_SR_RB)) {
533                    int i;
534                    for (i=0; i<SH_N_GPRS_BANKED; i++) {
535                            uint32_t tmp = cpu->cd.sh.r[i];
536                            cpu->cd.sh.r[i] = cpu->cd.sh.r_bank[i];
537                            cpu->cd.sh.r_bank[i] = tmp;
538                    }
539            }
540    
541            cpu->cd.sh.sr = new_sr;
542  }  }
543    
544    
545  /*  /*
546   *  sh_cpu_interrupt_ack():   *  sh_update_fpscr():
547     *
548     *  Writes a new value to the floating-point status/control register.
549   */   */
550  int sh_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)  void sh_update_fpscr(struct cpu *cpu, uint32_t new_fpscr)
551  {  {
552          /*  fatal("sh_cpu_interrupt_ack(): TODO\n");  */          uint32_t old_fpscr = cpu->cd.sh.fpscr;
553          return 0;  
554            if ((new_fpscr & SH_FPSCR_FR) != (old_fpscr & SH_FPSCR_FR)) {
555                    int i;
556                    for (i=0; i<SH_N_FPRS; i++) {
557                            uint32_t tmp = cpu->cd.sh.fr[i];
558                            cpu->cd.sh.fr[i] = cpu->cd.sh.xf[i];
559                            cpu->cd.sh.xf[i] = tmp;
560                    }
561            }
562    
563            cpu->cd.sh.fpscr = new_fpscr;
564    }
565    
566    
567    /*
568     *  sh_exception():
569     *
570     *  Causes a transfer of control to an exception or interrupt handler.
571     *  If intevt > 0, then it is an interrupt, otherwise an exception.
572     */
573    void sh_exception(struct cpu *cpu, int expevt, int intevt, uint32_t vaddr)
574    {
575            uint32_t vbr = cpu->cd.sh.vbr;
576    
577            if (!quiet_mode) {
578                    if (intevt > 0)
579                            debug("[ interrupt 0x%03x", intevt);
580                    else
581                            debug("[ exception 0x%03x", expevt);
582    
583                    debug(", pc=0x%08"PRIx32" ", (uint32_t)vaddr);
584                    if (intevt == 0)
585                            debug("vaddr=0x%08"PRIx32" ", vaddr);
586    
587                    debug(" ]\n");
588            }
589    
590            if (cpu->cd.sh.sr & SH_SR_BL) {
591                    fatal("sh_exception(): BL bit already set. TODO\n");
592    
593                    /*  This is actually OK in two cases: a User Break,
594                        or on NMI interrupts if a special flag is set?  */
595                    /*  TODO  */
596    
597                    expevt = EXPEVT_RESET_POWER;
598            }
599    
600            if (cpu->is_halted) {
601                    /*
602                     *  If the exception occurred on a 'sleep' instruction, then let
603                     *  the instruction following the sleep instruction be the one
604                     *  where execution resumes when the interrupt service routine
605                     *  returns.
606                     */
607                    cpu->is_halted = 0;
608                    cpu->pc += sizeof(uint16_t);
609            }
610    
611            if (cpu->delay_slot) {
612                    cpu->delay_slot = EXCEPTION_IN_DELAY_SLOT;
613                    cpu->pc -= sizeof(uint16_t);
614            }
615    
616            /*  Stuff common to all exceptions:  */
617            cpu->cd.sh.spc = cpu->pc;
618            cpu->cd.sh.ssr = cpu->cd.sh.sr;
619            cpu->cd.sh.sgr = cpu->cd.sh.r[15];
620            if (intevt > 0) {
621                    cpu->cd.sh.intevt = intevt;
622                    expevt = -1;
623            } else
624                    cpu->cd.sh.expevt = expevt;
625            sh_update_sr(cpu, cpu->cd.sh.sr | SH_SR_MD | SH_SR_RB | SH_SR_BL);
626    
627            /*  Most exceptions set PC to VBR + 0x100.  */
628            cpu->pc = vbr + 0x100;
629    
630            /*  Specific cases:  */
631            switch (expevt) {
632    
633            case -1:        /*  Interrupt  */
634                    cpu->pc = vbr + 0x600;
635                    break;
636    
637            case EXPEVT_RESET_POWER:
638            case EXPEVT_RESET_MANUAL:
639                    cpu->pc = 0xa0000000;
640                    cpu->cd.sh.vbr = 0x00000000;
641                    sh_update_sr(cpu, (cpu->cd.sh.sr | SH_SR_IMASK) & ~SH_SR_FD);
642                    break;
643    
644            case EXPEVT_TLB_MISS_LD:
645            case EXPEVT_TLB_MISS_ST:
646                    cpu->pc = vbr + 0x400;
647            case EXPEVT_TLB_PROT_LD:
648            case EXPEVT_TLB_PROT_ST:
649            case EXPEVT_TLB_MOD:
650                    cpu->cd.sh.tea = vaddr;
651                    cpu->cd.sh.pteh &= ~SH4_PTEH_VPN_MASK;
652                    cpu->cd.sh.pteh |= (vaddr & SH4_PTEH_VPN_MASK);
653                    break;
654    
655            case EXPEVT_TRAPA:
656                    /*  Note: The TRA register is already set by the
657                        implementation of the trapa instruction. See
658                        cpu_sh_instr.c.  */
659                    cpu->cd.sh.spc += sizeof(uint16_t);
660                    break;
661    
662            case EXPEVT_RES_INST:
663                    /*
664                     *  Note: Having this code here makes it possible to catch
665                     *  reserved instructions; during normal instruction execution,
666                     *  these are not very common.
667                     */
668    #if 1
669                    printf("\nRESERVED SuperH instruction at spc=%08"PRIx32"\n",
670                        cpu->cd.sh.spc);
671                    exit(1);
672    #else
673                    break;
674    #endif
675    
676            case EXPEVT_FPU_DISABLE:
677                    break;
678    
679            default:fatal("sh_exception(): exception 0x%x is not yet "
680                        "implemented.\n", expevt);
681                    exit(1);
682            }
683    
684            sh_pc_to_pointers(cpu);
685  }  }
686    
687    
# Line 259  int sh_cpu_disassemble_instr_compact(str Line 704  int sh_cpu_disassemble_instr_compact(str
704          else          else
705                  iword = (instr[1] << 8) + instr[0];                  iword = (instr[1] << 8) + instr[0];
706    
707          debug(":  %04x \t", iword);          debug(":  %04x %s\t", iword, cpu->delay_slot? "(d)" : "");
708          hi4 = iword >> 12; lo4 = iword & 15; lo8 = iword & 255;          hi4 = iword >> 12; lo4 = iword & 15; lo8 = iword & 255;
709          r8 = (iword >> 8) & 15; r4 = (iword >> 4) & 15;          r8 = (iword >> 8) & 15; r4 = (iword >> 4) & 15;
710    
# Line 273  int sh_cpu_disassemble_instr_compact(str Line 718  int sh_cpu_disassemble_instr_compact(str
718                          debug("stc\tsr,r%i\n", r8);                          debug("stc\tsr,r%i\n", r8);
719                  else if (lo8 == 0x03)                  else if (lo8 == 0x03)
720                          debug("bsrf\tr%i\n", r8);                          debug("bsrf\tr%i\n", r8);
721                  else if (lo4 == 0x4)                  else if (lo4 >= 4 && lo4 <= 6) {
722                          debug("mov.b\tr%i,@(r0,r%i)\n", r4, r8);                          if (lo4 == 0x4)
723                  else if (lo4 == 0x5)                                  debug("mov.b\tr%i,@(r0,r%i)", r4, r8);
724                          debug("mov.w\tr%i,@(r0,r%i)\n", r4, r8);                          else if (lo4 == 0x5)
725                  else if (lo4 == 0x6)                                  debug("mov.w\tr%i,@(r0,r%i)", r4, r8);
726                          debug("mov.l\tr%i,@(r0,r%i)\n", r4, r8);                          else if (lo4 == 0x6)
727                  else if (lo4 == 0x7)                                  debug("mov.l\tr%i,@(r0,r%i)", r4, r8);
728                            if (running) {
729                                    debug("\t; r0+r%i = 0x%08"PRIx32, r8,
730                                        cpu->cd.sh.r[0] + cpu->cd.sh.r[r8]);
731                            }
732                            debug("\n");
733                    } else if (lo4 == 0x7)
734                          debug("mul.l\tr%i,r%i\n", r4, r8);                          debug("mul.l\tr%i,r%i\n", r4, r8);
735                  else if (iword == 0x0008)                  else if (iword == 0x0008)
736                          debug("clrt\n");                          debug("clrt\n");
# Line 289  int sh_cpu_disassemble_instr_compact(str Line 740  int sh_cpu_disassemble_instr_compact(str
740                          debug("sts\tmach,r%i\n", r8);                          debug("sts\tmach,r%i\n", r8);
741                  else if (iword == 0x000b)                  else if (iword == 0x000b)
742                          debug("rts\n");                          debug("rts\n");
743                  else if (lo4 == 0xc)                  else if (lo4 >= 0xc && lo4 <= 0xe) {
744                          debug("mov.b\t@(r0,r%i),r%i\n", r4, r8);                          if (lo4 == 0xc)
745                  else if (lo4 == 0xd)                                  debug("mov.b\t@(r0,r%i),r%i", r4, r8);
746                          debug("mov.w\t@(r0,r%i),r%i\n", r4, r8);                          else if (lo4 == 0xd)
747                  else if (lo4 == 0xe)                                  debug("mov.w\t@(r0,r%i),r%i", r4, r8);
748                          debug("mov.l\t@(r0,r%i),r%i\n", r4, r8);                          else if (lo4 == 0xe)
749                  else if (lo8 == 0x12)                                  debug("mov.l\t@(r0,r%i),r%i", r4, r8);
750                            if (running) {
751                                    debug("\t; r0+r%i = 0x%08"PRIx32, r4,
752                                        cpu->cd.sh.r[0] + cpu->cd.sh.r[r4]);
753                            }
754                            debug("\n");
755                    } else if (lo8 == 0x12)
756                          debug("stc\tgbr,r%i\n", r8);                          debug("stc\tgbr,r%i\n", r8);
757                  else if (iword == 0x0018)                  else if (iword == 0x0018)
758                          debug("sett\n");                          debug("sett\n");
# Line 303  int sh_cpu_disassemble_instr_compact(str Line 760  int sh_cpu_disassemble_instr_compact(str
760                          debug("div0u\n");                          debug("div0u\n");
761                  else if (lo8 == 0x1a)                  else if (lo8 == 0x1a)
762                          debug("sts\tmacl,r%i\n", r8);                          debug("sts\tmacl,r%i\n", r8);
763                    else if (iword == 0x001b)
764                            debug("sleep\n");
765                    else if (lo8 == 0x22)
766                            debug("stc\tvbr,r%i\n", r8);
767                  else if (lo8 == 0x23)                  else if (lo8 == 0x23)
768                          debug("braf\tr%i\n", r8);                          debug("braf\tr%i\n", r8);
769                  else if (iword == 0x0028)                  else if (iword == 0x0028)
770                          debug("clrmac\n");                          debug("clrmac\n");
771                  else if (lo8 == 0x29)                  else if (lo8 == 0x29)
772                          debug("movt\tr%i\n", r8);                          debug("movt\tr%i\n", r8);
773                    else if (lo8 == 0x2a)
774                            debug("sts\tpr,r%i\n", r8);
775                    else if (iword == 0x002b)
776                            debug("rte\n");
777                    else if (lo8 == 0x32)
778                            debug("stc\tssr,r%i\n", r8);
779                    else if (iword == 0x0038)
780                            debug("ldtlb\n");
781                  else if (iword == 0x003b)                  else if (iword == 0x003b)
782                          debug("brk\n");                          debug("brk\n");
783                    else if (lo8 == 0x42)
784                            debug("stc\tspc,r%i\n", r8);
785                  else if (iword == 0x0048)                  else if (iword == 0x0048)
786                          debug("clrs\n");                          debug("clrs\n");
787                  else if (iword == 0x0058)                  else if (iword == 0x0058)
788                          debug("sets\n");                          debug("sets\n");
789                    else if (lo8 == 0x5a)
790                            debug("sts\tfpul,r%i\n", r8);
791                    else if (lo8 == 0x6a)
792                            debug("sts\tfpscr,r%i\n", r8);
793                    else if ((lo8 & 0x8f) == 0x82)
794                            debug("stc\tr%i_bank,r%i\n", (lo8 >> 4) & 7, r8);
795                  else if (lo8 == 0x83)                  else if (lo8 == 0x83)
796                          debug("pref\t@r%i\n", r8);                          debug("pref\t@r%i\n", r8);
797                    else if (lo8 == 0x93)
798                            debug("ocbi\t@r%i\n", r8);
799                    else if (lo8 == 0xa3)
800                            debug("ocbp\t@r%i\n", r8);
801                    else if (lo8 == 0xb3)
802                            debug("ocbwb\t@r%i\n", r8);
803                    else if (lo8 == 0xc3)
804                            debug("movca.l\tr0,@r%i\n", r8);
805                    else if (lo8 == 0xfa)
806                            debug("stc\tdbr,r%i\n", r8);
807                    else if (iword == SH_INVALID_INSTR)
808                            debug("gxemul_dreamcast_prom_emul\n");
809                  else                  else
810                          debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);                          debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
811                  break;                  break;
812          case 0x1:          case 0x1:
813                  debug("mov.l\tr%i,@(%i,r%i)\n", r4, lo4 * 4, r8);                  debug("mov.l\tr%i,@(%i,r%i)", r4, lo4 * 4, r8);
814                    if (running) {
815                            debug("\t; r%i+%i = 0x%08"PRIx32, r8, lo4 * 4,
816                                cpu->cd.sh.r[r8] + lo4 * 4);
817                    }
818                    debug("\n");
819                  break;                  break;
820          case 0x2:          case 0x2:
821                  if (lo4 == 0x0)                  if (lo4 == 0x0)
# Line 394  int sh_cpu_disassemble_instr_compact(str Line 888  int sh_cpu_disassemble_instr_compact(str
888                          debug("shll\tr%i\n", r8);                          debug("shll\tr%i\n", r8);
889                  else if (lo8 == 0x01)                  else if (lo8 == 0x01)
890                          debug("shlr\tr%i\n", r8);                          debug("shlr\tr%i\n", r8);
891                    else if (lo8 == 0x02)
892                            debug("sts.l\tmach,@-r%i\n", r8);
893                    else if (lo8 == 0x03)
894                            debug("stc.l\tsr,@-r%i\n", r8);
895                  else if (lo8 == 0x04)                  else if (lo8 == 0x04)
896                          debug("rotl\tr%i\n", r8);                          debug("rotl\tr%i\n", r8);
897                  else if (lo8 == 0x05)                  else if (lo8 == 0x05)
898                          debug("rotr\tr%i\n", r8);                          debug("rotr\tr%i\n", r8);
899                  else if (lo8 == 0x06)                  else if (lo8 == 0x06)
900                          debug("lds.l\t@r%i+,mach\n", r8);                          debug("lds.l\t@r%i+,mach\n", r8);
901                    else if (lo8 == 0x07)
902                            debug("ldc.l\t@r%i+,sr\n", r8);
903                  else if (lo8 == 0x08)                  else if (lo8 == 0x08)
904                          debug("shll2\tr%i\n", r8);                          debug("shll2\tr%i\n", r8);
905                  else if (lo8 == 0x09)                  else if (lo8 == 0x09)
# Line 418  int sh_cpu_disassemble_instr_compact(str Line 918  int sh_cpu_disassemble_instr_compact(str
918                          debug("dt\tr%i\n", r8);                          debug("dt\tr%i\n", r8);
919                  else if (lo8 == 0x11)                  else if (lo8 == 0x11)
920                          debug("cmp/pz\tr%i\n", r8);                          debug("cmp/pz\tr%i\n", r8);
921                    else if (lo8 == 0x12)
922                            debug("sts.l\tmacl,@-r%i\n", r8);
923                    else if (lo8 == 0x13)
924                            debug("stc.l\tgbr,@-r%i\n", r8);
925                  else if (lo8 == 0x15)                  else if (lo8 == 0x15)
926                          debug("cmp/pl\tr%i\n", r8);                          debug("cmp/pl\tr%i\n", r8);
927                  else if (lo8 == 0x16)                  else if (lo8 == 0x16)
928                          debug("lds.l\t@r%i+,macl\n", r8);                          debug("lds.l\t@r%i+,macl\n", r8);
929                    else if (lo8 == 0x17)
930                            debug("ldc.l\t@r%i+,gbr\n", r8);
931                  else if (lo8 == 0x18)                  else if (lo8 == 0x18)
932                          debug("shll8\tr%i\n", r8);                          debug("shll8\tr%i\n", r8);
933                  else if (lo8 == 0x19)                  else if (lo8 == 0x19)
# Line 438  int sh_cpu_disassemble_instr_compact(str Line 944  int sh_cpu_disassemble_instr_compact(str
944                          debug("shar\tr%i\n", r8);                          debug("shar\tr%i\n", r8);
945                  else if (lo8 == 0x22)                  else if (lo8 == 0x22)
946                          debug("sts.l\tpr,@-r%i\n", r8);                          debug("sts.l\tpr,@-r%i\n", r8);
947                    else if (lo8 == 0x23)
948                            debug("stc.l\tvbr,@-r%i\n", r8);
949                  else if (lo8 == 0x24)                  else if (lo8 == 0x24)
950                          debug("rotcl\tr%i\n", r8);                          debug("rotcl\tr%i\n", r8);
951                  else if (lo8 == 0x25)                  else if (lo8 == 0x25)
952                          debug("rotcr\tr%i\n", r8);                          debug("rotcr\tr%i\n", r8);
953                  else if (lo8 == 0x26)                  else if (lo8 == 0x26)
954                          debug("lds.l\t@r%i+,pr\n", r8);                          debug("lds.l\t@r%i+,pr\n", r8);
955                    else if (lo8 == 0x27)
956                            debug("ldc.l\t@r%i+,vbr\n", r8);
957                  else if (lo8 == 0x28)                  else if (lo8 == 0x28)
958                          debug("shll16\tr%i\n", r8);                          debug("shll16\tr%i\n", r8);
959                  else if (lo8 == 0x29)                  else if (lo8 == 0x29)
# Line 452  int sh_cpu_disassemble_instr_compact(str Line 962  int sh_cpu_disassemble_instr_compact(str
962                          debug("lds\tr%i,pr\n", r8);                          debug("lds\tr%i,pr\n", r8);
963                  else if (lo8 == 0x2b)                  else if (lo8 == 0x2b)
964                          debug("jmp\t@r%i\n", r8);                          debug("jmp\t@r%i\n", r8);
965                    else if (lo8 == 0x2e)
966                            debug("ldc\tr%i,vbr\n", r8);
967                    else if (lo8 == 0x33)
968                            debug("stc.l\tssr,@-r%i\n", r8);
969                    else if (lo8 == 0x37)
970                            debug("ldc.l\t@r%i+,ssr\n", r8);
971                    else if (lo8 == 0x3e)
972                            debug("ldc\tr%i,ssr\n", r8);
973                    else if (lo8 == 0x43)
974                            debug("stc.l\tspc,@-r%i\n", r8);
975                    else if (lo8 == 0x47)
976                            debug("ldc.l\t@r%i+,spc\n", r8);
977                    else if (lo8 == 0x4e)
978                            debug("ldc\tr%i,spc\n", r8);
979                    else if (lo8 == 0x52)
980                            debug("sts.l\tfpul,@-r%i\n", r8);
981                  else if (lo8 == 0x56)                  else if (lo8 == 0x56)
982                          debug("lds.l\t@r%i+,fpul\n", r8);                          debug("lds.l\t@r%i+,fpul\n", r8);
983                  else if (lo8 == 0x5a)                  else if (lo8 == 0x5a)
984                          debug("lds\tr%i,fpul\n", r8);                          debug("lds\tr%i,fpul\n", r8);
985                    else if (lo8 == 0x62)
986                            debug("sts.l\tfpscr,@-r%i\n", r8);
987                    else if (lo8 == 0x66)
988                            debug("lds.l\t@r%i+,fpscr\n", r8);
989                  else if (lo8 == 0x6a)                  else if (lo8 == 0x6a)
990                          debug("lds\tr%i,fpscr\n", r8);                          debug("lds\tr%i,fpscr\n", r8);
991                    else if ((lo8 & 0x8f) == 0x83)
992                            debug("stc.l\tr%i_bank,@-r%i\n", (lo8 >> 4) & 7, r8);
993                    else if ((lo8 & 0x8f) == 0x87)
994                            debug("ldc.l\t@r%i,r%i_bank\n", r8, (lo8 >> 4) & 7, r8);
995                    else if ((lo8 & 0x8f) == 0x8e)
996                            debug("ldc\tr%i,r%i_bank\n", r8, (lo8 >> 4) & 7);
997                    else if (lo8 == 0xfa)
998                            debug("ldc\tr%i,dbr\n", r8);
999                  else                  else
1000                          debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);                          debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
1001                  break;                  break;
1002          case 0x5:          case 0x5:
1003                  debug("mov.l\t@(%i,r%i),r%i\n", lo4 * 4, r4, r8);                  debug("mov.l\t@(%i,r%i),r%i", lo4 * 4, r4, r8);
1004                    if (running) {
1005                            debug("\t; r%i+%i = 0x%08"PRIx32, r4, lo4 * 4,
1006                                cpu->cd.sh.r[r4] + lo4 * 4);
1007                    }
1008                    debug("\n");
1009                  break;                  break;
1010          case 0x6:          case 0x6:
1011                  if (lo4 == 0x0)                  if (lo4 == 0x0)
# Line 475  int sh_cpu_disassemble_instr_compact(str Line 1018  int sh_cpu_disassemble_instr_compact(str
1018                          debug("mov\tr%i,r%i\n", r4, r8);                          debug("mov\tr%i,r%i\n", r4, r8);
1019                  else if (lo4 == 0x4)                  else if (lo4 == 0x4)
1020                          debug("mov.b\t@r%i+,r%i\n", r4, r8);                          debug("mov.b\t@r%i+,r%i\n", r4, r8);
1021                    else if (lo4 == 0x5)
1022                            debug("mov.w\t@r%i+,r%i\n", r4, r8);
1023                  else if (lo4 == 0x6)                  else if (lo4 == 0x6)
1024                          debug("mov.l\t@r%i+,r%i\n", r4, r8);                          debug("mov.l\t@r%i+,r%i\n", r4, r8);
1025                  else if (lo4 == 0x7)                  else if (lo4 == 0x7)
# Line 502  int sh_cpu_disassemble_instr_compact(str Line 1047  int sh_cpu_disassemble_instr_compact(str
1047                  debug("add\t#%i,r%i\n", (int8_t)lo8, r8);                  debug("add\t#%i,r%i\n", (int8_t)lo8, r8);
1048                  break;                  break;
1049          case 0x8:          case 0x8:
1050                  if (r8 == 0x8)                  if (r8 == 0 || r8 == 4) {
1051                            if (r8 == 0x0)
1052                                    debug("mov.b\tr0,@(%i,r%i)", lo4, r4);
1053                            else if (r8 == 0x4)
1054                                    debug("mov.b\t@(%i,r%i),r0", lo4, r4);
1055                            if (running) {
1056                                    debug("\t; r%i+%i = 0x%08"PRIx32, r4, lo4,
1057                                        cpu->cd.sh.r[r4] + lo4);
1058                            }
1059                            debug("\n");
1060                    } else if (r8 == 1 || r8 == 5) {
1061                            if (r8 == 0x1)
1062                                    debug("mov.w\tr0,@(%i,r%i)", lo4 * 2, r4);
1063                            else if (r8 == 0x5)
1064                                    debug("mov.w\t@(%i,r%i),r0", lo4 * 2, r4);
1065                            if (running) {
1066                                    debug("\t; r%i+%i = 0x%08"PRIx32, r4, lo4 * 2,
1067                                        cpu->cd.sh.r[r4] + lo4 * 2);
1068                            }
1069                            debug("\n");
1070                    } else if (r8 == 0x8) {
1071                          debug("cmp/eq\t#%i,r0\n", (int8_t)lo8);                          debug("cmp/eq\t#%i,r0\n", (int8_t)lo8);
1072                  else if (r8 == 0x9 || r8 == 0xb || r8 == 0xd || r8 == 0xf) {                  } else if (r8 == 0x9 || r8 == 0xb || r8 == 0xd || r8 == 0xf) {
1073                          addr = (int8_t)lo8;                          addr = (int8_t)lo8;
1074                          addr = dumpaddr + 4 + (addr << 1);                          addr = dumpaddr + 4 + (addr << 1);
1075                          debug("b%s%s\t0x%x\n",                          debug("b%s%s\t0x%x\n",
# Line 515  int sh_cpu_disassemble_instr_compact(str Line 1080  int sh_cpu_disassemble_instr_compact(str
1080                  break;                  break;
1081          case 0x9:          case 0x9:
1082          case 0xd:          case 0xd:
1083                  addr = ((int8_t)lo8) * (hi4==9? 2 : 4);                  addr = lo8 * (hi4==9? 2 : 4);
1084                  addr += (dumpaddr & ~(hi4==9? 1 : 3)) + 4;                  addr += (dumpaddr & ~(hi4==9? 1 : 3)) + 4;
1085                  debug("mov.%s\t0x%x,r%i\n", hi4==9? "w":"l", (int)addr, r8);                  debug("mov.%s\t0x%x,r%i\n", hi4==9? "w":"l", (int)addr, r8);
1086                  break;                  break;
# Line 527  int sh_cpu_disassemble_instr_compact(str Line 1092  int sh_cpu_disassemble_instr_compact(str
1092                  debug("%s\t0x%x\n", hi4==0xa? "bra":"bsr", (int)addr);                  debug("%s\t0x%x\n", hi4==0xa? "bra":"bsr", (int)addr);
1093                  break;                  break;
1094          case 0xc:          case 0xc:
1095                  if (r8 == 0x3)                  if (r8 == 0x0)
1096                            debug("mov.b\tr0,@(%i,gbr)\n", lo8);
1097                    else if (r8 == 0x1)
1098                            debug("mov.w\tr0,@(%i,gbr)\n", lo8 * 2);
1099                    else if (r8 == 0x2)
1100                            debug("mov.l\tr0,@(%i,gbr)\n", lo8 * 4);
1101                    else if (r8 == 0x3)
1102                          debug("trapa\t#%i\n", (uint8_t)lo8);                          debug("trapa\t#%i\n", (uint8_t)lo8);
1103                  else if (r8 == 0x8)                  else if (r8 == 0x4)
1104                            debug("mov.b\t(%i,gbr),r0\n", lo8);
1105                    else if (r8 == 0x5)
1106                            debug("mov.w\t(%i,gbr),r0\n", lo8 * 2);
1107                    else if (r8 == 0x6)
1108                            debug("mov.l\t(%i,gbr),r0\n", lo8 * 4);
1109                    else if (r8 == 0x7) {
1110                            addr = lo8 * 4 + (dumpaddr & ~3) + 4;
1111                            debug("mova\t0x%x,r0\n", (int)addr);
1112                    } else if (r8 == 0x8)
1113                          debug("tst\t#%i,r0\n", (uint8_t)lo8);                          debug("tst\t#%i,r0\n", (uint8_t)lo8);
1114                  else if (r8 == 0x9)                  else if (r8 == 0x9)
1115                          debug("and\t#%i,r0\n", (uint8_t)lo8);                          debug("and\t#%i,r0\n", (uint8_t)lo8);
# Line 551  int sh_cpu_disassemble_instr_compact(str Line 1131  int sh_cpu_disassemble_instr_compact(str
1131          case 0xe:          case 0xe:
1132                  debug("mov\t#%i,r%i\n", (int8_t)lo8, r8);                  debug("mov\t#%i,r%i\n", (int8_t)lo8, r8);
1133                  break;                  break;
1134            case 0xf:
1135                    if (lo4 == 0x0)
1136                            debug("fadd\t%sr%i,%sr%i\n",
1137                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1138                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1139                    else if (lo4 == 0x1)
1140                            debug("fsub\t%sr%i,%sr%i\n",
1141                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1142                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1143                    else if (lo4 == 0x2)
1144                            debug("fmul\t%sr%i,%sr%i\n",
1145                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1146                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1147                    else if (lo4 == 0x3)
1148                            debug("fdiv\t%sr%i,%sr%i\n",
1149                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1150                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1151                    else if (lo4 == 0x4)
1152                            debug("fcmp/eq\t%sr%i,%sr%i\n",
1153                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1154                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1155                    else if (lo4 == 0x5)
1156                            debug("fcmp/gt\t%sr%i,%sr%i\n",
1157                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1158                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1159                    else if (lo4 == 0x6) {
1160                            char *n = "fr";
1161                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1162                                    n = (r8 & 1)? "xd" : "dr";
1163                                    r8 &= ~1;
1164                            }
1165                            debug("fmov\t@(r0,r%i),%s%i\n", r4, n, r8);
1166                    } else if (lo4 == 0x7) {
1167                            char *n = "fr";
1168                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1169                                    n = (r4 & 1)? "xd" : "dr";
1170                                    r4 &= ~1;
1171                            }
1172                            debug("fmov\t%s%i,@(r0,r%i)\n", n, r4, r8);
1173                    } else if (lo4 == 0x8) {
1174                            char *n = "fr";
1175                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1176                                    n = (r8 & 1)? "xd" : "dr";
1177                                    r8 &= ~1;
1178                            }
1179                            debug("fmov\t@r%i,%s%i\n", r4, n, r8);
1180                    } else if (lo4 == 0x9) {
1181                            char *n = "fr";
1182                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1183                                    n = (r8 & 1)? "xd" : "dr";
1184                                    r8 &= ~1;
1185                            }
1186                            debug("fmov\t@r%i+,%s%i\n", r4, n, r8);
1187                    } else if (lo4 == 0xa) {
1188                            char *n = "fr";
1189                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1190                                    n = (r4 & 1)? "xd" : "dr";
1191                                    r4 &= ~1;
1192                            }
1193                            debug("fmov\t%s%i,@r%i\n", n, r4, r8);
1194                    } else if (lo4 == 0xb) {
1195                            char *n = "fr";
1196                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1197                                    n = (r4 & 1)? "xd" : "dr";
1198                                    r4 &= ~1;
1199                            }
1200                            debug("fmov\t%s%i,@-r%i\n", n, r4, r8);
1201                    } else if (lo4 == 0xc) {
1202                            char *n1 = "fr", *n2 = "fr";
1203                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1204                                    n1 = (r4 & 1)? "xd" : "dr";
1205                                    n2 = (r8 & 1)? "xd" : "dr";
1206                                    r4 &= ~1; r8 &= ~1;
1207                            }
1208                            debug("fmov\t%s%i,%s%i\n", n1, r4, n2, r8);
1209                    } else if (lo8 == 0x0d)
1210                            debug("fsts\tfpul,fr%i\n", r8);
1211                    else if (lo8 == 0x1d)
1212                            debug("flds\tfr%i,fpul\n", r8);
1213                    else if (lo8 == 0x2d)
1214                            debug("float\tfpul,%sr%i\n",
1215                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1216                    else if (lo8 == 0x3d)
1217                            debug("ftrc\t%sr%i,fpul\n",
1218                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1219                    else if (lo8 == 0x4d)
1220                            debug("fneg\t%sr%i\n",
1221                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1222                    else if (lo8 == 0x5d)
1223                            debug("fabs\t%sr%i\n",
1224                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1225                    else if (lo8 == 0x6d)
1226                            debug("fsqrt\t%sr%i\n",
1227                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1228                    else if (lo8 == 0x8d)
1229                            debug("fldi0\tfr%i\n", r8);
1230                    else if (lo8 == 0x9d)
1231                            debug("fldi1\tfr%i\n", r8);
1232                    else if ((iword & 0x01ff) == 0x00fd)
1233                            debug("fsca\tfpul,dr%i\n", r8);
1234                    else if (iword == 0xf3fd)
1235                            debug("fschg\n");
1236                    else if (iword == 0xfbfd)
1237                            debug("frchg\n");
1238                    else if ((iword & 0xf3ff) == 0xf1fd)
1239                            debug("ftrv\txmtrx,fv%i\n", r8 & 0xc);
1240                    else if (lo4 == 0xe)
1241                            debug("fmac\tfr0,fr%i,fr%i\n", r4, r8);
1242                    else
1243                            debug("UNIMPLEMENTED hi4=0x%x,0x%x\n", hi4, lo8);
1244                    break;
1245          default:debug("UNIMPLEMENTED hi4=0x%x\n", hi4);          default:debug("UNIMPLEMENTED hi4=0x%x\n", hi4);
1246          }          }
1247    
# Line 588  int sh_cpu_disassemble_instr(struct cpu Line 1279  int sh_cpu_disassemble_instr(struct cpu
1279          if (cpu->machine->ncpus > 1 && running)          if (cpu->machine->ncpus > 1 && running)
1280                  debug("cpu%i: ", cpu->cpu_id);                  debug("cpu%i: ", cpu->cpu_id);
1281    
1282          if (cpu->cd.sh.bits == 32)          if (cpu->cd.sh.cpu_type.bits == 32)
1283                  debug("%08x", (int)dumpaddr);                  debug("%08x", (int)dumpaddr);
1284          else          else
1285                  debug("%016llx", (long long)dumpaddr);                  debug("%016llx", (long long)dumpaddr);

Legend:
Removed from v.28  
changed lines
  Added in v.36

  ViewVC Help
Powered by ViewVC 1.1.26