/[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 26 by dpavlin, Mon Oct 8 16:20:10 2007 UTC revision 40 by dpavlin, Mon Oct 8 16:22:11 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.16 2006/06/24 21:47:23 debug Exp $   *  $Id: cpu_sh.c,v 1.72 2007/04/28 09:44:35 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->update_translation_table = sh32_update_translation_table;                  exit(1);
                 cpu->invalidate_translation_caches =  
                     sh32_invalidate_translation_caches;  
                 cpu->invalidate_code_translation =  
                     sh32_invalidate_code_translation;  
         } else {  
                 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                    cpu->cd.sh.pcic_pcibus = device_add(machine, "sh4");
190    
191                    /*
192                     *  Interrupt Controller initial values, according to the
193                     *  SH7760 manual:
194                     */
195                    cpu->cd.sh.intc_iprd = 0xda74;
196                    cpu->cd.sh.intc_intmsk00 = 0xf3ff7fff;
197                    cpu->cd.sh.intc_intmsk04 = 0x00ffffff;
198                    /*  All others are zero.  */
199    
200                    /*  TODO: Initial priorities?  */
201                    cpu->cd.sh.intc_intpri00 = 0x33333333;
202                    cpu->cd.sh.intc_intpri04 = 0x33333333;
203                    cpu->cd.sh.intc_intpri08 = 0x33333333;
204                    cpu->cd.sh.intc_intpri0c = 0x33333333;
205            }
206    
207            sh_update_interrupt_priorities(cpu);
208    
209          return 1;          return 1;
210  }  }
211    
212    
213  /*  /*
214     *  sh_update_interrupt_priorities():
215     *
216     *  SH interrupts are a bit complicated; there are several intc registers
217     *  controlling priorities for various peripherals:
218     *
219     *  Register:  Bits 15..12  11..8  7..4      3..0
220     *  ---------  -----------  -----  ----      ----
221     *  ipra       TMU0         TMU1   TMU2      Reserved
222     *  iprb       WDT          REF    Reserved  Reserved
223     *  iprc       GPIO         DMAC   Reserved  H-UDI
224     *  iprd       IRL0         IRL1   IRL2      IRL3
225     *
226     *  Register:  31..28  27..24  23..20  19..16  15..12  11..8   7..4   3..0
227     *  ---------  ------  ------  ------  ------  ------  -----   ----   ----
228     *  intpri00   IRQ4    IRQ5    IRQ6    IRQ7    Rsrvd.  Rsrvd.  Rsrvd. Reserved
229     *  intpri04   HCAN2,0 HCAN2,1 SSI(0)  SSI(1)  HAC(0)  HAC(1)  I2C(0) I2C(1)
230     *  intpri08   USB     LCDC    DMABRG  SCIF(0) SCIF(1) SCIF(2) SIM    HSPI
231     *  intpri0c   Reserv. Reserv. MMCIF   Reserv. MFI     Rsrvd.  ADC    CMT
232     */
233    void sh_update_interrupt_priorities(struct cpu *cpu)
234    {
235            int i;
236    
237            /*
238             *  Set priorities of known interrupts, without affecting the
239             *  SH_INT_ASSERTED bit:
240             */
241    
242            for (i=SH4_INTEVT_IRQ0; i<=SH4_INTEVT_IRQ14; i+=0x20) {
243                    cpu->cd.sh.int_prio_and_pending[i/0x20] &= ~SH_INT_PRIO_MASK;
244                    cpu->cd.sh.int_prio_and_pending[i/0x20] |= (15 - ((i -
245                        SH4_INTEVT_IRQ0) / 0x20));
246            }
247    
248            cpu->cd.sh.int_prio_and_pending[SH_INTEVT_TMU0_TUNI0 / 0x20] &=
249                ~SH_INT_PRIO_MASK;
250            cpu->cd.sh.int_prio_and_pending[SH_INTEVT_TMU0_TUNI0 / 0x20] |=
251                (cpu->cd.sh.intc_ipra >> 12) & 0xf;
252    
253            cpu->cd.sh.int_prio_and_pending[SH_INTEVT_TMU1_TUNI1 / 0x20] &=
254                ~SH_INT_PRIO_MASK;
255            cpu->cd.sh.int_prio_and_pending[SH_INTEVT_TMU1_TUNI1 / 0x20] |=
256                (cpu->cd.sh.intc_ipra >> 8) & 0xf;
257    
258            cpu->cd.sh.int_prio_and_pending[SH_INTEVT_TMU2_TUNI2 / 0x20] &=
259                ~SH_INT_PRIO_MASK;
260            cpu->cd.sh.int_prio_and_pending[SH_INTEVT_TMU2_TUNI2 / 0x20] |=
261                (cpu->cd.sh.intc_ipra >> 4) & 0xf;
262    
263            for (i=SH4_INTEVT_SCIF_ERI; i<=SH4_INTEVT_SCIF_TXI; i+=0x20) {
264                    cpu->cd.sh.int_prio_and_pending[i/0x20] &= ~SH_INT_PRIO_MASK;
265                    cpu->cd.sh.int_prio_and_pending[i/0x20] |=
266                        ((cpu->cd.sh.intc_intpri08 >> 16) & 0xf);
267            }
268    }
269    
270    
271    /*
272     *  sh_cpu_interrupt_assert():
273     */
274    void sh_cpu_interrupt_assert(struct interrupt *interrupt)
275    {
276            struct cpu *cpu = interrupt->extra;
277            unsigned int irq_nr = interrupt->line;
278            unsigned int index = irq_nr / 0x20;
279            unsigned int prio;
280    
281            /*  Assert the interrupt, and check its priority level:  */
282            cpu->cd.sh.int_prio_and_pending[index] |= SH_INT_ASSERTED;
283            prio = cpu->cd.sh.int_prio_and_pending[index] & SH_INT_PRIO_MASK;
284    
285            if (prio == 0) {
286                    /*  Interrupt not implemented? Hm.  */
287                    fatal("[ SH interrupt 0x%x, prio 0 (?), aborting ]\n", irq_nr);
288                    exit(1);
289            }
290    
291            if (cpu->cd.sh.int_to_assert == 0 || prio > cpu->cd.sh.int_level) {
292                    cpu->cd.sh.int_to_assert = irq_nr;
293                    cpu->cd.sh.int_level = prio;
294            }
295    }
296    
297    
298    /*
299     *  sh_cpu_interrupt_deassert():
300     */
301    void sh_cpu_interrupt_deassert(struct interrupt *interrupt)
302    {
303            struct cpu *cpu = interrupt->extra;
304            int irq_nr = interrupt->line;
305            int index = irq_nr / 0x20;
306    
307            /*  Deassert the interrupt:  */
308            if (cpu->cd.sh.int_prio_and_pending[index] & SH_INT_ASSERTED) {
309                    cpu->cd.sh.int_prio_and_pending[index] &= ~SH_INT_ASSERTED;
310    
311                    /*  Calculate new interrupt assertion:  */
312                    cpu->cd.sh.int_to_assert = 0;
313                    cpu->cd.sh.int_level = 0;
314    
315                    /*  NOTE/TODO: This is slow, but should hopefully work:  */
316                    for (index=0; index<0x1000/0x20; index++) {
317                            uint8_t x = cpu->cd.sh.int_prio_and_pending[index];
318                            uint8_t prio = x & SH_INT_PRIO_MASK;
319                            if (x & SH_INT_ASSERTED &&
320                                prio > cpu->cd.sh.int_level) {
321                                    cpu->cd.sh.int_to_assert = index * 0x20;
322                                    cpu->cd.sh.int_level = prio;
323                            }
324                    }
325            }
326    }
327    
328    
329    /*
330   *  sh_cpu_list_available_types():   *  sh_cpu_list_available_types():
331   *   *
332   *  Print a list of available SH CPU types.   *  Print a list of available SH CPU types.
333   */   */
334  void sh_cpu_list_available_types(void)  void sh_cpu_list_available_types(void)
335  {  {
336          debug("SH\n");          int i = 0, j;
337          /*  TODO  */          struct sh_cpu_type_def tdefs[] = SH_CPU_TYPE_DEFS;
338    
339            while (tdefs[i].name != NULL) {
340                    debug("%s", tdefs[i].name);
341                    for (j=10 - strlen(tdefs[i].name); j>0; j--)
342                            debug(" ");
343                    i ++;
344                    if ((i % 6) == 0 || tdefs[i].name == NULL)
345                            debug("\n");
346            }
347  }  }
348    
349    
# Line 110  void sh_cpu_list_available_types(void) Line 352  void sh_cpu_list_available_types(void)
352   */   */
353  void sh_cpu_dumpinfo(struct cpu *cpu)  void sh_cpu_dumpinfo(struct cpu *cpu)
354  {  {
355          debug("\n");          debug(" (%s-endian)\n",
356          /*  TODO  */              cpu->byte_order == EMUL_BIG_ENDIAN? "Big" : "Little");
357    }
358    
359    
360    /*
361     *  sh_cpu_instruction_has_delayslot():
362     *
363     *  Return 1 if an opcode is a branch, 0 otherwise.
364     */
365    int sh_cpu_instruction_has_delayslot(struct cpu *cpu, unsigned char *ib)
366    {
367            uint16_t iword = *((uint16_t *)&ib[0]);
368            int hi4, lo4, lo8;
369    
370            if (!cpu->is_32bit)
371                    return 0;
372    
373            if (cpu->byte_order == EMUL_BIG_ENDIAN)
374                    iword = BE16_TO_HOST(iword);
375            else
376                    iword = LE16_TO_HOST(iword);
377    
378            hi4 = iword >> 12; lo4 = iword & 15; lo8 = iword & 255;
379    
380            switch (hi4) {
381            case 0x0:
382                    if (iword == 0x000b)    /*  rts  */
383                            return 1;
384                    if (iword == 0x002b)    /*  rte  */
385                            return 1;
386                    if (lo8 == 0x03)        /*  bsrf  */
387                            return 1;
388                    if (lo8 == 0x23)        /*  braf  */
389                            return 1;
390                    break;
391            case 0x4:
392                    switch (lo8) {
393                    case 0x0b:      /*  jsr  */
394                    case 0x2b:      /*  jmp  */
395                            return 1;
396                    }
397                    break;
398            case 0x8:
399                    switch ((iword >> 8) & 0xf) {
400                    case 0xd:       /*  bt/s  */
401                    case 0xf:       /*  bf/s  */
402                            return 1;
403                    }
404                    break;
405            case 0xa:       /*  bra  */
406            case 0xb:       /*  bsr  */
407                    return 1;
408            }
409    
410            return 0;
411  }  }
412    
413    
# Line 128  void sh_cpu_register_dump(struct cpu *cp Line 424  void sh_cpu_register_dump(struct cpu *cp
424          char *symbol;          char *symbol;
425          uint64_t offset;          uint64_t offset;
426          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;  
427    
428          if (gprs) {          if (gprs) {
429                  /*  Special registers (pc, ...) first:  */                  /*  Special registers (pc, ...) first:  */
430                  symbol = get_symbol_name(&cpu->machine->symbol_context,                  symbol = get_symbol_name(&cpu->machine->symbol_context,
431                      cpu->pc, &offset);                      cpu->pc, &offset);
432    
433                  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);  
434                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");
435    
436                  if (bits32) {                  debug("cpu%i: sr  = 0x%08"PRIx32"  (%s, %s, %s, %s, %s, %s,"
437                          /*  32-bit:  */                      " imask=0x%x, %s, %s)\n", x, (int32_t)cpu->cd.sh.sr,
438                          for (i=0; i<nregs; i++) {                      (cpu->cd.sh.sr & SH_SR_MD)? "MD" : "!md",
439                                  if ((i % 4) == 0)                      (cpu->cd.sh.sr & SH_SR_RB)? "RB" : "!rb",
440                                          debug("cpu%i:", x);                      (cpu->cd.sh.sr & SH_SR_BL)? "BL" : "!bl",
441                                  debug(" r%02i = 0x%08x ", i,                      (cpu->cd.sh.sr & SH_SR_FD)? "FD" : "!fd",
442                                      (int)cpu->cd.sh.r[i]);                      (cpu->cd.sh.sr & SH_SR_M)? "M" : "!m",
443                                  if ((i % 4) == 3)                      (cpu->cd.sh.sr & SH_SR_Q)? "Q" : "!q",
444                                          debug("\n");                      (cpu->cd.sh.sr & SH_SR_IMASK) >> SH_SR_IMASK_SHIFT,
445                          }                      (cpu->cd.sh.sr & SH_SR_S)? "S" : "!s",
446                  } 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");  
                         }  
                 }  
         }  
 }  
447    
448                    symbol = get_symbol_name(&cpu->machine->symbol_context,
449                        cpu->cd.sh.pr, &offset);
450                    debug("cpu%i: pr  = 0x%08"PRIx32, x, (uint32_t)cpu->cd.sh.pr);
451                    debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");
452    
453  /*                  debug("cpu%i: mach = 0x%08"PRIx32"  macl = 0x%08"PRIx32
454   *  sh_cpu_register_match():                      "  gbr = 0x%08"PRIx32"\n", x, (uint32_t)cpu->cd.sh.mach,
455   */                      (uint32_t)cpu->cd.sh.macl, (uint32_t)cpu->cd.sh.gbr);
456  void sh_cpu_register_match(struct machine *m, char *name,  
457          int writeflag, uint64_t *valuep, int *match_register)                  for (i=0; i<nregs; i++) {
458  {                          if ((i % 4) == 0)
459          int cpunr = 0;                                  debug("cpu%i:", x);
460                            debug(" r%-2i = 0x%08x ", i, (int)cpu->cd.sh.r[i]);
461                            if ((i % 4) == 3)
462                                    debug("\n");
463                    }
464            }
465    
466          /*  CPU number:  */          if (coprocs & 1) {
467                    /*  Floating point:  */
468                    debug("cpu%i: fpscr = 0x%08"PRIx32" (%s,%s,%s)  fpul = 0x%08"
469                        PRIx32"\n", x, cpu->cd.sh.fpscr,
470                        cpu->cd.sh.fpscr & SH_FPSCR_PR? "PR" : "!pr",
471                        cpu->cd.sh.fpscr & SH_FPSCR_SZ? "SZ" : "!sz",
472                        cpu->cd.sh.fpscr & SH_FPSCR_FR? "FR" : "!fr",
473                        cpu->cd.sh.fpul);
474    
475                    for (i=0; i<SH_N_FPRS; i++) {
476                            if ((i % 4) == 0)
477                                    debug("cpu%i:", x);
478                            debug(" fr%-2i=0x%08x ", i, (int)cpu->cd.sh.fr[i]);
479                            if ((i % 4) == 3)
480                                    debug("\n");
481                    }
482    
483          /*  TODO  */                  for (i=0; i<SH_N_FPRS; i++) {
484                            if ((i % 4) == 0)
485                                    debug("cpu%i:", x);
486                            debug(" xf%-2i=0x%08x ", i, (int)cpu->cd.sh.xf[i]);
487                            if ((i % 4) == 3)
488                                    debug("\n");
489                    }
490            }
491    
492          /*  Register name:  */          if (coprocs & 2) {
493          if (strcasecmp(name, "pc") == 0) {                  /*  System registers, etc:  */
494                  if (writeflag) {                  debug("cpu%i: vbr = 0x%08"PRIx32"  sgr = 0x%08"PRIx32
495                          m->cpus[cpunr]->pc = *valuep;                      "\n", x, cpu->cd.sh.vbr, cpu->cd.sh.sgr);
496                  } else                  debug("cpu%i: spc = 0x%08"PRIx32"  ssr = 0x%08"PRIx32"\n",
497                          *valuep = m->cpus[cpunr]->pc;                      x, cpu->cd.sh.spc, cpu->cd.sh.ssr);
498                  *match_register = 1;                  debug("cpu%i: expevt = 0x%"PRIx32"  intevt = 0x%"PRIx32
499                        "  tra = 0x%"PRIx32"\n", x, cpu->cd.sh.expevt,
500                        cpu->cd.sh.intevt, cpu->cd.sh.tra);
501    
502                    for (i=0; i<SH_N_GPRS_BANKED; i++) {
503                            if ((i % 2) == 0)
504                                    debug("cpu%i:", x);
505                            debug(" r%i_bank = 0x%08x ", i,
506                                (int)cpu->cd.sh.r_bank[i]);
507                            if ((i % 2) == 1)
508                                    debug("\n");
509                    }
510          }          }
511  }  }
512    
# Line 202  void sh_cpu_register_match(struct machin Line 522  void sh_cpu_register_match(struct machin
522   */   */
523  void sh_cpu_tlbdump(struct machine *m, int x, int rawflag)  void sh_cpu_tlbdump(struct machine *m, int x, int rawflag)
524  {  {
525            int i, j;
526    
527            for (j=0; j<m->ncpus; j++) {
528                    struct cpu *cpu = m->cpus[j];
529    
530                    if (x >= 0 && j != x)
531                            continue;
532    
533                    for (i=0; i<SH_N_ITLB_ENTRIES; i++)
534                            printf("cpu%i: itlb_hi_%-2i = 0x%08"PRIx32"  "
535                                "itlb_lo_%-2i = 0x%08"PRIx32"\n", j, i,
536                                (uint32_t) cpu->cd.sh.itlb_hi[i], i,
537                                (uint32_t) cpu->cd.sh.itlb_lo[i]);
538                    for (i=0; i<SH_N_UTLB_ENTRIES; i++)
539                            printf("cpu%i: utlb_hi_%-2i = 0x%08"PRIx32"  "
540                                "utlb_lo_%-2i = 0x%08"PRIx32"\n", j, i,
541                                (uint32_t) cpu->cd.sh.utlb_hi[i], i,
542                                (uint32_t) cpu->cd.sh.utlb_lo[i]);
543            }
544  }  }
545    
546    
547  /*  /*
548   *  sh_cpu_gdb_stub():   *  sh_update_sr():
549   *   *
550   *  Execute a "remote GDB" command. Returns a newly allocated response string   *  Writes a new value to the status register.
  *  on success, NULL on failure.  
551   */   */
552  char *sh_cpu_gdb_stub(struct cpu *cpu, char *cmd)  void sh_update_sr(struct cpu *cpu, uint32_t new_sr)
553  {  {
554          fatal("sh_cpu_gdb_stub(): TODO\n");          uint32_t old_sr = cpu->cd.sh.sr;
555          return NULL;  
556            if ((new_sr & SH_SR_RB) != (old_sr & SH_SR_RB)) {
557                    int i;
558                    for (i=0; i<SH_N_GPRS_BANKED; i++) {
559                            uint32_t tmp = cpu->cd.sh.r[i];
560                            cpu->cd.sh.r[i] = cpu->cd.sh.r_bank[i];
561                            cpu->cd.sh.r_bank[i] = tmp;
562                    }
563            }
564    
565            cpu->cd.sh.sr = new_sr;
566  }  }
567    
568    
569  /*  /*
570   *  sh_cpu_interrupt():   *  sh_update_fpscr():
571     *
572     *  Writes a new value to the floating-point status/control register.
573   */   */
574  int sh_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)  void sh_update_fpscr(struct cpu *cpu, uint32_t new_fpscr)
575  {  {
576          fatal("sh_cpu_interrupt(): TODO\n");          uint32_t old_fpscr = cpu->cd.sh.fpscr;
577          return 0;  
578            if ((new_fpscr & SH_FPSCR_FR) != (old_fpscr & SH_FPSCR_FR)) {
579                    int i;
580                    for (i=0; i<SH_N_FPRS; i++) {
581                            uint32_t tmp = cpu->cd.sh.fr[i];
582                            cpu->cd.sh.fr[i] = cpu->cd.sh.xf[i];
583                            cpu->cd.sh.xf[i] = tmp;
584                    }
585            }
586    
587            cpu->cd.sh.fpscr = new_fpscr;
588  }  }
589    
590    
591  /*  /*
592   *  sh_cpu_interrupt_ack():   *  sh_exception():
593     *
594     *  Causes a transfer of control to an exception or interrupt handler.
595     *  If intevt > 0, then it is an interrupt, otherwise an exception.
596     *
597     *  vaddr contains the faulting address, on TLB exceptions.
598   */   */
599  int sh_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)  void sh_exception(struct cpu *cpu, int expevt, int intevt, uint32_t vaddr)
600  {  {
601          /*  fatal("sh_cpu_interrupt_ack(): TODO\n");  */          uint32_t vbr = cpu->cd.sh.vbr;
602          return 0;  
603            if (!quiet_mode) {
604                    if (intevt > 0)
605                            debug("[ interrupt 0x%03x", intevt);
606                    else
607                            debug("[ exception 0x%03x", expevt);
608    
609                    debug(", pc=0x%08"PRIx32" ", (uint32_t)cpu->pc);
610                    if (intevt == 0)
611                            debug("vaddr=0x%08"PRIx32" ", vaddr);
612    
613                    debug(" ]\n");
614            }
615    
616            if (cpu->cd.sh.sr & SH_SR_BL) {
617                    fatal("[ sh_exception(): BL bit already set. ]\n");
618    
619                    /*  This is actually OK in two cases: a User Break,
620                        or on NMI interrupts if a special flag is set?  */
621                    /*  TODO  */
622    
623                    expevt = EXPEVT_RESET_POWER;
624            }
625    
626            if (cpu->is_halted) {
627                    /*
628                     *  If the exception occurred on a 'sleep' instruction, then let
629                     *  the instruction following the sleep instruction be the one
630                     *  where execution resumes when the interrupt service routine
631                     *  returns.
632                     */
633                    cpu->is_halted = 0;
634                    cpu->pc += sizeof(uint16_t);
635            }
636    
637            if (cpu->delay_slot) {
638                    cpu->delay_slot = EXCEPTION_IN_DELAY_SLOT;
639                    cpu->pc -= sizeof(uint16_t);
640            }
641    
642    
643            /*
644             *  Stuff common to all exceptions:
645             */
646    
647            cpu->cd.sh.spc = cpu->pc;
648            cpu->cd.sh.ssr = cpu->cd.sh.sr;
649            cpu->cd.sh.sgr = cpu->cd.sh.r[15];
650    
651            if (intevt > 0) {
652                    cpu->cd.sh.intevt = intevt;
653                    expevt = -1;
654            } else {
655                    cpu->cd.sh.expevt = expevt;
656            }
657    
658            sh_update_sr(cpu, cpu->cd.sh.sr | SH_SR_MD | SH_SR_RB | SH_SR_BL);
659    
660            /*  Most exceptions set PC to VBR + 0x100.  */
661            cpu->pc = vbr + 0x100;
662    
663    
664            /*  Specific cases:  */
665            switch (expevt) {
666    
667            case -1:        /*  Interrupt  */
668                    cpu->pc = vbr + 0x600;
669                    break;
670    
671            case EXPEVT_RESET_POWER:
672            case EXPEVT_RESET_MANUAL:
673                    cpu->pc = 0xa0000000;
674                    cpu->cd.sh.vbr = 0x00000000;
675                    sh_update_sr(cpu, (cpu->cd.sh.sr | SH_SR_IMASK) & ~SH_SR_FD);
676                    break;
677    
678            case EXPEVT_TLB_MISS_LD:
679            case EXPEVT_TLB_MISS_ST:
680                    cpu->pc = vbr + 0x400;
681            case EXPEVT_TLB_PROT_LD:
682            case EXPEVT_TLB_PROT_ST:
683            case EXPEVT_TLB_MOD:
684                    cpu->cd.sh.tea = vaddr;
685                    cpu->cd.sh.pteh &= ~SH4_PTEH_VPN_MASK;
686                    cpu->cd.sh.pteh |= (vaddr & SH4_PTEH_VPN_MASK);
687                    break;
688    
689            case EXPEVT_TRAPA:
690                    /*
691                     *  Note: The TRA register is already set by the implementation
692                     *  of the trapa instruction. See cpu_sh_instr.c for details.
693                     *  Here, spc is incremented, so that a return from the trap
694                     *  handler transfers control to the instruction _following_
695                     *  the trapa.
696                     */
697                    cpu->cd.sh.spc += sizeof(uint16_t);
698                    break;
699    
700            case EXPEVT_RES_INST:
701                    /*
702                     *  Note: Having this code here makes it possible to catch
703                     *  reserved instructions; during normal instruction execution,
704                     *  these are not very common.
705                     */
706    #if 1
707                    printf("\nRESERVED SuperH instruction at spc=%08"PRIx32"\n",
708                        cpu->cd.sh.spc);
709                    exit(1);
710    #else
711                    break;
712    #endif
713    
714            case EXPEVT_FPU_DISABLE:
715                    break;
716    
717            default:fatal("sh_exception(): exception 0x%x is not yet "
718                        "implemented.\n", expevt);
719                    exit(1);
720            }
721    
722            sh_pc_to_pointers(cpu);
723  }  }
724    
725    
# Line 248  int sh_cpu_interrupt_ack(struct cpu *cpu Line 733  int sh_cpu_interrupt_ack(struct cpu *cpu
733  int sh_cpu_disassemble_instr_compact(struct cpu *cpu, unsigned char *instr,  int sh_cpu_disassemble_instr_compact(struct cpu *cpu, unsigned char *instr,
734          int running, uint64_t dumpaddr)          int running, uint64_t dumpaddr)
735  {  {
736          uint64_t addr;          char *symbol;
737            uint64_t offset, addr;
738          uint16_t iword;          uint16_t iword;
739          int hi4, lo4, lo8, r8, r4;          int hi4, lo4, lo8, r8, r4;
740    
# Line 257  int sh_cpu_disassemble_instr_compact(str Line 743  int sh_cpu_disassemble_instr_compact(str
743          else          else
744                  iword = (instr[1] << 8) + instr[0];                  iword = (instr[1] << 8) + instr[0];
745    
746          debug(":  %04x \t", iword);          debug(":  %04x %s\t", iword, cpu->delay_slot? "(d)" : "");
747          hi4 = iword >> 12; lo4 = iword & 15; lo8 = iword & 255;          hi4 = iword >> 12; lo4 = iword & 15; lo8 = iword & 255;
748          r8 = (iword >> 8) & 15; r4 = (iword >> 4) & 15;          r8 = (iword >> 8) & 15; r4 = (iword >> 4) & 15;
749    
# Line 271  int sh_cpu_disassemble_instr_compact(str Line 757  int sh_cpu_disassemble_instr_compact(str
757                          debug("stc\tsr,r%i\n", r8);                          debug("stc\tsr,r%i\n", r8);
758                  else if (lo8 == 0x03)                  else if (lo8 == 0x03)
759                          debug("bsrf\tr%i\n", r8);                          debug("bsrf\tr%i\n", r8);
760                  else if (lo4 == 0x4)                  else if (lo4 >= 4 && lo4 <= 6) {
761                          debug("mov.b\tr%i,@(r0,r%i)\n", r4, r8);                          if (lo4 == 0x4)
762                  else if (lo4 == 0x5)                                  debug("mov.b\tr%i,@(r0,r%i)", r4, r8);
763                          debug("mov.w\tr%i,@(r0,r%i)\n", r4, r8);                          else if (lo4 == 0x5)
764                  else if (lo4 == 0x6)                                  debug("mov.w\tr%i,@(r0,r%i)", r4, r8);
765                          debug("mov.l\tr%i,@(r0,r%i)\n", r4, r8);                          else if (lo4 == 0x6)
766                  else if (lo4 == 0x7)                                  debug("mov.l\tr%i,@(r0,r%i)", r4, r8);
767                            if (running) {
768                                    uint32_t addr = cpu->cd.sh.r[0] +
769                                        cpu->cd.sh.r[r8];
770                                    debug("\t; r0+r%i = ", r8);
771                                    symbol = get_symbol_name(
772                                        &cpu->machine->symbol_context,
773                                        addr, &offset);
774                                    if (symbol != NULL)
775                                            debug("<%s>", symbol);
776                                    else
777                                            debug("0x%08"PRIx32, addr);
778                            }
779                            debug("\n");
780                    } else if (lo4 == 0x7)
781                          debug("mul.l\tr%i,r%i\n", r4, r8);                          debug("mul.l\tr%i,r%i\n", r4, r8);
782                  else if (iword == 0x0008)                  else if (iword == 0x0008)
783                          debug("clrt\n");                          debug("clrt\n");
# Line 287  int sh_cpu_disassemble_instr_compact(str Line 787  int sh_cpu_disassemble_instr_compact(str
787                          debug("sts\tmach,r%i\n", r8);                          debug("sts\tmach,r%i\n", r8);
788                  else if (iword == 0x000b)                  else if (iword == 0x000b)
789                          debug("rts\n");                          debug("rts\n");
790                  else if (lo4 == 0xc)                  else if (lo4 >= 0xc && lo4 <= 0xe) {
791                          debug("mov.b\t@(r0,r%i),r%i\n", r4, r8);                          if (lo4 == 0xc)
792                  else if (lo4 == 0xd)                                  debug("mov.b\t@(r0,r%i),r%i", r4, r8);
793                          debug("mov.w\t@(r0,r%i),r%i\n", r4, r8);                          else if (lo4 == 0xd)
794                  else if (lo4 == 0xe)                                  debug("mov.w\t@(r0,r%i),r%i", r4, r8);
795                          debug("mov.l\t@(r0,r%i),r%i\n", r4, r8);                          else if (lo4 == 0xe)
796                  else if (lo8 == 0x12)                                  debug("mov.l\t@(r0,r%i),r%i", r4, r8);
797                            if (running) {
798                                    uint32_t addr = cpu->cd.sh.r[0] +
799                                        cpu->cd.sh.r[r4];
800                                    debug("\t; r0+r%i = ", r4);
801                                    symbol = get_symbol_name(
802                                        &cpu->machine->symbol_context,
803                                        addr, &offset);
804                                    if (symbol != NULL)
805                                            debug("<%s>", symbol);
806                                    else
807                                            debug("0x%08"PRIx32, addr);
808                            }
809                            debug("\n");
810                    } else if (lo8 == 0x12)
811                          debug("stc\tgbr,r%i\n", r8);                          debug("stc\tgbr,r%i\n", r8);
812                  else if (iword == 0x0018)                  else if (iword == 0x0018)
813                          debug("sett\n");                          debug("sett\n");
# Line 301  int sh_cpu_disassemble_instr_compact(str Line 815  int sh_cpu_disassemble_instr_compact(str
815                          debug("div0u\n");                          debug("div0u\n");
816                  else if (lo8 == 0x1a)                  else if (lo8 == 0x1a)
817                          debug("sts\tmacl,r%i\n", r8);                          debug("sts\tmacl,r%i\n", r8);
818                    else if (iword == 0x001b)
819                            debug("sleep\n");
820                    else if (lo8 == 0x22)
821                            debug("stc\tvbr,r%i\n", r8);
822                  else if (lo8 == 0x23)                  else if (lo8 == 0x23)
823                          debug("braf\tr%i\n", r8);                          debug("braf\tr%i\n", r8);
824                  else if (iword == 0x0028)                  else if (iword == 0x0028)
825                          debug("clrmac\n");                          debug("clrmac\n");
826                  else if (lo8 == 0x29)                  else if (lo8 == 0x29)
827                          debug("movt\tr%i\n", r8);                          debug("movt\tr%i\n", r8);
828                    else if (lo8 == 0x2a)
829                            debug("sts\tpr,r%i\n", r8);
830                    else if (iword == 0x002b)
831                            debug("rte\n");
832                    else if (lo8 == 0x32)
833                            debug("stc\tssr,r%i\n", r8);
834                    else if (iword == 0x0038)
835                            debug("ldtlb\n");
836                  else if (iword == 0x003b)                  else if (iword == 0x003b)
837                          debug("brk\n");                          debug("brk\n");
838                    else if (lo8 == 0x42)
839                            debug("stc\tspc,r%i\n", r8);
840                  else if (iword == 0x0048)                  else if (iword == 0x0048)
841                          debug("clrs\n");                          debug("clrs\n");
842                  else if (iword == 0x0058)                  else if (iword == 0x0058)
843                          debug("sets\n");                          debug("sets\n");
844                    else if (lo8 == 0x5a)
845                            debug("sts\tfpul,r%i\n", r8);
846                    else if (lo8 == 0x6a)
847                            debug("sts\tfpscr,r%i\n", r8);
848                    else if ((lo8 & 0x8f) == 0x82)
849                            debug("stc\tr%i_bank,r%i\n", (lo8 >> 4) & 7, r8);
850                  else if (lo8 == 0x83)                  else if (lo8 == 0x83)
851                          debug("pref\t@r%i\n", r8);                          debug("pref\t@r%i\n", r8);
852                    else if (lo8 == 0x93)
853                            debug("ocbi\t@r%i\n", r8);
854                    else if (lo8 == 0xa3)
855                            debug("ocbp\t@r%i\n", r8);
856                    else if (lo8 == 0xb3)
857                            debug("ocbwb\t@r%i\n", r8);
858                    else if (lo8 == 0xc3)
859                            debug("movca.l\tr0,@r%i\n", r8);
860                    else if (lo8 == 0xfa)
861                            debug("stc\tdbr,r%i\n", r8);
862                    else if (iword == SH_INVALID_INSTR)
863                            debug("gxemul_dreamcast_prom_emul\n");
864                  else                  else
865                          debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);                          debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
866                  break;                  break;
867          case 0x1:          case 0x1:
868                  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);
869                    if (running) {
870                            uint32_t addr = cpu->cd.sh.r[r8] + lo4 * 4;
871                            debug("\t; r%i+%i = ", r8, lo4 * 4);
872                            symbol = get_symbol_name(&cpu->machine->symbol_context,
873                                addr, &offset);
874                            if (symbol != NULL)
875                                    debug("<%s>", symbol);
876                            else
877                                    debug("0x%08"PRIx32, addr);
878                    }
879                    debug("\n");
880                  break;                  break;
881          case 0x2:          case 0x2:
882                  if (lo4 == 0x0)                  if (lo4 == 0x0)
# Line 392  int sh_cpu_disassemble_instr_compact(str Line 949  int sh_cpu_disassemble_instr_compact(str
949                          debug("shll\tr%i\n", r8);                          debug("shll\tr%i\n", r8);
950                  else if (lo8 == 0x01)                  else if (lo8 == 0x01)
951                          debug("shlr\tr%i\n", r8);                          debug("shlr\tr%i\n", r8);
952                    else if (lo8 == 0x02)
953                            debug("sts.l\tmach,@-r%i\n", r8);
954                    else if (lo8 == 0x03)
955                            debug("stc.l\tsr,@-r%i\n", r8);
956                  else if (lo8 == 0x04)                  else if (lo8 == 0x04)
957                          debug("rotl\tr%i\n", r8);                          debug("rotl\tr%i\n", r8);
958                  else if (lo8 == 0x05)                  else if (lo8 == 0x05)
959                          debug("rotr\tr%i\n", r8);                          debug("rotr\tr%i\n", r8);
960                  else if (lo8 == 0x06)                  else if (lo8 == 0x06)
961                          debug("lds.l\t@r%i+,mach\n", r8);                          debug("lds.l\t@r%i+,mach\n", r8);
962                    else if (lo8 == 0x07)
963                            debug("ldc.l\t@r%i+,sr\n", r8);
964                  else if (lo8 == 0x08)                  else if (lo8 == 0x08)
965                          debug("shll2\tr%i\n", r8);                          debug("shll2\tr%i\n", r8);
966                  else if (lo8 == 0x09)                  else if (lo8 == 0x09)
# Line 416  int sh_cpu_disassemble_instr_compact(str Line 979  int sh_cpu_disassemble_instr_compact(str
979                          debug("dt\tr%i\n", r8);                          debug("dt\tr%i\n", r8);
980                  else if (lo8 == 0x11)                  else if (lo8 == 0x11)
981                          debug("cmp/pz\tr%i\n", r8);                          debug("cmp/pz\tr%i\n", r8);
982                    else if (lo8 == 0x12)
983                            debug("sts.l\tmacl,@-r%i\n", r8);
984                    else if (lo8 == 0x13)
985                            debug("stc.l\tgbr,@-r%i\n", r8);
986                  else if (lo8 == 0x15)                  else if (lo8 == 0x15)
987                          debug("cmp/pl\tr%i\n", r8);                          debug("cmp/pl\tr%i\n", r8);
988                  else if (lo8 == 0x16)                  else if (lo8 == 0x16)
989                          debug("lds.l\t@r%i+,macl\n", r8);                          debug("lds.l\t@r%i+,macl\n", r8);
990                    else if (lo8 == 0x17)
991                            debug("ldc.l\t@r%i+,gbr\n", r8);
992                  else if (lo8 == 0x18)                  else if (lo8 == 0x18)
993                          debug("shll8\tr%i\n", r8);                          debug("shll8\tr%i\n", r8);
994                  else if (lo8 == 0x19)                  else if (lo8 == 0x19)
# Line 436  int sh_cpu_disassemble_instr_compact(str Line 1005  int sh_cpu_disassemble_instr_compact(str
1005                          debug("shar\tr%i\n", r8);                          debug("shar\tr%i\n", r8);
1006                  else if (lo8 == 0x22)                  else if (lo8 == 0x22)
1007                          debug("sts.l\tpr,@-r%i\n", r8);                          debug("sts.l\tpr,@-r%i\n", r8);
1008                    else if (lo8 == 0x23)
1009                            debug("stc.l\tvbr,@-r%i\n", r8);
1010                  else if (lo8 == 0x24)                  else if (lo8 == 0x24)
1011                          debug("rotcl\tr%i\n", r8);                          debug("rotcl\tr%i\n", r8);
1012                  else if (lo8 == 0x25)                  else if (lo8 == 0x25)
1013                          debug("rotcr\tr%i\n", r8);                          debug("rotcr\tr%i\n", r8);
1014                  else if (lo8 == 0x26)                  else if (lo8 == 0x26)
1015                          debug("lds.l\t@r%i+,pr\n", r8);                          debug("lds.l\t@r%i+,pr\n", r8);
1016                    else if (lo8 == 0x27)
1017                            debug("ldc.l\t@r%i+,vbr\n", r8);
1018                  else if (lo8 == 0x28)                  else if (lo8 == 0x28)
1019                          debug("shll16\tr%i\n", r8);                          debug("shll16\tr%i\n", r8);
1020                  else if (lo8 == 0x29)                  else if (lo8 == 0x29)
1021                          debug("shlr16\tr%i\n", r8);                          debug("shlr16\tr%i\n", r8);
1022                  else if (lo8 == 0x2a)                  else if (lo8 == 0x2a)
1023                          debug("lds\tr%i,pr\n", r8);                          debug("lds\tr%i,pr\n", r8);
1024                  else if (lo8 == 0x2b)                  else if (lo8 == 0x2b) {
1025                          debug("jmp\t@r%i\n", r8);                          debug("jmp\t@r%i", r8);
1026                            if (running) {
1027                                    symbol = get_symbol_name(
1028                                        &cpu->machine->symbol_context,
1029                                        cpu->cd.sh.r[r8], &offset);
1030                                    if (symbol != NULL)
1031                                            debug("\t\t; <%s>", symbol);
1032                            }
1033                            debug("\n");
1034                    } else if (lo8 == 0x2e)
1035                            debug("ldc\tr%i,vbr\n", r8);
1036                    else if (lo8 == 0x33)
1037                            debug("stc.l\tssr,@-r%i\n", r8);
1038                    else if (lo8 == 0x37)
1039                            debug("ldc.l\t@r%i+,ssr\n", r8);
1040                    else if (lo8 == 0x3e)
1041                            debug("ldc\tr%i,ssr\n", r8);
1042                    else if (lo8 == 0x43)
1043                            debug("stc.l\tspc,@-r%i\n", r8);
1044                    else if (lo8 == 0x47)
1045                            debug("ldc.l\t@r%i+,spc\n", r8);
1046                    else if (lo8 == 0x4e)
1047                            debug("ldc\tr%i,spc\n", r8);
1048                    else if (lo8 == 0x52)
1049                            debug("sts.l\tfpul,@-r%i\n", r8);
1050                  else if (lo8 == 0x56)                  else if (lo8 == 0x56)
1051                          debug("lds.l\t@r%i+,fpul\n", r8);                          debug("lds.l\t@r%i+,fpul\n", r8);
1052                  else if (lo8 == 0x5a)                  else if (lo8 == 0x5a)
1053                          debug("lds\tr%i,fpul\n", r8);                          debug("lds\tr%i,fpul\n", r8);
1054                    else if (lo8 == 0x62)
1055                            debug("sts.l\tfpscr,@-r%i\n", r8);
1056                    else if (lo8 == 0x66)
1057                            debug("lds.l\t@r%i+,fpscr\n", r8);
1058                  else if (lo8 == 0x6a)                  else if (lo8 == 0x6a)
1059                          debug("lds\tr%i,fpscr\n", r8);                          debug("lds\tr%i,fpscr\n", r8);
1060                    else if ((lo8 & 0x8f) == 0x83)
1061                            debug("stc.l\tr%i_bank,@-r%i\n", (lo8 >> 4) & 7, r8);
1062                    else if ((lo8 & 0x8f) == 0x87)
1063                            debug("ldc.l\t@r%i,r%i_bank\n", r8, (lo8 >> 4) & 7, r8);
1064                    else if ((lo8 & 0x8f) == 0x8e)
1065                            debug("ldc\tr%i,r%i_bank\n", r8, (lo8 >> 4) & 7);
1066                    else if (lo8 == 0xfa)
1067                            debug("ldc\tr%i,dbr\n", r8);
1068                  else                  else
1069                          debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);                          debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
1070                  break;                  break;
1071          case 0x5:          case 0x5:
1072                  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);
1073                    if (running) {
1074                            debug("\t; r%i+%i = 0x%08"PRIx32, r4, lo4 * 4,
1075                                cpu->cd.sh.r[r4] + lo4 * 4);
1076                    }
1077                    debug("\n");
1078                  break;                  break;
1079          case 0x6:          case 0x6:
1080                  if (lo4 == 0x0)                  if (lo4 == 0x0)
# Line 473  int sh_cpu_disassemble_instr_compact(str Line 1087  int sh_cpu_disassemble_instr_compact(str
1087                          debug("mov\tr%i,r%i\n", r4, r8);                          debug("mov\tr%i,r%i\n", r4, r8);
1088                  else if (lo4 == 0x4)                  else if (lo4 == 0x4)
1089                          debug("mov.b\t@r%i+,r%i\n", r4, r8);                          debug("mov.b\t@r%i+,r%i\n", r4, r8);
1090                    else if (lo4 == 0x5)
1091                            debug("mov.w\t@r%i+,r%i\n", r4, r8);
1092                  else if (lo4 == 0x6)                  else if (lo4 == 0x6)
1093                          debug("mov.l\t@r%i+,r%i\n", r4, r8);                          debug("mov.l\t@r%i+,r%i\n", r4, r8);
1094                  else if (lo4 == 0x7)                  else if (lo4 == 0x7)
# Line 500  int sh_cpu_disassemble_instr_compact(str Line 1116  int sh_cpu_disassemble_instr_compact(str
1116                  debug("add\t#%i,r%i\n", (int8_t)lo8, r8);                  debug("add\t#%i,r%i\n", (int8_t)lo8, r8);
1117                  break;                  break;
1118          case 0x8:          case 0x8:
1119                  if (r8 == 0x8)                  if (r8 == 0 || r8 == 4) {
1120                            if (r8 == 0x0)
1121                                    debug("mov.b\tr0,@(%i,r%i)", lo4, r4);
1122                            else if (r8 == 0x4)
1123                                    debug("mov.b\t@(%i,r%i),r0", lo4, r4);
1124                            if (running) {
1125                                    debug("\t; r%i+%i = 0x%08"PRIx32, r4, lo4,
1126                                        cpu->cd.sh.r[r4] + lo4);
1127                            }
1128                            debug("\n");
1129                    } else if (r8 == 1 || r8 == 5) {
1130                            if (r8 == 0x1)
1131                                    debug("mov.w\tr0,@(%i,r%i)", lo4 * 2, r4);
1132                            else if (r8 == 0x5)
1133                                    debug("mov.w\t@(%i,r%i),r0", lo4 * 2, r4);
1134                            if (running) {
1135                                    debug("\t; r%i+%i = 0x%08"PRIx32, r4, lo4 * 2,
1136                                        cpu->cd.sh.r[r4] + lo4 * 2);
1137                            }
1138                            debug("\n");
1139                    } else if (r8 == 0x8) {
1140                          debug("cmp/eq\t#%i,r0\n", (int8_t)lo8);                          debug("cmp/eq\t#%i,r0\n", (int8_t)lo8);
1141                  else if (r8 == 0x9 || r8 == 0xb || r8 == 0xd || r8 == 0xf) {                  } else if (r8 == 0x9 || r8 == 0xb || r8 == 0xd || r8 == 0xf) {
1142                          addr = (int8_t)lo8;                          addr = (int8_t)lo8;
1143                          addr = dumpaddr + 4 + (addr << 1);                          addr = dumpaddr + 4 + (addr << 1);
1144                          debug("b%s%s\t0x%x\n",                          debug("b%s%s\t0x%x",
1145                              (r8 == 0x9 || r8 == 0xd)? "t" : "f",                              (r8 == 0x9 || r8 == 0xd)? "t" : "f",
1146                              (r8 == 0x9 || r8 == 0xb)? "" : "/s", (int)addr);                              (r8 == 0x9 || r8 == 0xb)? "" : "/s", (int)addr);
1147                            symbol = get_symbol_name(&cpu->machine->symbol_context,
1148                                addr, &offset);
1149                            if (symbol != NULL)
1150                                    debug("\t; <%s>", symbol);
1151                            debug("\n");
1152                  } else                  } else
1153                          debug("UNIMPLEMENTED hi4=0x%x,0x%x\n", hi4, r8);                          debug("UNIMPLEMENTED hi4=0x%x,0x%x\n", hi4, r8);
1154                  break;                  break;
1155          case 0x9:          case 0x9:
1156          case 0xd:          case 0xd:
1157                  addr = ((int8_t)lo8) * (hi4==9? 2 : 4);                  addr = lo8 * (hi4==9? 2 : 4);
1158                  addr += (dumpaddr & ~(hi4==9? 1 : 3)) + 4;                  addr += (dumpaddr & ~(hi4==9? 1 : 3)) + 4;
1159                  debug("mov.%s\t0x%x,r%i\n", hi4==9? "w":"l", (int)addr, r8);                  debug("mov.%s\t0x%x,r%i", hi4==9? "w":"l", (int)addr, r8);
1160                    symbol = get_symbol_name(&cpu->machine->symbol_context,
1161                        addr, &offset);
1162                    if (symbol != NULL)
1163                            debug("\t; <%s>", symbol);
1164                    debug("\n");
1165                  break;                  break;
1166          case 0xa:          case 0xa:
1167          case 0xb:          case 0xb:
1168                  addr = (int32_t)(int16_t)((iword & 0xfff) << 4);                  addr = (int32_t)(int16_t)((iword & 0xfff) << 4);
1169                  addr = ((int32_t)addr >> 3);                  addr = ((int32_t)addr >> 3);
1170                  addr += dumpaddr + 4;                  addr += dumpaddr + 4;
1171                  debug("%s\t0x%x\n", hi4==0xa? "bra":"bsr", (int)addr);                  debug("%s\t0x%x", hi4==0xa? "bra":"bsr", (int)addr);
1172    
1173                    symbol = get_symbol_name(&cpu->machine->symbol_context,
1174                        addr, &offset);
1175                    if (symbol != NULL)
1176                            debug("\t; <%s>", symbol);
1177                    debug("\n");
1178                  break;                  break;
1179          case 0xc:          case 0xc:
1180                  if (r8 == 0x3)                  if (r8 == 0x0)
1181                            debug("mov.b\tr0,@(%i,gbr)\n", lo8);
1182                    else if (r8 == 0x1)
1183                            debug("mov.w\tr0,@(%i,gbr)\n", lo8 * 2);
1184                    else if (r8 == 0x2)
1185                            debug("mov.l\tr0,@(%i,gbr)\n", lo8 * 4);
1186                    else if (r8 == 0x3)
1187                          debug("trapa\t#%i\n", (uint8_t)lo8);                          debug("trapa\t#%i\n", (uint8_t)lo8);
1188                  else if (r8 == 0x8)                  else if (r8 == 0x4)
1189                            debug("mov.b\t(%i,gbr),r0\n", lo8);
1190                    else if (r8 == 0x5)
1191                            debug("mov.w\t(%i,gbr),r0\n", lo8 * 2);
1192                    else if (r8 == 0x6)
1193                            debug("mov.l\t(%i,gbr),r0\n", lo8 * 4);
1194                    else if (r8 == 0x7) {
1195                            addr = lo8 * 4 + (dumpaddr & ~3) + 4;
1196                            debug("mova\t0x%x,r0\n", (int)addr);
1197                    } else if (r8 == 0x8)
1198                          debug("tst\t#%i,r0\n", (uint8_t)lo8);                          debug("tst\t#%i,r0\n", (uint8_t)lo8);
1199                  else if (r8 == 0x9)                  else if (r8 == 0x9)
1200                          debug("and\t#%i,r0\n", (uint8_t)lo8);                          debug("and\t#%i,r0\n", (uint8_t)lo8);
# Line 549  int sh_cpu_disassemble_instr_compact(str Line 1216  int sh_cpu_disassemble_instr_compact(str
1216          case 0xe:          case 0xe:
1217                  debug("mov\t#%i,r%i\n", (int8_t)lo8, r8);                  debug("mov\t#%i,r%i\n", (int8_t)lo8, r8);
1218                  break;                  break;
1219            case 0xf:
1220                    if (lo4 == 0x0)
1221                            debug("fadd\t%sr%i,%sr%i\n",
1222                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1223                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1224                    else if (lo4 == 0x1)
1225                            debug("fsub\t%sr%i,%sr%i\n",
1226                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1227                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1228                    else if (lo4 == 0x2)
1229                            debug("fmul\t%sr%i,%sr%i\n",
1230                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1231                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1232                    else if (lo4 == 0x3)
1233                            debug("fdiv\t%sr%i,%sr%i\n",
1234                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1235                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1236                    else if (lo4 == 0x4)
1237                            debug("fcmp/eq\t%sr%i,%sr%i\n",
1238                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1239                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1240                    else if (lo4 == 0x5)
1241                            debug("fcmp/gt\t%sr%i,%sr%i\n",
1242                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1243                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1244                    else if (lo4 == 0x6) {
1245                            char *n = "fr";
1246                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1247                                    n = (r8 & 1)? "xd" : "dr";
1248                                    r8 &= ~1;
1249                            }
1250                            debug("fmov\t@(r0,r%i),%s%i\n", r4, n, r8);
1251                    } else if (lo4 == 0x7) {
1252                            char *n = "fr";
1253                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1254                                    n = (r4 & 1)? "xd" : "dr";
1255                                    r4 &= ~1;
1256                            }
1257                            debug("fmov\t%s%i,@(r0,r%i)\n", n, r4, r8);
1258                    } else if (lo4 == 0x8) {
1259                            char *n = "fr";
1260                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1261                                    n = (r8 & 1)? "xd" : "dr";
1262                                    r8 &= ~1;
1263                            }
1264                            debug("fmov\t@r%i,%s%i\n", r4, n, r8);
1265                    } else if (lo4 == 0x9) {
1266                            char *n = "fr";
1267                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1268                                    n = (r8 & 1)? "xd" : "dr";
1269                                    r8 &= ~1;
1270                            }
1271                            debug("fmov\t@r%i+,%s%i\n", r4, n, r8);
1272                    } else if (lo4 == 0xa) {
1273                            char *n = "fr";
1274                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1275                                    n = (r4 & 1)? "xd" : "dr";
1276                                    r4 &= ~1;
1277                            }
1278                            debug("fmov\t%s%i,@r%i\n", n, r4, r8);
1279                    } else if (lo4 == 0xb) {
1280                            char *n = "fr";
1281                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1282                                    n = (r4 & 1)? "xd" : "dr";
1283                                    r4 &= ~1;
1284                            }
1285                            debug("fmov\t%s%i,@-r%i\n", n, r4, r8);
1286                    } else if (lo4 == 0xc) {
1287                            char *n1 = "fr", *n2 = "fr";
1288                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1289                                    n1 = (r4 & 1)? "xd" : "dr";
1290                                    n2 = (r8 & 1)? "xd" : "dr";
1291                                    r4 &= ~1; r8 &= ~1;
1292                            }
1293                            debug("fmov\t%s%i,%s%i\n", n1, r4, n2, r8);
1294                    } else if (lo8 == 0x0d)
1295                            debug("fsts\tfpul,fr%i\n", r8);
1296                    else if (lo8 == 0x1d)
1297                            debug("flds\tfr%i,fpul\n", r8);
1298                    else if (lo8 == 0x2d)
1299                            debug("float\tfpul,%sr%i\n",
1300                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1301                    else if (lo8 == 0x3d)
1302                            debug("ftrc\t%sr%i,fpul\n",
1303                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1304                    else if (lo8 == 0x4d)
1305                            debug("fneg\t%sr%i\n",
1306                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1307                    else if (lo8 == 0x5d)
1308                            debug("fabs\t%sr%i\n",
1309                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1310                    else if (lo8 == 0x6d)
1311                            debug("fsqrt\t%sr%i\n",
1312                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1313                    else if (lo8 == 0x8d)
1314                            debug("fldi0\tfr%i\n", r8);
1315                    else if (lo8 == 0x9d)
1316                            debug("fldi1\tfr%i\n", r8);
1317                    else if (lo8 == 0xad)
1318                            debug("fcnvsd\tfpul,dr%i\n", r8);
1319                    else if (lo8 == 0xbd)
1320                            debug("fcnvds\tdr%i,fpul\n", r8);
1321                    else if ((iword & 0x01ff) == 0x00fd)
1322                            debug("fsca\tfpul,dr%i\n", r8);
1323                    else if (iword == 0xf3fd)
1324                            debug("fschg\n");
1325                    else if (iword == 0xfbfd)
1326                            debug("frchg\n");
1327                    else if ((iword & 0xf3ff) == 0xf1fd)
1328                            debug("ftrv\txmtrx,fv%i\n", r8 & 0xc);
1329                    else if (lo4 == 0xe)
1330                            debug("fmac\tfr0,fr%i,fr%i\n", r4, r8);
1331                    else
1332                            debug("UNIMPLEMENTED hi4=0x%x,0x%x\n", hi4, lo8);
1333                    break;
1334          default:debug("UNIMPLEMENTED hi4=0x%x\n", hi4);          default:debug("UNIMPLEMENTED hi4=0x%x\n", hi4);
1335          }          }
1336    
# Line 586  int sh_cpu_disassemble_instr(struct cpu Line 1368  int sh_cpu_disassemble_instr(struct cpu
1368          if (cpu->machine->ncpus > 1 && running)          if (cpu->machine->ncpus > 1 && running)
1369                  debug("cpu%i: ", cpu->cpu_id);                  debug("cpu%i: ", cpu->cpu_id);
1370    
1371          if (cpu->cd.sh.bits == 32)          if (cpu->cd.sh.cpu_type.bits == 32)
1372                  debug("%08x", (int)dumpaddr);                  debug("%08x", (int)dumpaddr);
1373          else          else
1374                  debug("%016llx", (long long)dumpaddr);                  debug("%016llx", (long long)dumpaddr);

Legend:
Removed from v.26  
changed lines
  Added in v.40

  ViewVC Help
Powered by ViewVC 1.1.26