/[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 30 by dpavlin, Mon Oct 8 16:20:40 2007 UTC revision 32 by dpavlin, Mon Oct 8 16:20:58 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_sh.c,v 1.21 2006/07/25 21:49:14 debug Exp $   *  $Id: cpu_sh.c,v 1.53 2006/10/31 11:07:05 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 "machine.h"  #include "machine.h"
46  #include "memory.h"  #include "memory.h"
47  #include "misc.h"  #include "misc.h"
48    #include "settings.h"
49  #include "symbol.h"  #include "symbol.h"
50    
51    #include "sh4_exception.h"
52    #include "sh4_mmu.h"
53    
54  #define DYNTRANS_DUALMODE_32  
55    #define DYNTRANS_32
56    #define DYNTRANS_DELAYSLOT
57  #include "tmp_sh_head.c"  #include "tmp_sh_head.c"
58    
59    
60    extern int quiet_mode;
61    
62    void sh_pc_to_pointers(struct cpu *);
63    
64    
65  /*  /*
66   *  sh_cpu_new():   *  sh_cpu_new():
67   *   *
# Line 79  int sh_cpu_new(struct cpu *cpu, struct m Line 93  int sh_cpu_new(struct cpu *cpu, struct m
93          cpu->is_32bit = cpu->cd.sh.cpu_type.bits == 32;          cpu->is_32bit = cpu->cd.sh.cpu_type.bits == 32;
94          cpu->cd.sh.compact = 1;         /*  Default to 16-bit opcode mode  */          cpu->cd.sh.compact = 1;         /*  Default to 16-bit opcode mode  */
95    
96            if (!cpu->is_32bit) {
97                    fatal("SH64 emulation not implemented. Sorry.\n");
98                    exit(1);
99            }
100    
101            cpu->instruction_has_delayslot = sh_cpu_instruction_has_delayslot;
102    
103          cpu->translate_v2p = sh_translate_v2p;          cpu->translate_v2p = sh_translate_v2p;
104    
105          if (cpu->is_32bit) {          cpu->run_instr = sh_run_instr;
106                  cpu->run_instr = sh32_run_instr;          cpu->update_translation_table = sh_update_translation_table;
107                  cpu->update_translation_table = sh32_update_translation_table;          cpu->invalidate_translation_caches =
108                  cpu->invalidate_translation_caches =              sh_invalidate_translation_caches;
109                      sh32_invalidate_translation_caches;          cpu->invalidate_code_translation =
110                  cpu->invalidate_code_translation =              sh_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;  
         }  
111    
112          /*  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):  */
113          if (cpu_id == 0) {          if (cpu_id == 0) {
# Line 105  int sh_cpu_new(struct cpu *cpu, struct m Line 117  int sh_cpu_new(struct cpu *cpu, struct m
117          /*  Initial value of FPSCR (according to the SH4 manual):  */          /*  Initial value of FPSCR (according to the SH4 manual):  */
118          cpu->cd.sh.fpscr = 0x00040001;          cpu->cd.sh.fpscr = 0x00040001;
119    
120            /*  (Initial value of the program counter on reboot is 0xA0000000.)  */
121    
122          /*  Start in Privileged Mode:  */          /*  Start in Privileged Mode:  */
123          cpu->cd.sh.sr = SH_SR_MD;          cpu->cd.sh.sr = SH_SR_MD | SH_SR_IMASK;
124    
125            /*  Stack pointer at end of physical RAM:  */
126            cpu->cd.sh.r[15] = cpu->machine->physical_ram_in_mb * 1048576 - 64;
127    
128            CPU_SETTINGS_ADD_REGISTER64("pc", cpu->pc);
129            CPU_SETTINGS_ADD_REGISTER32("sr", cpu->cd.sh.sr);
130            CPU_SETTINGS_ADD_REGISTER32("pr", cpu->cd.sh.pr);
131            CPU_SETTINGS_ADD_REGISTER32("vbr", cpu->cd.sh.vbr);
132            CPU_SETTINGS_ADD_REGISTER32("gbr", cpu->cd.sh.gbr);
133            CPU_SETTINGS_ADD_REGISTER32("macl", cpu->cd.sh.macl);
134            CPU_SETTINGS_ADD_REGISTER32("mach", cpu->cd.sh.mach);
135            CPU_SETTINGS_ADD_REGISTER32("fpscr", cpu->cd.sh.fpscr);
136            CPU_SETTINGS_ADD_REGISTER32("fpul", cpu->cd.sh.fpul);
137            for (i=0; i<SH_N_GPRS; i++) {
138                    char tmpstr[5];
139                    snprintf(tmpstr, sizeof(tmpstr), "r%i", i);
140                    CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.r[i]);
141            }
142            for (i=0; i<SH_N_GPRS_BANKED; i++) {
143                    char tmpstr[15];
144                    snprintf(tmpstr, sizeof(tmpstr), "r%i_bank", i);
145                    CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.r_bank[i]);
146            }
147            for (i=0; i<SH_N_FPRS; i++) {
148                    char tmpstr[6];
149                    snprintf(tmpstr, sizeof(tmpstr), "fr%i", i);
150                    CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.fr[i]);
151                    snprintf(tmpstr, sizeof(tmpstr), "xf%i", i);
152                    CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.xf[i]);
153            }
154            for (i=0; i<SH_N_ITLB_ENTRIES; i++) {
155                    char tmpstr[15];
156                    snprintf(tmpstr, sizeof(tmpstr), "itlb_hi_%i", i);
157                    CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.itlb_hi[i]);
158                    snprintf(tmpstr, sizeof(tmpstr), "itlb_lo_%i", i);
159                    CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.itlb_lo[i]);
160            }
161            for (i=0; i<SH_N_UTLB_ENTRIES; i++) {
162                    char tmpstr[15];
163                    snprintf(tmpstr, sizeof(tmpstr), "utlb_hi_%i", i);
164                    CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.utlb_hi[i]);
165                    snprintf(tmpstr, sizeof(tmpstr), "utlb_lo_%i", i);
166                    CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.utlb_lo[i]);
167            }
168    
169            /*  SH4-specific memory mapped registers, TLBs, caches, etc:  */
170            if (cpu->cd.sh.cpu_type.arch == 4)
171                    device_add(machine, "sh4");
172    
173          return 1;          return 1;
174  }  }
# Line 138  void sh_cpu_list_available_types(void) Line 200  void sh_cpu_list_available_types(void)
200   */   */
201  void sh_cpu_dumpinfo(struct cpu *cpu)  void sh_cpu_dumpinfo(struct cpu *cpu)
202  {  {
203          debug("\n");          debug(" (%s-endian)\n",
204          /*  TODO  */              cpu->byte_order == EMUL_BIG_ENDIAN? "Big" : "Little");
205    }
206    
207    
208    /*
209     *  sh_cpu_instruction_has_delayslot():
210     *
211     *  Return 1 if an opcode is a branch, 0 otherwise.
212     */
213    int sh_cpu_instruction_has_delayslot(struct cpu *cpu, unsigned char *ib)
214    {
215            uint16_t iword = *((uint16_t *)&ib[0]);
216            int hi4, lo4, lo8;
217    
218            if (!cpu->is_32bit)
219                    return 0;
220    
221            if (cpu->byte_order == EMUL_BIG_ENDIAN)
222                    iword = BE16_TO_HOST(iword);
223            else
224                    iword = LE16_TO_HOST(iword);
225    
226            hi4 = iword >> 12; lo4 = iword & 15; lo8 = iword & 255;
227    
228            switch (hi4) {
229            case 0x0:
230                    if (iword == 0x000b)    /*  rts  */
231                            return 1;
232                    if (iword == 0x002b)    /*  rte  */
233                            return 1;
234                    if (lo8 == 0x03)        /*  bsrf  */
235                            return 1;
236                    if (lo8 == 0x23)        /*  braf  */
237                            return 1;
238                    break;
239            case 0x4:
240                    switch (lo8) {
241                    case 0x0b:      /*  jsr  */
242                    case 0x2b:      /*  jmp  */
243                            return 1;
244                    }
245                    break;
246            case 0x8:
247                    switch ((iword >> 8) & 0xf) {
248                    case 0xd:       /*  bt/s  */
249                    case 0xf:       /*  bf/s  */
250                            return 1;
251                    }
252                    break;
253            case 0xa:       /*  bra  */
254            case 0xb:       /*  bsr  */
255                    return 1;
256            }
257    
258            return 0;
259  }  }
260    
261    
# Line 156  void sh_cpu_register_dump(struct cpu *cp Line 272  void sh_cpu_register_dump(struct cpu *cp
272          char *symbol;          char *symbol;
273          uint64_t offset;          uint64_t offset;
274          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.cpu_type.bits == 32;  
275    
276          if (gprs) {          if (gprs) {
277                  /*  Special registers (pc, ...) first:  */                  /*  Special registers (pc, ...) first:  */
278                  symbol = get_symbol_name(&cpu->machine->symbol_context,                  symbol = get_symbol_name(&cpu->machine->symbol_context,
279                      cpu->pc, &offset);                      cpu->pc, &offset);
280    
281                  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);  
282                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");
283    
284                  debug("cpu%i: sr  = %s, %s, %s, %s, %s, %s, imask=0x%x, "                  debug("cpu%i: sr  = 0x%08"PRIx32"  (%s, %s, %s, %s, %s, %s,"
285                      "%s, %s\n", x,                      " imask=0x%x, %s, %s)\n", x, (int32_t)cpu->cd.sh.sr,
286                      (cpu->cd.sh.sr & SH_SR_MD)? "MD" : "!md",                      (cpu->cd.sh.sr & SH_SR_MD)? "MD" : "!md",
287                      (cpu->cd.sh.sr & SH_SR_RB)? "RB" : "!rb",                      (cpu->cd.sh.sr & SH_SR_RB)? "RB" : "!rb",
288                      (cpu->cd.sh.sr & SH_SR_BL)? "BL" : "!bl",                      (cpu->cd.sh.sr & SH_SR_BL)? "BL" : "!bl",
# Line 182  void sh_cpu_register_dump(struct cpu *cp Line 293  void sh_cpu_register_dump(struct cpu *cp
293                      (cpu->cd.sh.sr & SH_SR_S)? "S" : "!s",                      (cpu->cd.sh.sr & SH_SR_S)? "S" : "!s",
294                      (cpu->cd.sh.sr & SH_SR_T)? "T" : "!t");                      (cpu->cd.sh.sr & SH_SR_T)? "T" : "!t");
295    
296                  if (bits32) {                  symbol = get_symbol_name(&cpu->machine->symbol_context,
297                          /*  32-bit:  */                      cpu->cd.sh.pr, &offset);
298                          for (i=0; i<nregs; i++) {                  debug("cpu%i: pr  = 0x%08"PRIx32, x, (uint32_t)cpu->cd.sh.pr);
299                                  if ((i % 4) == 0)                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");
300                                          debug("cpu%i:", x);  
301                                  debug(" r%02i = 0x%08x ", i,                  debug("cpu%i: mach = 0x%08"PRIx32"  macl = 0x%08"PRIx32
302                                      (int)cpu->cd.sh.r[i]);                      "  gbr = 0x%08"PRIx32"\n", x, (uint32_t)cpu->cd.sh.mach,
303                                  if ((i % 4) == 3)                      (uint32_t)cpu->cd.sh.macl, (uint32_t)cpu->cd.sh.gbr);
304                                          debug("\n");  
305                          }                  for (i=0; i<nregs; i++) {
306                  } else {                          if ((i % 4) == 0)
307                          /*  64-bit:  */                                  debug("cpu%i:", x);
308                          for (i=0; i<nregs; i++) {                          debug(" r%-2i = 0x%08x ", i, (int)cpu->cd.sh.r[i]);
309                                  int r = (i >> 1) + ((i & 1) << 4);                          if ((i % 4) == 3)
310                                  if ((i % 2) == 0)                                  debug("\n");
                                         debug("cpu%i:", x);  
                                 debug(" r%02i = 0x%016llx ", r,  
                                     (long long)cpu->cd.sh.r[r]);  
                                 if ((i % 2) == 1)  
                                         debug("\n");  
                         }  
311                  }                  }
312          }          }
 }  
313    
314            if (coprocs & 1) {
315                    /*  Floating point:  */
316                    debug("cpu%i: fpscr = 0x%08"PRIx32"  fpul = 0x%08"PRIx32
317                        "\n", x, cpu->cd.sh.fpscr, cpu->cd.sh.fpul);
318    
319                    for (i=0; i<SH_N_FPRS; i++) {
320                            if ((i % 4) == 0)
321                                    debug("cpu%i:", x);
322                            debug(" fr%-2i=0x%08x ", i, (int)cpu->cd.sh.fr[i]);
323                            if ((i % 4) == 3)
324                                    debug("\n");
325                    }
326    
327  /*                  for (i=0; i<SH_N_FPRS; i++) {
328   *  sh_cpu_register_match():                          if ((i % 4) == 0)
329   */                                  debug("cpu%i:", x);
330  void sh_cpu_register_match(struct machine *m, char *name,                          debug(" xf%-2i=0x%08x ", i, (int)cpu->cd.sh.xf[i]);
331          int writeflag, uint64_t *valuep, int *match_register)                          if ((i % 4) == 3)
332  {                                  debug("\n");
333          int cpunr = 0;                  }
334            }
         /*  CPU number:  */  
   
         /*  TODO  */  
335    
336          /*  Register name:  */          if (coprocs & 2) {
337          if (strcasecmp(name, "pc") == 0) {                  /*  System registers, etc:  */
338                  if (writeflag) {                  debug("cpu%i: vbr = 0x%08"PRIx32"  sgr = 0x%08"PRIx32
339                          m->cpus[cpunr]->pc = *valuep;                      "\n", x, cpu->cd.sh.vbr, cpu->cd.sh.sgr);
340                  } else                  debug("cpu%i: spc = 0x%08"PRIx32"  ssr = 0x%08"PRIx32"\n",
341                          *valuep = m->cpus[cpunr]->pc;                      x, cpu->cd.sh.spc, cpu->cd.sh.ssr);
342                  *match_register = 1;                  debug("cpu%i: expevt = 0x%"PRIx32"  intevt = 0x%"PRIx32
343          } else if (name[0] == 'r' && isdigit((int)name[1])) {                      "  tra = 0x%"PRIx32"\n", x, cpu->cd.sh.expevt,
344                  int nr = atoi(name + 1);                      cpu->cd.sh.intevt, cpu->cd.sh.tra);
345                  if (nr >= 0 && nr < SH_N_GPRS) {  
346                          if (writeflag)                  for (i=0; i<SH_N_GPRS_BANKED; i++) {
347                                  m->cpus[cpunr]->cd.sh.r[nr] = *valuep;                          if ((i % 2) == 0)
348                          else                                  debug("cpu%i:", x);
349                                  *valuep = m->cpus[cpunr]->cd.sh.r[nr];                          debug(" r%i_bank = 0x%08x ", i,
350                          *match_register = 1;                              (int)cpu->cd.sh.r_bank[i]);
351                            if ((i % 2) == 1)
352                                    debug("\n");
353                  }                  }
354          }          }
355  }  }
# Line 251  void sh_cpu_register_match(struct machin Line 366  void sh_cpu_register_match(struct machin
366   */   */
367  void sh_cpu_tlbdump(struct machine *m, int x, int rawflag)  void sh_cpu_tlbdump(struct machine *m, int x, int rawflag)
368  {  {
369            int i, j;
370    
371            for (j=0; j<m->ncpus; j++) {
372                    struct cpu *cpu = m->cpus[j];
373    
374                    if (x >= 0 && j != x)
375                            continue;
376    
377                    for (i=0; i<SH_N_ITLB_ENTRIES; i++)
378                            printf("cpu%i: itlb_hi_%-2i = 0x%08"PRIx32"  "
379                                "itlb_lo_%-2i = 0x%08"PRIx32"\n", j, i,
380                                (uint32_t) cpu->cd.sh.itlb_hi[i], i,
381                                (uint32_t) cpu->cd.sh.itlb_lo[i]);
382                    for (i=0; i<SH_N_UTLB_ENTRIES; i++)
383                            printf("cpu%i: utlb_hi_%-2i = 0x%08"PRIx32"  "
384                                "utlb_lo_%-2i = 0x%08"PRIx32"\n", j, i,
385                                (uint32_t) cpu->cd.sh.utlb_hi[i], i,
386                                (uint32_t) cpu->cd.sh.utlb_lo[i]);
387            }
388  }  }
389    
390    
# Line 269  char *sh_cpu_gdb_stub(struct cpu *cpu, c Line 403  char *sh_cpu_gdb_stub(struct cpu *cpu, c
403    
404  /*  /*
405   *  sh_cpu_interrupt():   *  sh_cpu_interrupt():
406     *
407     *  Note: This gives higher interrupt priority to lower number interrupts.
408     *        Hopefully this is correct.
409   */   */
410  int sh_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)  int sh_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)
411  {  {
412          fatal("sh_cpu_interrupt(): TODO\n");          int word_index, bit_index;
413    
414            if (cpu->cd.sh.int_to_assert == 0 || irq_nr < cpu->cd.sh.int_to_assert)
415                    cpu->cd.sh.int_to_assert = irq_nr;
416    
417            /*
418             *  TODO: Keep track of all pending interrupts at multiple levels...
419             *
420             *  This is just a quick hack:
421             */
422            cpu->cd.sh.int_level = 1;
423            if (irq_nr == SH_INTEVT_TMU0_TUNI0)
424                    cpu->cd.sh.int_level = (cpu->cd.sh.intc_ipra >> 12) & 0xf;
425            if (irq_nr == SH_INTEVT_TMU1_TUNI1)
426                    cpu->cd.sh.int_level = (cpu->cd.sh.intc_ipra >> 8) & 0xf;
427            if (irq_nr == SH_INTEVT_TMU2_TUNI2)
428                    cpu->cd.sh.int_level = (cpu->cd.sh.intc_ipra >> 4) & 0xf;
429            if (irq_nr >= SH4_INTEVT_SCIF_ERI &&
430                irq_nr <= SH4_INTEVT_SCIF_TXI)
431                    cpu->cd.sh.int_level = (cpu->cd.sh.intc_iprc >> 4) & 0xf;
432    
433            irq_nr /= 0x20;
434            word_index = irq_nr / (sizeof(uint32_t)*8);
435            bit_index = irq_nr & ((sizeof(uint32_t)*8) - 1);
436    
437            cpu->cd.sh.int_pending[word_index] |= (1 << bit_index);
438    
439          return 0;          return 0;
440  }  }
441    
# Line 282  int sh_cpu_interrupt(struct cpu *cpu, ui Line 445  int sh_cpu_interrupt(struct cpu *cpu, ui
445   */   */
446  int sh_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)  int sh_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)
447  {  {
448          /*  fatal("sh_cpu_interrupt_ack(): TODO\n");  */          int word_index, bit_index;
449    
450            if (cpu->cd.sh.int_to_assert == irq_nr) {
451                    /*
452                     *  Rescan all interrupts to see if any are still asserted.
453                     *
454                     *  Note: The scan only has to go from irq_nr + 0x20 to the max
455                     *        index, since any lower interrupt cannot be asserted
456                     *        at this time.
457                     */
458                    int i, max = 0x1000;
459                    cpu->cd.sh.int_to_assert = 0;
460    
461                    for (i=irq_nr+0x20; i<max; i+=0x20) {
462                            int j = i / 0x20;
463                            int word_index = j / (sizeof(uint32_t)*8);
464                            int bit_index = j & ((sizeof(uint32_t)*8) - 1);
465    
466                            /*  Skip entire word if no bits are set:  */
467                            if (bit_index == 0 &&
468                                cpu->cd.sh.int_pending[word_index] == 0)
469                                    i += (sizeof(uint32_t)*8 - 1) * 0x20;
470                            else if (cpu->cd.sh.int_pending[word_index]
471                                & (1 << bit_index)) {
472                                    cpu->cd.sh.int_to_assert = i;
473                                    break;
474                            }
475                    }
476            }
477    
478            irq_nr /= 0x20;
479            word_index = irq_nr / (sizeof(uint32_t)*8);
480            bit_index = irq_nr & ((sizeof(uint32_t)*8) - 1);
481    
482            cpu->cd.sh.int_pending[word_index] &= ~(1 << bit_index);
483    
484          return 0;          return 0;
485  }  }
486    
487    
488  /*  /*
489   *  sh_update_sr():   *  sh_update_sr():
490     *
491     *  Writes a new value to the status register.
492   */   */
493  void sh_update_sr(struct cpu *cpu, uint32_t new_sr)  void sh_update_sr(struct cpu *cpu, uint32_t new_sr)
494  {  {
495          uint32_t old_sr = cpu->cd.sh.sr;          uint32_t old_sr = cpu->cd.sh.sr;
496    
497          if ((new_sr & SH_SR_RB) != (old_sr & SH_SR_RB)) {          if ((new_sr & SH_SR_RB) != (old_sr & SH_SR_RB)) {
498                  fatal("sh_update_sr(): Register bank switching is not"                  int i;
499                      " implemented yet! TODO\n");                  for (i=0; i<SH_N_GPRS_BANKED; i++) {
500                  exit(1);                          uint32_t tmp = cpu->cd.sh.r[i];
501                            cpu->cd.sh.r[i] = cpu->cd.sh.r_bank[i];
502                            cpu->cd.sh.r_bank[i] = tmp;
503                    }
504          }          }
505    
506          cpu->cd.sh.sr = new_sr;          cpu->cd.sh.sr = new_sr;
# Line 305  void sh_update_sr(struct cpu *cpu, uint3 Line 508  void sh_update_sr(struct cpu *cpu, uint3
508    
509    
510  /*  /*
511     *  sh_update_fpscr():
512     *
513     *  Writes a new value to the floating-point status/control register.
514     */
515    void sh_update_fpscr(struct cpu *cpu, uint32_t new_fpscr)
516    {
517            uint32_t old_fpscr = cpu->cd.sh.fpscr;
518    
519            if ((new_fpscr & SH_FPSCR_FR) != (old_fpscr & SH_FPSCR_FR)) {
520                    int i;
521                    for (i=0; i<SH_N_FPRS; i++) {
522                            uint32_t tmp = cpu->cd.sh.fr[i];
523                            cpu->cd.sh.fr[i] = cpu->cd.sh.xf[i];
524                            cpu->cd.sh.xf[i] = tmp;
525                    }
526            }
527    
528            cpu->cd.sh.fpscr = new_fpscr;
529    }
530    
531    
532    /*
533     *  sh_exception():
534     *
535     *  Causes a transfer of control to an exception or interrupt handler.
536     *  If intevt > 0, then it is an interrupt, otherwise an exception.
537     */
538    void sh_exception(struct cpu *cpu, int expevt, int intevt, uint32_t vaddr)
539    {
540            uint32_t vbr = cpu->cd.sh.vbr;
541    
542            if (!quiet_mode) {
543                    if (intevt > 0)
544                            debug("[ interrupt 0x%03x", intevt);
545                    else
546                            debug("[ exception 0x%03x", expevt);
547    
548                    debug(", pc=0x%08"PRIx32" ", (uint32_t)vaddr);
549                    if (intevt == 0)
550                            debug("vaddr=0x%08"PRIx32" ", vaddr);
551    
552                    debug(" ]\n");
553            }
554    
555            if (cpu->cd.sh.sr & SH_SR_BL) {
556                    fatal("sh_exception(): BL bit already set. TODO\n");
557    
558                    /*  This is actually OK in two cases: a User Break,
559                        or on NMI interrupts if a special flag is set?  */
560                    /*  TODO  */
561    
562                    expevt = EXPEVT_RESET_POWER;
563            }
564    
565            if (cpu->is_halted) {
566                    /*
567                     *  If the exception occurred on a 'sleep' instruction, then let
568                     *  the instruction following the sleep instruction be the one
569                     *  where execution resumes when the interrupt service routine
570                     *  returns.
571                     */
572                    cpu->is_halted = 0;
573                    cpu->pc += sizeof(uint16_t);
574            }
575    
576            if (cpu->delay_slot) {
577                    cpu->delay_slot = EXCEPTION_IN_DELAY_SLOT;
578                    cpu->pc -= sizeof(uint16_t);
579            }
580    
581            /*  Stuff common to all exceptions:  */
582            cpu->cd.sh.spc = cpu->pc;
583            cpu->cd.sh.ssr = cpu->cd.sh.sr;
584            cpu->cd.sh.sgr = cpu->cd.sh.r[15];
585            if (intevt > 0) {
586                    cpu->cd.sh.intevt = intevt;
587                    expevt = -1;
588            } else
589                    cpu->cd.sh.expevt = expevt;
590            sh_update_sr(cpu, cpu->cd.sh.sr | SH_SR_MD | SH_SR_RB | SH_SR_BL);
591    
592            /*  Most exceptions set PC to VBR + 0x100.  */
593            cpu->pc = vbr + 0x100;
594    
595            /*  Specific cases:  */
596            switch (expevt) {
597    
598            case -1:        /*  Interrupt  */
599                    cpu->pc = vbr + 0x600;
600                    break;
601    
602            case EXPEVT_RESET_POWER:
603            case EXPEVT_RESET_MANUAL:
604                    cpu->pc = 0xa0000000;
605                    cpu->cd.sh.vbr = 0x00000000;
606                    sh_update_sr(cpu, (cpu->cd.sh.sr | SH_SR_IMASK) & ~SH_SR_FD);
607                    break;
608    
609            case EXPEVT_TLB_MISS_LD:
610            case EXPEVT_TLB_MISS_ST:
611                    cpu->pc = vbr + 0x400;
612            case EXPEVT_TLB_PROT_LD:
613            case EXPEVT_TLB_PROT_ST:
614            case EXPEVT_TLB_MOD:
615                    cpu->cd.sh.tea = vaddr;
616                    cpu->cd.sh.pteh &= ~SH4_PTEH_VPN_MASK;
617                    cpu->cd.sh.pteh |= (vaddr & SH4_PTEH_VPN_MASK);
618                    break;
619    
620            case EXPEVT_TRAPA:
621                    /*  Note: The TRA register is already set by the
622                        implementation of the trapa instruction. See
623                        cpu_sh_instr.c.  */
624                    cpu->cd.sh.spc += sizeof(uint16_t);
625                    break;
626    
627            default:fatal("sh_exception(): exception 0x%x is not yet "
628                        "implemented.\n", expevt);
629                    exit(1);
630            }
631    
632            sh_pc_to_pointers(cpu);
633    }
634    
635    
636    /*
637   *  sh_cpu_disassemble_instr_compact():   *  sh_cpu_disassemble_instr_compact():
638   *   *
639   *  SHcompact instruction disassembly. The top 4 bits of each 16-bit   *  SHcompact instruction disassembly. The top 4 bits of each 16-bit
# Line 323  int sh_cpu_disassemble_instr_compact(str Line 652  int sh_cpu_disassemble_instr_compact(str
652          else          else
653                  iword = (instr[1] << 8) + instr[0];                  iword = (instr[1] << 8) + instr[0];
654    
655          debug(":  %04x \t", iword);          debug(":  %04x %s\t", iword, cpu->delay_slot? "(d)" : "");
656          hi4 = iword >> 12; lo4 = iword & 15; lo8 = iword & 255;          hi4 = iword >> 12; lo4 = iword & 15; lo8 = iword & 255;
657          r8 = (iword >> 8) & 15; r4 = (iword >> 4) & 15;          r8 = (iword >> 8) & 15; r4 = (iword >> 4) & 15;
658    
# Line 367  int sh_cpu_disassemble_instr_compact(str Line 696  int sh_cpu_disassemble_instr_compact(str
696                          debug("div0u\n");                          debug("div0u\n");
697                  else if (lo8 == 0x1a)                  else if (lo8 == 0x1a)
698                          debug("sts\tmacl,r%i\n", r8);                          debug("sts\tmacl,r%i\n", r8);
699                    else if (iword == 0x001b)
700                            debug("sleep\n");
701                    else if (lo8 == 0x22)
702                            debug("stc\tvbr,r%i\n", r8);
703                  else if (lo8 == 0x23)                  else if (lo8 == 0x23)
704                          debug("braf\tr%i\n", r8);                          debug("braf\tr%i\n", r8);
705                  else if (iword == 0x0028)                  else if (iword == 0x0028)
706                          debug("clrmac\n");                          debug("clrmac\n");
707                  else if (lo8 == 0x29)                  else if (lo8 == 0x29)
708                          debug("movt\tr%i\n", r8);                          debug("movt\tr%i\n", r8);
709                    else if (lo8 == 0x2a)
710                            debug("sts\tpr,r%i\n", r8);
711                    else if (iword == 0x002b)
712                            debug("rte\n");
713                    else if (lo8 == 0x32)
714                            debug("stc\tssr,r%i\n", r8);
715                    else if (iword == 0x0038)
716                            debug("ldtlb\n");
717                  else if (iword == 0x003b)                  else if (iword == 0x003b)
718                          debug("brk\n");                          debug("brk\n");
719                    else if (lo8 == 0x42)
720                            debug("stc\tspc,r%i\n", r8);
721                  else if (iword == 0x0048)                  else if (iword == 0x0048)
722                          debug("clrs\n");                          debug("clrs\n");
723                  else if (iword == 0x0058)                  else if (iword == 0x0058)
724                          debug("sets\n");                          debug("sets\n");
725                    else if (lo8 == 0x5a)
726                            debug("sts\tfpul,r%i\n", r8);
727                    else if (lo8 == 0x6a)
728                            debug("sts\tfpscr,r%i\n", r8);
729                    else if ((lo8 & 0x8f) == 0x82)
730                            debug("stc\tr%i_bank,r%i\n", (lo8 >> 4) & 7, r8);
731                  else if (lo8 == 0x83)                  else if (lo8 == 0x83)
732                          debug("pref\t@r%i\n", r8);                          debug("pref\t@r%i\n", r8);
733                    else if (lo8 == 0x93)
734                            debug("ocbi\t@r%i\n", r8);
735                    else if (lo8 == 0xa3)
736                            debug("ocbp\t@r%i\n", r8);
737                    else if (lo8 == 0xb3)
738                            debug("ocbwb\t@r%i\n", r8);
739                    else if (lo8 == 0xc3)
740                            debug("movca.l\tr0,@r%i\n", r8);
741                    else if (lo8 == 0xfa)
742                            debug("stc\tdbr,r%i\n", r8);
743                    else if (iword == 0x00ff)
744                            debug("gxemul_dreamcast_prom_emul\n");
745                  else                  else
746                          debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);                          debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
747                  break;                  break;
# Line 458  int sh_cpu_disassemble_instr_compact(str Line 819  int sh_cpu_disassemble_instr_compact(str
819                          debug("shll\tr%i\n", r8);                          debug("shll\tr%i\n", r8);
820                  else if (lo8 == 0x01)                  else if (lo8 == 0x01)
821                          debug("shlr\tr%i\n", r8);                          debug("shlr\tr%i\n", r8);
822                    else if (lo8 == 0x02)
823                            debug("sts.l\tmach,@-r%i\n", r8);
824                    else if (lo8 == 0x03)
825                            debug("stc.l\tsr,@-r%i\n", r8);
826                  else if (lo8 == 0x04)                  else if (lo8 == 0x04)
827                          debug("rotl\tr%i\n", r8);                          debug("rotl\tr%i\n", r8);
828                  else if (lo8 == 0x05)                  else if (lo8 == 0x05)
829                          debug("rotr\tr%i\n", r8);                          debug("rotr\tr%i\n", r8);
830                  else if (lo8 == 0x06)                  else if (lo8 == 0x06)
831                          debug("lds.l\t@r%i+,mach\n", r8);                          debug("lds.l\t@r%i+,mach\n", r8);
832                    else if (lo8 == 0x07)
833                            debug("ldc.l\t@r%i+,sr\n", r8);
834                  else if (lo8 == 0x08)                  else if (lo8 == 0x08)
835                          debug("shll2\tr%i\n", r8);                          debug("shll2\tr%i\n", r8);
836                  else if (lo8 == 0x09)                  else if (lo8 == 0x09)
# Line 482  int sh_cpu_disassemble_instr_compact(str Line 849  int sh_cpu_disassemble_instr_compact(str
849                          debug("dt\tr%i\n", r8);                          debug("dt\tr%i\n", r8);
850                  else if (lo8 == 0x11)                  else if (lo8 == 0x11)
851                          debug("cmp/pz\tr%i\n", r8);                          debug("cmp/pz\tr%i\n", r8);
852                    else if (lo8 == 0x12)
853                            debug("sts.l\tmacl,@-r%i\n", r8);
854                    else if (lo8 == 0x13)
855                            debug("stc.l\tgbr,@-r%i\n", r8);
856                  else if (lo8 == 0x15)                  else if (lo8 == 0x15)
857                          debug("cmp/pl\tr%i\n", r8);                          debug("cmp/pl\tr%i\n", r8);
858                  else if (lo8 == 0x16)                  else if (lo8 == 0x16)
859                          debug("lds.l\t@r%i+,macl\n", r8);                          debug("lds.l\t@r%i+,macl\n", r8);
860                    else if (lo8 == 0x17)
861                            debug("ldc.l\t@r%i+,gbr\n", r8);
862                  else if (lo8 == 0x18)                  else if (lo8 == 0x18)
863                          debug("shll8\tr%i\n", r8);                          debug("shll8\tr%i\n", r8);
864                  else if (lo8 == 0x19)                  else if (lo8 == 0x19)
# Line 502  int sh_cpu_disassemble_instr_compact(str Line 875  int sh_cpu_disassemble_instr_compact(str
875                          debug("shar\tr%i\n", r8);                          debug("shar\tr%i\n", r8);
876                  else if (lo8 == 0x22)                  else if (lo8 == 0x22)
877                          debug("sts.l\tpr,@-r%i\n", r8);                          debug("sts.l\tpr,@-r%i\n", r8);
878                    else if (lo8 == 0x23)
879                            debug("stc.l\tvbr,@-r%i\n", r8);
880                  else if (lo8 == 0x24)                  else if (lo8 == 0x24)
881                          debug("rotcl\tr%i\n", r8);                          debug("rotcl\tr%i\n", r8);
882                  else if (lo8 == 0x25)                  else if (lo8 == 0x25)
883                          debug("rotcr\tr%i\n", r8);                          debug("rotcr\tr%i\n", r8);
884                  else if (lo8 == 0x26)                  else if (lo8 == 0x26)
885                          debug("lds.l\t@r%i+,pr\n", r8);                          debug("lds.l\t@r%i+,pr\n", r8);
886                    else if (lo8 == 0x27)
887                            debug("ldc.l\t@r%i+,vbr\n", r8);
888                  else if (lo8 == 0x28)                  else if (lo8 == 0x28)
889                          debug("shll16\tr%i\n", r8);                          debug("shll16\tr%i\n", r8);
890                  else if (lo8 == 0x29)                  else if (lo8 == 0x29)
# Line 516  int sh_cpu_disassemble_instr_compact(str Line 893  int sh_cpu_disassemble_instr_compact(str
893                          debug("lds\tr%i,pr\n", r8);                          debug("lds\tr%i,pr\n", r8);
894                  else if (lo8 == 0x2b)                  else if (lo8 == 0x2b)
895                          debug("jmp\t@r%i\n", r8);                          debug("jmp\t@r%i\n", r8);
896                    else if (lo8 == 0x2e)
897                            debug("ldc\tr%i,vbr\n", r8);
898                    else if (lo8 == 0x33)
899                            debug("stc.l\tssr,@-r%i\n", r8);
900                    else if (lo8 == 0x37)
901                            debug("ldc.l\t@r%i+,ssr\n", r8);
902                    else if (lo8 == 0x3e)
903                            debug("ldc\tr%i,ssr\n", r8);
904                    else if (lo8 == 0x43)
905                            debug("stc.l\tspc,@-r%i\n", r8);
906                    else if (lo8 == 0x47)
907                            debug("ldc.l\t@r%i+,spc\n", r8);
908                    else if (lo8 == 0x4e)
909                            debug("ldc\tr%i,spc\n", r8);
910                    else if (lo8 == 0x52)
911                            debug("sts.l\tfpul,@-r%i\n", r8);
912                  else if (lo8 == 0x56)                  else if (lo8 == 0x56)
913                          debug("lds.l\t@r%i+,fpul\n", r8);                          debug("lds.l\t@r%i+,fpul\n", r8);
914                  else if (lo8 == 0x5a)                  else if (lo8 == 0x5a)
915                          debug("lds\tr%i,fpul\n", r8);                          debug("lds\tr%i,fpul\n", r8);
916                    else if (lo8 == 0x62)
917                            debug("sts.l\tfpscr,@-r%i\n", r8);
918                    else if (lo8 == 0x66)
919                            debug("lds.l\t@r%i+,fpscr\n", r8);
920                  else if (lo8 == 0x6a)                  else if (lo8 == 0x6a)
921                          debug("lds\tr%i,fpscr\n", r8);                          debug("lds\tr%i,fpscr\n", r8);
922                    else if ((lo8 & 0x8f) == 0x83)
923                            debug("stc.l\tr%i_bank,@-r%i\n", (lo8 >> 4) & 7, r8);
924                    else if ((lo8 & 0x8f) == 0x87)
925                            debug("ldc.l\t@r%i,r%i_bank\n", r8, (lo8 >> 4) & 7, r8);
926                    else if ((lo8 & 0x8f) == 0x8e)
927                            debug("ldc\tr%i,r%i_bank\n", r8, (lo8 >> 4) & 7);
928                    else if (lo8 == 0xfa)
929                            debug("ldc\tr%i,dbr\n", r8);
930                  else                  else
931                          debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);                          debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
932                  break;                  break;
# Line 539  int sh_cpu_disassemble_instr_compact(str Line 944  int sh_cpu_disassemble_instr_compact(str
944                          debug("mov\tr%i,r%i\n", r4, r8);                          debug("mov\tr%i,r%i\n", r4, r8);
945                  else if (lo4 == 0x4)                  else if (lo4 == 0x4)
946                          debug("mov.b\t@r%i+,r%i\n", r4, r8);                          debug("mov.b\t@r%i+,r%i\n", r4, r8);
947                    else if (lo4 == 0x5)
948                            debug("mov.w\t@r%i+,r%i\n", r4, r8);
949                  else if (lo4 == 0x6)                  else if (lo4 == 0x6)
950                          debug("mov.l\t@r%i+,r%i\n", r4, r8);                          debug("mov.l\t@r%i+,r%i\n", r4, r8);
951                  else if (lo4 == 0x7)                  else if (lo4 == 0x7)
# Line 566  int sh_cpu_disassemble_instr_compact(str Line 973  int sh_cpu_disassemble_instr_compact(str
973                  debug("add\t#%i,r%i\n", (int8_t)lo8, r8);                  debug("add\t#%i,r%i\n", (int8_t)lo8, r8);
974                  break;                  break;
975          case 0x8:          case 0x8:
976                  if (r8 == 0x8)                  if (r8 == 0x0) {
977                            debug("mov.b\tr0,@(%i,r%i)\n", lo4, r4);
978                    } else if (r8 == 0x1) {
979                            debug("mov.w\tr0,@(%i,r%i)\n", lo4 * 2, r4);
980                    } else if (r8 == 0x4) {
981                            debug("mov.b\t@(%i,r%i),r0\n", lo4, r4);
982                    } else if (r8 == 0x5) {
983                            debug("mov.w\t@(%i,r%i),r0\n", lo4 * 2, r4);
984                    } else if (r8 == 0x8) {
985                          debug("cmp/eq\t#%i,r0\n", (int8_t)lo8);                          debug("cmp/eq\t#%i,r0\n", (int8_t)lo8);
986                  else if (r8 == 0x9 || r8 == 0xb || r8 == 0xd || r8 == 0xf) {                  } else if (r8 == 0x9 || r8 == 0xb || r8 == 0xd || r8 == 0xf) {
987                          addr = (int8_t)lo8;                          addr = (int8_t)lo8;
988                          addr = dumpaddr + 4 + (addr << 1);                          addr = dumpaddr + 4 + (addr << 1);
989                          debug("b%s%s\t0x%x\n",                          debug("b%s%s\t0x%x\n",
# Line 591  int sh_cpu_disassemble_instr_compact(str Line 1006  int sh_cpu_disassemble_instr_compact(str
1006                  debug("%s\t0x%x\n", hi4==0xa? "bra":"bsr", (int)addr);                  debug("%s\t0x%x\n", hi4==0xa? "bra":"bsr", (int)addr);
1007                  break;                  break;
1008          case 0xc:          case 0xc:
1009                  if (r8 == 0x3)                  if (r8 == 0x0)
1010                            debug("mov.b\tr0,@(%i,gbr)\n", lo8);
1011                    else if (r8 == 0x1)
1012                            debug("mov.w\tr0,@(%i,gbr)\n", lo8 * 2);
1013                    else if (r8 == 0x2)
1014                            debug("mov.l\tr0,@(%i,gbr)\n", lo8 * 4);
1015                    else if (r8 == 0x3)
1016                          debug("trapa\t#%i\n", (uint8_t)lo8);                          debug("trapa\t#%i\n", (uint8_t)lo8);
1017                  else if (r8 == 0x8)                  else if (r8 == 0x4)
1018                            debug("mov.b\t(%i,gbr),r0\n", lo8);
1019                    else if (r8 == 0x5)
1020                            debug("mov.w\t(%i,gbr),r0\n", lo8 * 2);
1021                    else if (r8 == 0x6)
1022                            debug("mov.l\t(%i,gbr),r0\n", lo8 * 4);
1023                    else if (r8 == 0x7) {
1024                            addr = lo8 * 4 + (dumpaddr & ~3) + 4;
1025                            debug("mova\t0x%x,r0\n", (int)addr);
1026                    } else if (r8 == 0x8)
1027                          debug("tst\t#%i,r0\n", (uint8_t)lo8);                          debug("tst\t#%i,r0\n", (uint8_t)lo8);
1028                  else if (r8 == 0x9)                  else if (r8 == 0x9)
1029                          debug("and\t#%i,r0\n", (uint8_t)lo8);                          debug("and\t#%i,r0\n", (uint8_t)lo8);
# Line 615  int sh_cpu_disassemble_instr_compact(str Line 1045  int sh_cpu_disassemble_instr_compact(str
1045          case 0xe:          case 0xe:
1046                  debug("mov\t#%i,r%i\n", (int8_t)lo8, r8);                  debug("mov\t#%i,r%i\n", (int8_t)lo8, r8);
1047                  break;                  break;
1048            case 0xf:
1049                    if (lo4 == 0x0)
1050                            debug("fadd\t%sr%i,%sr%i\n",
1051                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1052                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1053                    else if (lo4 == 0x1)
1054                            debug("fsub\t%sr%i,%sr%i\n",
1055                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1056                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1057                    else if (lo4 == 0x2)
1058                            debug("fmul\t%sr%i,%sr%i\n",
1059                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1060                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1061                    else if (lo4 == 0x3)
1062                            debug("fdiv\t%sr%i,%sr%i\n",
1063                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1064                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1065                    else if (lo4 == 0x4)
1066                            debug("fcmp/eq\t%sr%i,%sr%i\n",
1067                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1068                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1069                    else if (lo4 == 0x5)
1070                            debug("fcmp/gt\t%sr%i,%sr%i\n",
1071                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1072                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1073                    else if (lo4 == 0x6) {
1074                            char *n = "fr";
1075                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1076                                    n = (r8 & 1)? "xd" : "dr";
1077                                    r8 &= ~1;
1078                            }
1079                            debug("fmov\t@(r0,r%i),%s%i\n", r4, n, r8);
1080                    } else if (lo4 == 0x7) {
1081                            char *n = "fr";
1082                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1083                                    n = (r4 & 1)? "xd" : "dr";
1084                                    r4 &= ~1;
1085                            }
1086                            debug("fmov\t%s%i,@(r0,r%i)\n", n, r4, r8);
1087                    } else if (lo4 == 0x8) {
1088                            char *n = "fr";
1089                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1090                                    n = (r8 & 1)? "xd" : "dr";
1091                                    r8 &= ~1;
1092                            }
1093                            debug("fmov\t@r%i,%s%i\n", r4, n, r8);
1094                    } else if (lo4 == 0x9) {
1095                            char *n = "fr";
1096                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1097                                    n = (r8 & 1)? "xd" : "dr";
1098                                    r8 &= ~1;
1099                            }
1100                            debug("fmov\t@r%i+,%s%i\n", r4, n, r8);
1101                    } else if (lo4 == 0xa) {
1102                            char *n = "fr";
1103                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1104                                    n = (r4 & 1)? "xd" : "dr";
1105                                    r4 &= ~1;
1106                            }
1107                            debug("fmov\t%s%i,@r%i\n", n, r4, r8);
1108                    } else if (lo4 == 0xb) {
1109                            char *n = "fr";
1110                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1111                                    n = (r4 & 1)? "xd" : "dr";
1112                                    r4 &= ~1;
1113                            }
1114                            debug("fmov\t%s%i,@-r%i\n", n, r4, r8);
1115                    } else if (lo4 == 0xc) {
1116                            char *n1 = "fr", *n2 = "fr";
1117                            if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1118                                    n1 = (r4 & 1)? "xd" : "dr";
1119                                    n2 = (r8 & 1)? "xd" : "dr";
1120                                    r4 &= ~1; r8 &= ~1;
1121                            }
1122                            debug("fmov\t%s%i,%s%i\n", n1, r4, n2, r8);
1123                    } else if (lo8 == 0x0d)
1124                            debug("fsts\tfpul,fr%i\n", r8);
1125                    else if (lo8 == 0x1d)
1126                            debug("flds\tfr%i,fpul\n", r8);
1127                    else if (lo8 == 0x2d)
1128                            debug("float\tfpul,%sr%i\n",
1129                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1130                    else if (lo8 == 0x3d)
1131                            debug("ftrc\t%sr%i,fpul\n",
1132                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1133                    else if (lo8 == 0x4d)
1134                            debug("fneg\t%sr%i\n",
1135                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1136                    else if (lo8 == 0x5d)
1137                            debug("fabs\t%sr%i\n",
1138                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1139                    else if (lo8 == 0x6d)
1140                            debug("fsqrt\t%sr%i\n",
1141                                cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1142                    else if (lo8 == 0x8d)
1143                            debug("fldi0\tfr%i\n", r8);
1144                    else if (lo8 == 0x9d)
1145                            debug("fldi1\tfr%i\n", r8);
1146                    else if ((iword & 0x01ff) == 0x00fd)
1147                            debug("fsca\tfpul,dr%i\n", r8);
1148                    else if (iword == 0xf3fd)
1149                            debug("fschg\n");
1150                    else if (iword == 0xfbfd)
1151                            debug("frchg\n");
1152                    else if ((iword & 0xf3ff) == 0xf1fd)
1153                            debug("ftrv\txmtrx,fv%i\n", r8 & 0xc);
1154                    else if (lo4 == 0xe)
1155                            debug("fmac\tfr0,fr%i,fr%i\n", r4, r8);
1156                    else
1157                            debug("UNIMPLEMENTED hi4=0x%x,0x%x\n", hi4, lo8);
1158                    break;
1159          default:debug("UNIMPLEMENTED hi4=0x%x\n", hi4);          default:debug("UNIMPLEMENTED hi4=0x%x\n", hi4);
1160          }          }
1161    

Legend:
Removed from v.30  
changed lines
  Added in v.32

  ViewVC Help
Powered by ViewVC 1.1.26