cpu_mips.cc Source File

Back to the index.

cpu_mips.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003-2019 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *
28  * MIPS core CPU emulation.
29  */
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/types.h>
35 #include <ctype.h>
36 #include <unistd.h>
37 
38 #include "../../config.h"
39 
40 #include "arcbios.h"
41 #include "cop0.h"
42 #include "cpu.h"
43 #include "cpu_mips.h"
44 #include "debugger.h"
45 #include "devices.h"
46 #include "emul.h"
47 #include "machine.h"
48 #include "memory.h"
49 #include "mips_cpu_types.h"
50 #include "opcodes_mips.h"
51 #include "settings.h"
52 #include "symbol.h"
53 
54 
55 static const char *exception_names[] = EXCEPTION_NAMES;
56 
57 static const char *hi6_names[] = HI6_NAMES;
58 static const char *regimm_names[] = REGIMM_NAMES;
59 static const char *special_names[] = SPECIAL_NAMES;
60 static const char *special_rot_names[] = SPECIAL_ROT_NAMES;
61 static const char *special2_names[] = SPECIAL2_NAMES;
62 static const char *mmi_names[] = MMI_NAMES;
63 static const char *mmi0_names[] = MMI0_NAMES;
64 static const char *mmi1_names[] = MMI1_NAMES;
65 static const char *mmi2_names[] = MMI2_NAMES;
66 static const char *mmi3_names[] = MMI3_NAMES;
67 static const char *special3_names[] = SPECIAL3_NAMES;
68 
69 static const char *regnames[] = MIPS_REGISTER_NAMES;
70 static const char *cop0_names[] = COP0_NAMES;
71 
72 
73 #define DYNTRANS_DUALMODE_32
74 #define DYNTRANS_DELAYSLOT
75 #include "tmp_mips_head.cc"
76 
77 void mips_pc_to_pointers(struct cpu *);
78 void mips32_pc_to_pointers(struct cpu *);
79 
80 
81 /*
82  * mips_cpu_new():
83  *
84  * Create a new MIPS cpu object.
85  *
86  * Returns 1 on success, 0 if there was no valid MIPS processor with
87  * a matching name.
88  */
89 int mips_cpu_new(struct cpu *cpu, struct memory *mem, struct machine *machine,
90  int cpu_id, char *cpu_type_name)
91 {
92  int i, found, j, tags_size, n_cache_lines, size_per_cache_line;
93  struct mips_cpu_type_def cpu_type_defs[] = MIPS_CPU_TYPE_DEFS;
94  int64_t secondary_cache_size;
95  int x, linesize;
96 
97  /* Scan the cpu_type_defs list for this cpu type: */
98  i = 0;
99  found = -1;
100  while (i >= 0 && cpu_type_defs[i].name != NULL) {
101  if (strcasecmp(cpu_type_defs[i].name, cpu_type_name) == 0) {
102  found = i;
103  break;
104  }
105  i++;
106  }
107 
108  if (found == -1)
109  return 0;
110 
112  cpu->cd.mips.cpu_type = cpu_type_defs[found];
113  cpu->name = strdup(cpu->cd.mips.cpu_type.name);
116 
117  if (cpu->cd.mips.cpu_type.isa_level <= 2 ||
118  cpu->cd.mips.cpu_type.isa_level == 32)
119  cpu->is_32bit = 1;
120 
121  if (cpu->is_32bit) {
128  } else {
135  }
136 
138 
139  if (cpu_id == 0)
140  debug("%s", cpu->cd.mips.cpu_type.name);
141 
142  /*
143  * CACHES:
144  *
145  * 1) Use DEFAULT_PCACHE_SIZE and DEFAULT_PCACHE_LINESIZE etc.
146  * 2) If there are specific values defined for this type of cpu,
147  * in its cpu_type substruct, then let's use those.
148  * 3) Values in the emul struct override both of the above.
149  *
150  * Once we've decided which values to use, they are stored in
151  * the emul struct so they can be used from src/machine.c etc.
152  */
153 
155  if (cpu->cd.mips.cpu_type.pdcache)
156  x = cpu->cd.mips.cpu_type.pdcache;
157  if (cpu->cd.mips.cache_pdcache == 0)
158  cpu->cd.mips.cache_pdcache = x;
159 
161  if (cpu->cd.mips.cpu_type.picache)
162  x = cpu->cd.mips.cpu_type.picache;
163  if (cpu->cd.mips.cache_picache == 0)
164  cpu->cd.mips.cache_picache = x;
165 
166  if (cpu->cd.mips.cache_secondary == 0)
168 
169  linesize = DEFAULT_PCACHE_LINESIZE;
171  linesize = cpu->cd.mips.cpu_type.pdlinesize;
172  if (cpu->cd.mips.cache_pdcache_linesize == 0)
173  cpu->cd.mips.cache_pdcache_linesize = linesize;
174 
175  linesize = DEFAULT_PCACHE_LINESIZE;
177  linesize = cpu->cd.mips.cpu_type.pilinesize;
178  if (cpu->cd.mips.cache_picache_linesize == 0)
179  cpu->cd.mips.cache_picache_linesize = linesize;
180 
181  linesize = 0;
183  linesize = cpu->cd.mips.cpu_type.slinesize;
185  cpu->cd.mips.cache_secondary_linesize = linesize;
186 
187 
188  /*
189  * Primary Data and Instruction caches:
190  */
191  for (i=CACHE_DATA; i<=CACHE_INSTRUCTION; i++) {
192  switch (i) {
193  case CACHE_DATA:
194  x = 1 << cpu->cd.mips.cache_pdcache;
195  linesize = 1 << cpu->cd.mips.cache_pdcache_linesize;
196  break;
197  case CACHE_INSTRUCTION:
198  x = 1 << cpu->cd.mips.cache_picache;
199  linesize = 1 << cpu->cd.mips.cache_picache_linesize;
200  break;
201  }
202 
203  /* Primary cache size and linesize: */
204  cpu->cd.mips.cache_size[i] = x;
205  cpu->cd.mips.cache_linesize[i] = linesize;
206 
207  switch (cpu->cd.mips.cpu_type.rev) {
208  case MIPS_R2000:
209  case MIPS_R3000:
210  size_per_cache_line = sizeof(struct r3000_cache_line);
211  break;
212  default:
213  size_per_cache_line = 32; /* TODO */
214  }
215 
216  cpu->cd.mips.cache_mask[i] = cpu->cd.mips.cache_size[i] - 1;
217 
218  CHECK_ALLOCATION(cpu->cd.mips.cache[i] = (unsigned char *)
219  malloc(cpu->cd.mips.cache_size[i]));
220 
221  n_cache_lines = cpu->cd.mips.cache_size[i] /
223  tags_size = n_cache_lines * size_per_cache_line;
224 
226  malloc(tags_size));
227 
228  /* Initialize the cache tags: */
229  switch (cpu->cd.mips.cpu_type.rev) {
230  case MIPS_R2000:
231  case MIPS_R3000:
232  for (j=0; j<n_cache_lines; j++) {
233  struct r3000_cache_line *rp;
234  rp = (struct r3000_cache_line *)
235  cpu->cd.mips.cache_tags[i];
236  rp[j].tag_paddr = 0;
237  rp[j].tag_valid = 0;
238  }
239  break;
240  default:
241  ;
242  }
243 
244  /* Set cache_last_paddr to something "impossible": */
246  }
247 
248  /*
249  * Secondary cache:
250  */
251  secondary_cache_size = 0;
252  if (cpu->cd.mips.cache_secondary)
253  secondary_cache_size = 1 << cpu->cd.mips.cache_secondary;
254  /* TODO: linesize... */
255 
256  if (cpu_id == 0) {
257  debug(" (I+D = %i+%i KB",
258  (int)(cpu->cd.mips.cache_size[CACHE_INSTRUCTION] / 1024),
259  (int)(cpu->cd.mips.cache_size[CACHE_DATA] / 1024));
260 
261  if (secondary_cache_size != 0) {
262  debug(", L2 = ");
263  if (secondary_cache_size >= 1048576)
264  debug("%i MB", (int)
265  (secondary_cache_size / 1048576));
266  else
267  debug("%i KB", (int)
268  (secondary_cache_size / 1024));
269  }
270 
271  debug(")");
272  }
273 
274  /* Register the CPU's interrupts: */
275  for (i=2; i<8; i++) {
276  struct interrupt templ;
277  char name[50];
278  snprintf(name, sizeof(name), "%s.%i", cpu->path, i);
279  memset(&templ, 0, sizeof(templ));
280  templ.line = 1 << (STATUS_IM_SHIFT + i);
281  templ.name = name;
282  templ.extra = cpu;
286 
287  if (i == 7)
289  }
290 
291  /* System coprocessor (0), and FPU (1): */
292  cpu->cd.mips.coproc[0] = mips_coproc_new(cpu, 0);
293  cpu->cd.mips.coproc[1] = mips_coproc_new(cpu, 1);
294 
295  switch (cpu->cd.mips.cpu_type.mmu_model) {
296  case MMU3K:
297  cpu->vaddr_mask = 0x00000000ffffffffULL;
299  break;
300  case MMU8K:
302  break;
303  case MMU10K:
306  break;
307  default:
308  if (cpu->is_32bit)
309  cpu->vaddr_mask = 0x00000000ffffffffULL;
310  else
312 
313  if (cpu->cd.mips.cpu_type.rev == MIPS_R4100)
315  else
317  }
318 
319  // TODO: Consider moving to src/machine/machine_test.cc?
320  // This is only here to make the floating point tests work out-of-the-box.
321  if (!cpu->is_32bit)
323 
324  if (cpu->machine->prom_emulation) {
325  /*
326  * Default behaviour of jumping to 0xbfc00000 should be
327  * a reboot, unless machine-specific initialization code
328  * overrides this.
329  *
330  * Note: Specifically big-endian machines should override
331  * this, since the default MIPS CPU is little-endian!
332  */
333  store_32bit_word(cpu, 0xffffffff9fc00000ULL, 0x00c0de0d);
334  }
335 
336  /* Add all register names to the settings: */
340  for (i=0; i<N_MIPS_GPRS; i++)
341  CPU_SETTINGS_ADD_REGISTER64(regnames[i], cpu->cd.mips.gpr[i]);
342  /* TODO: Write via special handler function! */
343  for (i=0; i<N_MIPS_COPROC_REGS; i++)
344  CPU_SETTINGS_ADD_REGISTER64(cop0_names[i],
345  cpu->cd.mips.coproc[0]->reg[i]);
346 
347  return 1;
348 }
349 
350 
351 /*
352  * mips_cpu_dumpinfo():
353  *
354  * Debug dump of MIPS-specific CPU data for specific CPU.
355  */
356 void mips_cpu_dumpinfo(struct cpu *cpu)
357 {
358  int iadd = DEBUG_INDENTATION;
359  struct mips_cpu_type_def *ct = &cpu->cd.mips.cpu_type;
360 
361  debug_indentation(iadd);
362 
363  debug("\n%i-bit %s-endian (MIPS",
364  cpu->is_32bit? 32 : 64,
365  cpu->byte_order == EMUL_BIG_ENDIAN? "Big" : "Little");
366 
367  switch (ct->isa_level) {
368  case 1: debug(" ISA I"); break;
369  case 2: debug(" ISA II"); break;
370  case 3: debug(" ISA III"); break;
371  case 4: debug(" ISA IV"); break;
372  case 5: debug(" ISA V"); break;
373  case 32:
374  case 64:debug("%i, revision %i", ct->isa_level, ct->isa_revision);
375  break;
376  default:debug(" ISA level %i", ct->isa_level);
377  }
378 
379  debug("), ");
380  if (ct->nr_of_tlb_entries)
381  debug("%i TLB entries", ct->nr_of_tlb_entries);
382  else
383  debug("no TLB");
384  debug("\n");
385 
386  if (ct->picache) {
387  debug("L1 I-cache: %i KB", (1 << ct->picache) / 1024);
388  if (ct->pilinesize)
389  debug(", %i bytes per line", 1 << ct->pilinesize);
390  if (ct->piways > 1)
391  debug(", %i-way", ct->piways);
392  else
393  debug(", direct-mapped");
394  debug("\n");
395  }
396 
397  if (ct->pdcache) {
398  debug("L1 D-cache: %i KB", (1 << ct->pdcache) / 1024);
399  if (ct->pdlinesize)
400  debug(", %i bytes per line", 1 << ct->pdlinesize);
401  if (ct->pdways > 1)
402  debug(", %i-way", ct->pdways);
403  else
404  debug(", direct-mapped");
405  debug("\n");
406  }
407 
408  if (ct->scache) {
409  int kb = (1 << ct->scache) / 1024;
410  debug("L2 cache: %i %s",
411  kb >= 1024? kb / 1024 : kb, kb >= 1024? "MB":"KB");
412  if (ct->slinesize)
413  debug(", %i bytes per line", 1 << ct->slinesize);
414  if (ct->sways > 1)
415  debug(", %i-way", ct->sways);
416  else
417  debug(", direct-mapped");
418  debug("\n");
419  }
420 
421  debug_indentation(-iadd);
422 }
423 
424 
425 /*
426  * mips_cpu_list_available_types():
427  *
428  * Print a list of available MIPS CPU types.
429  */
431 {
432  int i, j;
433  struct mips_cpu_type_def cpu_type_defs[] = MIPS_CPU_TYPE_DEFS;
434 
435  i = 0;
436  while (cpu_type_defs[i].name != NULL) {
437  debug("%s", cpu_type_defs[i].name);
438  for (j=10 - strlen(cpu_type_defs[i].name); j>0; j--)
439  debug(" ");
440  i++;
441  if ((i % 6) == 0 || cpu_type_defs[i].name == NULL)
442  debug("\n");
443  }
444 }
445 
446 
447 /*
448  * mips_cpu_instruction_has_delayslot():
449  *
450  * Return 1 if an opcode is a branch, 0 otherwise.
451  */
452 int mips_cpu_instruction_has_delayslot(struct cpu *cpu, unsigned char *ib)
453 {
454  uint32_t iword = *((uint32_t *)&ib[0]);
455 
457  iword = LE32_TO_HOST(iword);
458  else
459  iword = BE32_TO_HOST(iword);
460 
461  switch (iword >> 26) {
462  case HI6_SPECIAL:
463  switch (iword & 0x3f) {
464  case SPECIAL_JR:
465  case SPECIAL_JALR:
466  return 1;
467  }
468  break;
469  case HI6_REGIMM:
470  switch ((iword >> 16) & 0x1f) {
471  case REGIMM_BLTZ:
472  case REGIMM_BGEZ:
473  case REGIMM_BLTZL:
474  case REGIMM_BGEZL:
475  case REGIMM_BLTZAL:
476  case REGIMM_BLTZALL:
477  case REGIMM_BGEZAL:
478  case REGIMM_BGEZALL:
479  return 1;
480  }
481  break;
482  case HI6_BEQ:
483  case HI6_BEQL:
484  case HI6_BNE:
485  case HI6_BNEL:
486  case HI6_BGTZ:
487  case HI6_BGTZL:
488  case HI6_BLEZ:
489  case HI6_BLEZL:
490  case HI6_J:
491  case HI6_JAL:
492  return 1;
493  }
494 
495  return 0;
496 }
497 
498 
499 /*
500  * mips_cpu_tlbdump():
501  *
502  * Called from the debugger to dump the TLB in a readable format.
503  * x is the cpu number to dump, or -1 to dump all CPUs.
504  *
505  * If rawflag is nonzero, then the TLB contents isn't formated nicely,
506  * just dumped.
507  */
508 void mips_cpu_tlbdump(struct machine *m, int x, int rawflag)
509 {
510  int i, j;
511 
512  /* Raw output: */
513  if (rawflag) {
514  for (i=0; i<m->ncpus; i++) {
515  struct mips_coproc *cop0 =
516  m->cpus[i]->cd.mips.coproc[0];
517 
518  if (x >= 0 && i != x)
519  continue;
520 
521  /* Print index, random, and wired: */
522  printf("cpu%i: (", i);
523 
524  if (m->cpus[i]->is_32bit)
525  printf("index=0x%08x random=0x%08x",
526  (int) cop0->reg[COP0_INDEX],
527  (int) cop0->reg[COP0_RANDOM]);
528  else
529  printf("index=0x%016" PRIx64
530  " random=0x%016" PRIx64,
531  (uint64_t) cop0->reg[COP0_INDEX],
532  (uint64_t) cop0->reg[COP0_RANDOM]);
533 
534  if (m->cpus[i]->cd.mips.cpu_type.isa_level >= 3)
535  printf(" wired=0x%" PRIx64,
536  (uint64_t) cop0->reg[COP0_WIRED]);
537 
538  printf(")\n");
539 
540  for (j=0; j<m->cpus[i]->cd.mips.cpu_type.
541  nr_of_tlb_entries; j++) {
542  if (m->cpus[i]->cd.mips.cpu_type.mmu_model ==
543  MMU3K)
544  printf(" %02x: hi=0x%08" PRIx32" lo=0x%08"
545  PRIx32"\n", j,
546  (uint32_t) cop0->tlbs[j].hi,
547  (uint32_t) cop0->tlbs[j].lo0);
548  else if (m->cpus[i]->is_32bit)
549  printf(" %02x: hi=0x%08" PRIx32" mask=0x"
550  "%08" PRIx32" lo0=0x%08" PRIx32
551  " lo1=0x%08" PRIx32"\n", j,
552  (uint32_t) cop0->tlbs[j].hi,
553  (uint32_t) cop0->tlbs[j].mask,
554  (uint32_t) cop0->tlbs[j].lo0,
555  (uint32_t) cop0->tlbs[j].lo1);
556  else
557  printf(" %02x: hi=0x%016" PRIx64" mask="
558  "0x%016" PRIx64" lo0=0x%016" PRIx64
559  " lo1=0x%016" PRIx64"\n", j,
560  (uint64_t) cop0->tlbs[j].hi,
561  (uint64_t) cop0->tlbs[j].mask,
562  (uint64_t) cop0->tlbs[j].lo0,
563  (uint64_t) cop0->tlbs[j].lo1);
564  }
565  }
566 
567  return;
568  }
569 
570  /* Nicely formatted output: */
571  for (i=0; i<m->ncpus; i++) {
572  int pageshift = 12;
573  struct mips_coproc *cop0 = m->cpus[i]->cd.mips.coproc[0];
574 
575  if (x >= 0 && i != x)
576  continue;
577 
578  if (m->cpus[i]->cd.mips.cpu_type.rev == MIPS_R4100)
579  pageshift = 10;
580 
581  /* Print index, random, and wired: */
582  printf("cpu%i: (", i);
583  switch (m->cpus[i]->cd.mips.cpu_type.isa_level) {
584  case 1:
585  case 2: printf("index=0x%x random=0x%x",
586  (int) ((cop0->reg[COP0_INDEX] & R2K3K_INDEX_MASK)
587  >> R2K3K_INDEX_SHIFT),
588  (int) ((cop0->reg[COP0_RANDOM] & R2K3K_RANDOM_MASK)
589  >> R2K3K_RANDOM_SHIFT));
590  break;
591  default:printf("index=0x%x random=0x%x",
592  (int) (cop0->reg[COP0_INDEX] & INDEX_MASK),
593  (int) (cop0->reg[COP0_RANDOM] & RANDOM_MASK));
594  printf(" wired=0x%" PRIx64,
595  (uint64_t) cop0->reg[COP0_WIRED]);
596  }
597 
598  printf(")\n");
599 
600  for (j=0; j<m->cpus[i]->cd.mips.cpu_type.
601  nr_of_tlb_entries; j++) {
602  uint64_t hi = cop0->tlbs[j].hi;
603  uint64_t lo0 = cop0->tlbs[j].lo0;
604  uint64_t lo1 = cop0->tlbs[j].lo1;
605  uint64_t mask = cop0->tlbs[j].mask;
606  uint64_t psize;
607 
608  mask |= (1 << (pageshift+1)) - 1;
609  /* here mask = e.g. 0x1fff for 4KB pages */
610 
611  printf(" %02x: ", j);
612 
613  switch (m->cpus[i]->cd.mips.cpu_type.mmu_model) {
614  case MMU3K:
615  if (!(lo0 & R2K3K_ENTRYLO_V)) {
616  printf("(invalid)\n");
617  continue;
618  }
619  printf("vaddr=0x%08x ",
620  (int) (hi&R2K3K_ENTRYHI_VPN_MASK));
621  if (lo0 & R2K3K_ENTRYLO_G)
622  printf("(global), ");
623  else
624  printf("(asid %02x),", (int) ((hi &
627  printf(" paddr=0x%08x ",
628  (int) (lo0&R2K3K_ENTRYLO_PFN_MASK));
629  if (lo0 & R2K3K_ENTRYLO_N)
630  printf("N");
631  if (lo0 & R2K3K_ENTRYLO_D)
632  printf("D");
633  printf("\n");
634  break;
635  default:switch (m->cpus[i]->cd.mips.cpu_type.mmu_model){
636  case MMU32:
637  printf("vaddr=0x%08" PRIx32" ",
638  (uint32_t) (hi & ~mask));
639  break;
640  default:/* R4x00, R1x000, MIPS64, etc. */
641  printf("vaddr=%016" PRIx64" ",
642  (uint64_t) (hi & ~mask));
643  }
644  if (hi & TLB_G)
645  printf("(global): ");
646  else
647  printf("(asid %02x):",
648  (int) (hi & ENTRYHI_ASID));
649 
650  /* TODO: Coherency bits */
651 
652  if (!(lo0 & ENTRYLO_V))
653  printf(" p0=(invalid) ");
654  else {
655  uint64_t paddr = lo0 & ENTRYLO_PFN_MASK;
656  paddr >>= ENTRYLO_PFN_SHIFT;
657  paddr <<= pageshift;
658  paddr &= ~(mask >> 1);
659  printf(" p0=0x%09" PRIx64" ",
660  (uint64_t) paddr);
661  }
662  printf(lo0 & ENTRYLO_D? "D" : " ");
663 
664  if (!(lo1 & ENTRYLO_V))
665  printf(" p1=(invalid) ");
666  else {
667  uint64_t paddr = lo1 & ENTRYLO_PFN_MASK;
668  paddr >>= ENTRYLO_PFN_SHIFT;
669  paddr <<= pageshift;
670  paddr &= ~(mask >> 1);
671  printf(" p1=0x%09" PRIx64" ",
672  (uint64_t) paddr);
673  }
674  printf(lo1 & ENTRYLO_D? "D" : " ");
675 
676  /* convert e.g. 0x1fff to 4096 */
677  psize = (mask + 1) >> 1;
678 
679  if (psize >= 1024 && psize <= 256*1024)
680  printf(" (%iKB)", (int) (psize >> 10));
681  else if (psize >= 1024*1024 && psize <=
682  64*1024*1024)
683  printf(" (%iMB)", (int) (psize >> 20));
684  else
685  printf(" (?)");
686 
687  printf("\n");
688  }
689  }
690  }
691 }
692 
693 
694 /*
695  * mips_cpu_disassemble_instr():
696  *
697  * Convert an instruction word into human readable format, for instruction
698  * tracing.
699  *
700  * If running is 1, cpu->pc should be the address of the instruction.
701  *
702  * If running is 0, things that depend on the runtime environment (eg.
703  * register contents) will not be shown, and addr will be used instead of
704  * cpu->pc for relative addresses.
705  *
706  * NOTE 2: coprocessor instructions are not decoded nicely yet (TODO)
707  */
708 int mips_cpu_disassemble_instr(struct cpu *cpu, unsigned char *originstr,
709  int running, uint64_t dumpaddr)
710 {
711  int hi6, special6, regimm5, sub;
712  int rt, rd, rs, sa, imm, copz, cache_op, which_cache, showtag;
713  uint64_t addr, offset;
714  uint32_t instrword;
715  unsigned char instr[4];
716  char *symbol;
717 
718  if (running)
719  dumpaddr = cpu->pc;
720 
721  if ((dumpaddr & 3) != 0)
722  printf("WARNING: Unaligned address!\n");
723 
725  dumpaddr, &offset);
726  if (symbol != NULL && offset==0)
727  debug("<%s>\n", symbol);
728 
729  if (cpu->machine->ncpus > 1 && running)
730  debug("cpu%i: ", cpu->cpu_id);
731 
732  if (cpu->is_32bit)
733  debug("%08" PRIx32, (uint32_t)dumpaddr);
734  else
735  debug("%016" PRIx64, (uint64_t)dumpaddr);
736 
737  memcpy(instr, originstr, sizeof(uint32_t));
738 
739  /*
740  * The rest of the code is written for little endian,
741  * so swap if necessary:
742  */
743  if (cpu->byte_order == EMUL_BIG_ENDIAN) {
744  int tmp = instr[0]; instr[0] = instr[3];
745  instr[3] = tmp;
746  tmp = instr[1]; instr[1] = instr[2];
747  instr[2] = tmp;
748  }
749 
750  debug(": %02x%02x%02x%02x",
751  instr[3], instr[2], instr[1], instr[0]);
752 
753  if (running && cpu->delay_slot)
754  debug(" (d)");
755 
756  debug("\t");
757 
758  /*
759  * Decode the instruction:
760  */
761 
762  hi6 = (instr[3] >> 2) & 0x3f;
763 
764  switch (hi6) {
765  case HI6_SPECIAL:
766  special6 = instr[0] & 0x3f;
767  switch (special6) {
768  case SPECIAL_SLL:
769  case SPECIAL_SRL:
770  case SPECIAL_SRA:
771  case SPECIAL_DSLL:
772  case SPECIAL_DSRL:
773  case SPECIAL_DSRA:
774  case SPECIAL_DSLL32:
775  case SPECIAL_DSRL32:
776  case SPECIAL_DSRA32:
777  sub = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
778  rt = instr[2] & 31;
779  rd = (instr[1] >> 3) & 31;
780  sa = ((instr[1] & 7) << 2) + ((instr[0] >> 6) & 3);
781 
782  if (rd == 0 && special6 == SPECIAL_SLL) {
783  if (sa == 0)
784  debug("nop");
785  else if (sa == 1)
786  debug("ssnop");
787  else if (sa == 3)
788  debug("ehb");
789  else
790  debug("nop (weird, sa=%i)", sa);
791  break;
792  }
793 
794  switch (sub) {
795  case 0x00:
796  debug("%s\t%s,", special_names[special6],
797  regnames[rd]);
798  debug("%s,%i", regnames[rt], sa);
799  break;
800  case 0x01:
801  debug("%s\t%s,",
802  special_rot_names[special6],
803  regnames[rd]);
804  debug("%s,%i", regnames[rt], sa);
805  break;
806  default:debug("UNIMPLEMENTED special, sub=0x%02x\n",
807  sub);
808  }
809  break;
810  case SPECIAL_DSRLV:
811  case SPECIAL_DSRAV:
812  case SPECIAL_DSLLV:
813  case SPECIAL_SLLV:
814  case SPECIAL_SRAV:
815  case SPECIAL_SRLV:
816  rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
817  rt = instr[2] & 31;
818  rd = (instr[1] >> 3) & 31;
819  sub = ((instr[1] & 7) << 2) + ((instr[0] >> 6) & 3);
820 
821  switch (sub) {
822  case 0x00:
823  debug("%s\t%s", special_names[special6],
824  regnames[rd]);
825  debug(",%s", regnames[rt]);
826  debug(",%s", regnames[rs]);
827  break;
828  case 0x01:
829  debug("%s\t%s", special_rot_names[special6],
830  regnames[rd]);
831  debug(",%s", regnames[rt]);
832  debug(",%s", regnames[rs]);
833  break;
834  default:debug("UNIMPLEMENTED special, sub=0x%02x\n",
835  sub);
836  }
837  break;
838  case SPECIAL_JR:
839  rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
841  cpu->cd.mips.gpr[rs], &offset);
842  /* .hb = hazard barrier hint on MIPS32/64 rev 2 */
843  debug("jr%s\t%s",
844  (instr[1] & 0x04) ? ".hb" : "",
845  regnames[rs]);
846  if (running && symbol != NULL)
847  debug("\t<%s>", symbol);
848  break;
849  case SPECIAL_JALR:
850  rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
851  rd = (instr[1] >> 3) & 31;
853  cpu->cd.mips.gpr[rs], &offset);
854  /* .hb = hazard barrier hint on MIPS32/64 rev 2 */
855  debug("jalr%s\t%s",
856  (instr[1] & 0x04) ? ".hb" : "",
857  regnames[rd]);
858  debug(",%s", regnames[rs]);
859  if (running && symbol != NULL)
860  debug("\t<%s>", symbol);
861  break;
862  case SPECIAL_MFHI:
863  case SPECIAL_MFLO:
864  rd = (instr[1] >> 3) & 31;
865  debug("%s\t%s", special_names[special6], regnames[rd]);
866  break;
867  case SPECIAL_MTLO:
868  case SPECIAL_MTHI:
869  rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
870  debug("%s\t%s", special_names[special6], regnames[rs]);
871  break;
872  case SPECIAL_ADD:
873  case SPECIAL_ADDU:
874  case SPECIAL_SUB:
875  case SPECIAL_SUBU:
876  case SPECIAL_AND:
877  case SPECIAL_OR:
878  case SPECIAL_XOR:
879  case SPECIAL_NOR:
880  case SPECIAL_SLT:
881  case SPECIAL_SLTU:
882  case SPECIAL_DADD:
883  case SPECIAL_DADDU:
884  case SPECIAL_DSUB:
885  case SPECIAL_DSUBU:
886  case SPECIAL_MOVZ:
887  case SPECIAL_MOVN:
888  rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
889  rt = instr[2] & 31;
890  rd = (instr[1] >> 3) & 31;
891  if (cpu->is_32bit && (special6 == SPECIAL_ADDU ||
892  special6 == SPECIAL_SUBU) && rt == 0) {
893  /* Special case 1: addu/subu with
894  rt = the zero register ==> move */
895  debug("move\t%s", regnames[rd]);
896  debug(",%s", regnames[rs]);
897  } else if (special6 == SPECIAL_ADDU && cpu->is_32bit
898  && rs == 0) {
899  /* Special case 2: addu with
900  rs = the zero register ==> move */
901  debug("move\t%s", regnames[rd]);
902  debug(",%s", regnames[rt]);
903  } else {
904  debug("%s\t%s", special_names[special6],
905  regnames[rd]);
906  debug(",%s", regnames[rs]);
907  debug(",%s", regnames[rt]);
908  }
909  break;
910  case SPECIAL_MULT:
911  case SPECIAL_MULTU:
912  case SPECIAL_DMULT:
913  case SPECIAL_DMULTU:
914  case SPECIAL_DIV:
915  case SPECIAL_DIVU:
916  case SPECIAL_DDIV:
917  case SPECIAL_DDIVU:
918  rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
919  rt = instr[2] & 31;
920  rd = (instr[1] >> 3) & 31;
921  debug("%s\t", special_names[special6]);
922  if (rd != 0) {
923  if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
924  if (special6 == SPECIAL_MULT ||
925  special6 == SPECIAL_MULTU)
926  debug("%s,", regnames[rd]);
927  else
928  debug("WEIRD_R5900_RD,");
929  } else {
930  debug("WEIRD_RD_NONZERO,");
931  }
932  }
933  debug("%s", regnames[rs]);
934  debug(",%s", regnames[rt]);
935  break;
936  case SPECIAL_TGE:
937  case SPECIAL_TGEU:
938  case SPECIAL_TLT:
939  case SPECIAL_TLTU:
940  case SPECIAL_TEQ:
941  case SPECIAL_TNE:
942  rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
943  rt = instr[2] & 31;
944  rd = ((instr[1] << 8) + instr[0]) >> 6; // code, not rd
945  debug("%s\t", special_names[special6]);
946  debug("%s", regnames[rs]);
947  debug(",%s", regnames[rt]);
948  if (rd != 0)
949  debug(",0x%x", rd);
950  break;
951  case SPECIAL_SYNC:
952  imm = ((instr[1] & 7) << 2) + (instr[0] >> 6);
953  debug("sync\t0x%02x", imm);
954  break;
955  case SPECIAL_SYSCALL:
956  imm = (((instr[3] << 24) + (instr[2] << 16) +
957  (instr[1] << 8) + instr[0]) >> 6) & 0xfffff;
958  if (imm != 0)
959  debug("syscall\t0x%05x", imm);
960  else
961  debug("syscall");
962  break;
963  case SPECIAL_BREAK:
964  imm = (((instr[3] << 24) + (instr[2] << 16) +
965  (instr[1] << 8) + instr[0]) >> 6) & 0xfffff;
966  if (imm != 0)
967  debug("break\t0x%05x", imm);
968  else
969  debug("break");
970  break;
971  case SPECIAL_MFSA:
972  if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
973  rd = (instr[1] >> 3) & 31;
974  debug("mfsa\t%s", regnames[rd]);
975  } else {
976  debug("unimplemented special 0x28");
977  }
978  break;
979  case SPECIAL_MTSA:
980  if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
981  rs = ((instr[3] & 3) << 3) +
982  ((instr[2] >> 5) & 7);
983  debug("mtsa\t%s", regnames[rs]);
984  } else {
985  debug("unimplemented special 0x29");
986  }
987  break;
988  default:
989  debug("%s\t= UNIMPLEMENTED", special_names[special6]);
990  }
991  break;
992  case HI6_BEQ:
993  case HI6_BEQL:
994  case HI6_BNE:
995  case HI6_BNEL:
996  case HI6_BGTZ:
997  case HI6_BGTZL:
998  case HI6_BLEZ:
999  case HI6_BLEZL:
1000  rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1001  rt = instr[2] & 31;
1002  imm = (instr[1] << 8) + instr[0];
1003  if (imm >= 32768)
1004  imm -= 65536;
1005  addr = (dumpaddr + 4) + (imm << 2);
1006 
1007  if (hi6 == HI6_BEQ && rt == MIPS_GPR_ZERO &&
1008  rs == MIPS_GPR_ZERO)
1009  debug("b\t");
1010  else {
1011  debug("%s\t", hi6_names[hi6]);
1012  switch (hi6) {
1013  case HI6_BEQ:
1014  case HI6_BEQL:
1015  case HI6_BNE:
1016  case HI6_BNEL:
1017  debug("%s,", regnames[rt]);
1018  }
1019  debug("%s,", regnames[rs]);
1020  }
1021 
1022  if (cpu->is_32bit)
1023  debug("0x%08" PRIx32, (uint32_t)addr);
1024  else
1025  debug("0x%016" PRIx64, (uint64_t)addr);
1026 
1028  addr, &offset);
1029  if (symbol != NULL && offset != addr)
1030  debug("\t<%s>", symbol);
1031  break;
1032  case HI6_ADDI:
1033  case HI6_ADDIU:
1034  case HI6_DADDI:
1035  case HI6_DADDIU:
1036  case HI6_SLTI:
1037  case HI6_SLTIU:
1038  case HI6_ANDI:
1039  case HI6_ORI:
1040  case HI6_XORI:
1041  rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1042  rt = instr[2] & 31;
1043  imm = (instr[1] << 8) + instr[0];
1044  if (imm >= 32768)
1045  imm -= 65536;
1046  debug("%s\t%s,", hi6_names[hi6], regnames[rt]);
1047  debug("%s,", regnames[rs]);
1048  if (hi6 == HI6_ANDI || hi6 == HI6_ORI || hi6 == HI6_XORI)
1049  debug("0x%04x", imm & 0xffff);
1050  else
1051  debug("%i", imm);
1052  break;
1053  case HI6_LUI:
1054  rt = instr[2] & 31;
1055  imm = (instr[1] << 8) + instr[0];
1056  debug("lui\t%s,0x%x", regnames[rt], imm);
1057  break;
1058  case HI6_LB:
1059  case HI6_LBU:
1060  case HI6_LH:
1061  case HI6_LHU:
1062  case HI6_LW:
1063  case HI6_LWU:
1064  case HI6_LD:
1065  case HI6_LQ_MDMX:
1066  case HI6_LWC1:
1067  case HI6_LWC2:
1068  case HI6_LWC3:
1069  case HI6_LDC1:
1070  case HI6_LDC2:
1071  case HI6_LL:
1072  case HI6_LLD:
1073  case HI6_SB:
1074  case HI6_SH:
1075  case HI6_SW:
1076  case HI6_SD:
1077  case HI6_SQ_SPECIAL3:
1078  case HI6_SC:
1079  case HI6_SCD:
1080  case HI6_SWC1:
1081  case HI6_SWC2:
1082  case HI6_SWC3:
1083  case HI6_SDC1:
1084  case HI6_SDC2:
1085  case HI6_LWL:
1086  case HI6_LWR:
1087  case HI6_LDL:
1088  case HI6_LDR:
1089  case HI6_SWL:
1090  case HI6_SWR:
1091  case HI6_SDL:
1092  case HI6_SDR:
1093  if (hi6 == HI6_LQ_MDMX &&
1094  cpu->cd.mips.cpu_type.rev != MIPS_R5900) {
1095  debug("mdmx\t(UNIMPLEMENTED)");
1096  break;
1097  }
1098  if (hi6 == HI6_SQ_SPECIAL3 &&
1099  cpu->cd.mips.cpu_type.rev != MIPS_R5900) {
1100  int msbd, lsb, sub10;
1101  special6 = instr[0] & 0x3f;
1102  rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1103  rt = instr[2] & 31;
1104  rd = msbd = (instr[1] >> 3) & 31;
1105  lsb = ((instr[1] & 7) << 2) | (instr[0] >> 6);
1106  sub10 = (rs << 5) | lsb;
1107 
1108  switch (special6) {
1109 
1110  case SPECIAL3_EXT:
1111  case SPECIAL3_DEXT:
1112  case SPECIAL3_DEXTM:
1113  case SPECIAL3_DEXTU:
1114  debug("%s", special3_names[special6]);
1115  if (special6 == SPECIAL3_DEXTM)
1116  msbd += 32;
1117  if (special6 == SPECIAL3_DEXTU)
1118  lsb += 32;
1119  debug("\t%s", regnames[rt]);
1120  debug(",%s", regnames[rs]);
1121  debug(",%i,%i", lsb, msbd + 1);
1122  break;
1123 
1124  case SPECIAL3_INS:
1125  case SPECIAL3_DINS:
1126  case SPECIAL3_DINSM:
1127  case SPECIAL3_DINSU:
1128  debug("%s", special3_names[special6]);
1129  if (special6 == SPECIAL3_DINSM)
1130  msbd += 32;
1131  if (special6 == SPECIAL3_DINSU) {
1132  lsb += 32;
1133  msbd += 32;
1134  }
1135  msbd -= lsb;
1136  debug("\t%s", regnames[rt]);
1137  debug(",%s", regnames[rs]);
1138  debug(",%i,%i", lsb, msbd + 1);
1139  break;
1140 
1141  case SPECIAL3_BSHFL:
1142  switch (sub10) {
1143  case BSHFL_WSBH:
1144  case BSHFL_SEB:
1145  case BSHFL_SEH:
1146  switch (sub10) {
1147  case BSHFL_WSBH: debug("wsbh"); break;
1148  case BSHFL_SEB: debug("seb"); break;
1149  case BSHFL_SEH: debug("seh"); break;
1150  }
1151  debug("\t%s", regnames[rd]);
1152  debug(",%s", regnames[rt]);
1153  break;
1154  default:debug("%s", special3_names[special6]);
1155  debug("\t(UNIMPLEMENTED)");
1156  }
1157  break;
1158 
1159  case SPECIAL3_DBSHFL:
1160  switch (sub10) {
1161  case BSHFL_DSBH:
1162  case BSHFL_DSHD:
1163  switch (sub10) {
1164  case BSHFL_DSBH: debug("dsbh"); break;
1165  case BSHFL_DSHD: debug("dshd"); break;
1166  }
1167  debug("\t%s", regnames[rd]);
1168  debug(",%s", regnames[rt]);
1169  break;
1170  default:debug("%s", special3_names[special6]);
1171  debug("\t(UNIMPLEMENTED)");
1172  }
1173  break;
1174 
1175  case SPECIAL3_RDHWR:
1176  debug("%s", special3_names[special6]);
1177  debug("\t%s", regnames[rt]);
1178  debug(",hwr%i", rd);
1179  break;
1180 
1181  default:debug("%s", special3_names[special6]);
1182  debug("\t(UNIMPLEMENTED)");
1183  }
1184  break;
1185  }
1186 
1187  rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1188  rt = instr[2] & 31;
1189  imm = (instr[1] << 8) + instr[0];
1190  if (imm >= 32768)
1191  imm -= 65536;
1193  cpu->cd.mips.gpr[rs] + imm, &offset);
1194 
1195  /* LWC3 is PREF in the newer ISA levels: */
1196  /* TODO: Which ISAs? IV? V? 32? 64? */
1197  if (cpu->cd.mips.cpu_type.isa_level >= 4 && hi6 == HI6_LWC3) {
1198  debug("pref\t0x%x,%i(%s)",
1199  rt, imm, regnames[rs]);
1200 
1201  if (running) {
1202  debug("\t[0x%016" PRIx64" = %s]",
1203  (uint64_t)(cpu->cd.mips.gpr[rs] + imm));
1204  if (symbol != NULL)
1205  debug(" = %s", symbol);
1206  debug("]");
1207  }
1208  goto disasm_ret;
1209  }
1210 
1211  debug("%s\t", hi6_names[hi6]);
1212 
1213  if (hi6 == HI6_SWC1 || hi6 == HI6_SWC2 || hi6 == HI6_SWC3 ||
1214  hi6 == HI6_SDC1 || hi6 == HI6_SDC2 ||
1215  hi6 == HI6_LWC1 || hi6 == HI6_LWC2 || hi6 == HI6_LWC3 ||
1216  hi6 == HI6_LDC1 || hi6 == HI6_LDC2)
1217  debug("r%i", rt);
1218  else
1219  debug("%s", regnames[rt]);
1220 
1221  debug(",%i(%s)", imm, regnames[rs]);
1222 
1223  if (running) {
1224  debug("\t[");
1225 
1226  if (cpu->is_32bit)
1227  debug("0x%08" PRIx32,
1228  (uint32_t) (cpu->cd.mips.gpr[rs] + imm));
1229  else
1230  debug("0x%016" PRIx64,
1231  (uint64_t) (cpu->cd.mips.gpr[rs] + imm));
1232 
1233  if (symbol != NULL)
1234  debug(" = %s", symbol);
1235 
1236  /* TODO: In some cases, it is possible to peek into
1237  memory, and display that data here, like for the
1238  other emulation modes. */
1239 
1240  debug("]");
1241  }
1242  break;
1243 
1244  case HI6_J:
1245  case HI6_JAL:
1246  imm = (((instr[3] & 3) << 24) + (instr[2] << 16) +
1247  (instr[1] << 8) + instr[0]) << 2;
1248  addr = (dumpaddr + 4) & ~((1 << 28) - 1);
1249  addr |= imm;
1251  addr, &offset);
1252  debug("%s\t0x", hi6_names[hi6]);
1253  if (cpu->is_32bit)
1254  debug("%08" PRIx32, (uint32_t) addr);
1255  else
1256  debug("%016" PRIx64, (uint64_t) addr);
1257  if (symbol != NULL)
1258  debug("\t<%s>", symbol);
1259  break;
1260 
1261  case HI6_COP0:
1262  case HI6_COP1:
1263  case HI6_COP2:
1264  case HI6_COP3:
1265  imm = (instr[3] << 24) + (instr[2] << 16) +
1266  (instr[1] << 8) + instr[0];
1267  imm &= ((1 << 26) - 1);
1268 
1269  /* Call coproc_function(), but ONLY disassembly, no exec: */
1271  hi6 - HI6_COP0, imm, 1, running);
1272  return sizeof(instrword);
1273 
1274  case HI6_CACHE:
1275  rt = ((instr[3] & 3) << 3) + (instr[2] >> 5); /* base */
1276  copz = instr[2] & 31;
1277  imm = (instr[1] << 8) + instr[0];
1278  cache_op = copz >> 2;
1279  which_cache = copz & 3;
1280  showtag = 0;
1281  debug("cache\t0x%02x,0x%04x(%s)", copz, imm, regnames[rt]);
1282  if (which_cache==0) debug(" [ primary I-cache");
1283  if (which_cache==1) debug(" [ primary D-cache");
1284  if (which_cache==2) debug(" [ secondary I-cache");
1285  if (which_cache==3) debug(" [ secondary D-cache");
1286  debug(", ");
1287  if (cache_op==0) debug("index invalidate");
1288  if (cache_op==1) debug("index load tag");
1289  if (cache_op==2) debug("index store tag"), showtag=1;
1290  if (cache_op==3) debug("create dirty exclusive");
1291  if (cache_op==4) debug("hit invalidate");
1292  if (cache_op==5) debug("fill OR hit writeback invalidate");
1293  if (cache_op==6) debug("hit writeback");
1294  if (cache_op==7) debug("hit set virtual");
1295  if (running)
1296  debug(", addr 0x%016" PRIx64,
1297  (uint64_t)(cpu->cd.mips.gpr[rt] + imm));
1298  if (showtag)
1299  debug(", taghi=%08lx lo=%08lx",
1300  (long)cpu->cd.mips.coproc[0]->reg[COP0_TAGDATA_HI],
1301  (long)cpu->cd.mips.coproc[0]->reg[COP0_TAGDATA_LO]);
1302  debug(" ]");
1303  break;
1304 
1305  case HI6_SPECIAL2:
1306  special6 = instr[0] & 0x3f;
1307  instrword = (instr[3] << 24) + (instr[2] << 16) +
1308  (instr[1] << 8) + instr[0];
1309  rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1310  rt = instr[2] & 31;
1311  rd = (instr[1] >> 3) & 31;
1312 
1313  if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
1314  int c790mmifunc = (instrword >> 6) & 0x1f;
1315  if (special6 != MMI_MMI0 && special6 != MMI_MMI1 &&
1316  special6 != MMI_MMI2 && special6 != MMI_MMI3)
1317  debug("%s\t", mmi_names[special6]);
1318 
1319  switch (special6) {
1320 
1321  case MMI_MADD:
1322  case MMI_MADDU:
1323  if (rd != MIPS_GPR_ZERO) {
1324  debug("%s,", regnames[rd]);
1325  }
1326  debug("%s,%s", regnames[rs], regnames[rt]);
1327  break;
1328 
1329  case MMI_MMI0:
1330  debug("%s\t", mmi0_names[c790mmifunc]);
1331  switch (c790mmifunc) {
1332 
1333  case MMI0_PEXTLB:
1334  case MMI0_PEXTLH:
1335  case MMI0_PEXTLW:
1336  case MMI0_PMAXH:
1337  case MMI0_PMAXW:
1338  case MMI0_PPACB:
1339  case MMI0_PPACH:
1340  case MMI0_PPACW:
1341  debug("%s,%s,%s", regnames[rd],
1342  regnames[rs], regnames[rt]);
1343  break;
1344 
1345  default:debug("(UNIMPLEMENTED)");
1346  }
1347  break;
1348 
1349  case MMI_MMI1:
1350  debug("%s\t", mmi1_names[c790mmifunc]);
1351  switch (c790mmifunc) {
1352 
1353  case MMI1_PEXTUB:
1354  case MMI1_PEXTUH:
1355  case MMI1_PEXTUW:
1356  case MMI1_PMINH:
1357  case MMI1_PMINW:
1358  debug("%s,%s,%s", regnames[rd],
1359  regnames[rs], regnames[rt]);
1360  break;
1361 
1362  default:debug("(UNIMPLEMENTED)");
1363  }
1364  break;
1365 
1366  case MMI_MMI2:
1367  debug("%s\t", mmi2_names[c790mmifunc]);
1368  switch (c790mmifunc) {
1369 
1370  case MMI2_PMFHI:
1371  case MMI2_PMFLO:
1372  debug("%s", regnames[rd]);
1373  break;
1374 
1375  case MMI2_PHMADH:
1376  case MMI2_PHMSBH:
1377  case MMI2_PINTH:
1378  case MMI2_PMADDH:
1379  case MMI2_PMADDW:
1380  case MMI2_PMSUBH:
1381  case MMI2_PMSUBW:
1382  case MMI2_PMULTH:
1383  case MMI2_PMULTW:
1384  case MMI2_PSLLVW:
1385  debug("%s,%s,%s", regnames[rd],
1386  regnames[rs], regnames[rt]);
1387  break;
1388 
1389  default:debug("(UNIMPLEMENTED)");
1390  }
1391  break;
1392 
1393  case MMI_MMI3:
1394  debug("%s\t", mmi3_names[c790mmifunc]);
1395  switch (c790mmifunc) {
1396 
1397  case MMI3_PMTHI:
1398  case MMI3_PMTLO:
1399  debug("%s", regnames[rs]);
1400  break;
1401 
1402  case MMI3_PINTEH:
1403  case MMI3_PMADDUW:
1404  case MMI3_PMULTUW:
1405  case MMI3_PNOR:
1406  case MMI3_POR:
1407  case MMI3_PSRAVW:
1408  debug("%s,%s,%s", regnames[rd],
1409  regnames[rs], regnames[rt]);
1410  break;
1411 
1412  default:debug("(UNIMPLEMENTED)");
1413  }
1414  break;
1415 
1416  default:debug("(UNIMPLEMENTED)");
1417  }
1418  break;
1419  }
1420 
1421  /* SPECIAL2: */
1422  debug("%s\t", special2_names[special6]);
1423 
1424  switch (special6) {
1425 
1426  case SPECIAL2_MADD:
1427  case SPECIAL2_MADDU:
1428  case SPECIAL2_MSUB:
1429  case SPECIAL2_MSUBU:
1430  if (rd != MIPS_GPR_ZERO) {
1431  debug("WEIRD_NONZERO_RD(%s),",
1432  regnames[rd]);
1433  }
1434  debug("%s,%s", regnames[rs], regnames[rt]);
1435  break;
1436 
1437  case SPECIAL2_MUL:
1438  /* Apparently used both on R5900 and MIPS32: */
1439  debug("%s,%s,%s", regnames[rd],
1440  regnames[rs], regnames[rt]);
1441  break;
1442 
1443  case SPECIAL2_CLZ:
1444  case SPECIAL2_CLO:
1445  case SPECIAL2_DCLZ:
1446  case SPECIAL2_DCLO:
1447  debug("%s,%s", regnames[rd], regnames[rs]);
1448  break;
1449 
1450  default:
1451  debug("(UNIMPLEMENTED)");
1452  }
1453  break;
1454 
1455  case HI6_REGIMM:
1456  regimm5 = instr[2] & 0x1f;
1457  rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1458  imm = (instr[1] << 8) + instr[0];
1459  if (imm >= 32768)
1460  imm -= 65536;
1461 
1462  switch (regimm5) {
1463 
1464  case REGIMM_BLTZ:
1465  case REGIMM_BGEZ:
1466  case REGIMM_BLTZL:
1467  case REGIMM_BGEZL:
1468  case REGIMM_BLTZAL:
1469  case REGIMM_BLTZALL:
1470  case REGIMM_BGEZAL:
1471  case REGIMM_BGEZALL:
1472  debug("%s\t%s,", regimm_names[regimm5], regnames[rs]);
1473 
1474  addr = (dumpaddr + 4) + (imm << 2);
1475 
1476  if (cpu->is_32bit)
1477  debug("0x%08" PRIx32, (uint32_t) addr);
1478  else
1479  debug("0x%016" PRIx64, (uint64_t) addr);
1480  break;
1481 
1482  case REGIMM_TGEI:
1483  case REGIMM_TGEIU:
1484  case REGIMM_TLTI:
1485  case REGIMM_TLTIU:
1486  case REGIMM_TEQI:
1487  case REGIMM_TNEI:
1488  debug("%s\t%s,", regimm_names[regimm5], regnames[rs]);
1489 
1490  if (cpu->is_32bit)
1491  debug("0x%" PRIx32, (uint32_t) imm);
1492  else
1493  debug("0x%" PRIx64, (uint64_t) imm);
1494  break;
1495 
1496  case REGIMM_SYNCI:
1497  debug("%s\t%i(%s)", regimm_names[regimm5],
1498  imm, regnames[rs]);
1499  break;
1500 
1501  default:
1502  debug("unimplemented regimm5 = 0x%02x", regimm5);
1503  }
1504  break;
1505  default:
1506  debug("unimplemented hi6 = 0x%02x", hi6);
1507  }
1508 
1509 disasm_ret:
1510  debug("\n");
1511  return sizeof(instrword);
1512 }
1513 
1514 
1515 /*
1516  * mips_cpu_register_dump():
1517  *
1518  * Dump cpu registers in a relatively readable format.
1519  *
1520  * gprs: set to non-zero to dump GPRs and hi/lo/pc
1521  * coprocs: set bit 0..3 to dump registers in coproc 0..3.
1522  */
1523 void mips_cpu_register_dump(struct cpu *cpu, int gprs, int coprocs)
1524 {
1525  int coprocnr, i, bits32;
1526  uint64_t offset;
1527  char *symbol;
1528  int bits128 = cpu->cd.mips.cpu_type.rev == MIPS_R5900;
1529 
1530  bits32 = cpu->is_32bit;
1531 
1532  if (gprs) {
1533  /* Special registers (pc, hi/lo) first: */
1535  cpu->pc, &offset);
1536 
1537  if (bits32)
1538  debug("cpu%i: pc = %08" PRIx32,
1539  cpu->cpu_id, (uint32_t) cpu->pc);
1540  else if (bits128)
1541  debug("cpu%i: pc=%016" PRIx64,
1542  cpu->cpu_id, (uint64_t) cpu->pc);
1543  else
1544  debug("cpu%i: pc = 0x%016" PRIx64,
1545  cpu->cpu_id, (uint64_t) cpu->pc);
1546 
1547  debug(" <%s>\n", symbol != NULL? symbol :
1548  " no symbol ");
1549 
1550  if (bits32)
1551  debug("cpu%i: hi = %08" PRIx32" lo = %08" PRIx32"\n",
1552  cpu->cpu_id, (uint32_t) cpu->cd.mips.hi,
1553  (uint32_t) cpu->cd.mips.lo);
1554  else if (bits128) {
1555  debug("cpu%i: hi=%016" PRIx64"%016" PRIx64" lo="
1556  "%016" PRIx64"%016" PRIx64"\n", cpu->cpu_id,
1557  cpu->cd.mips.hi1, cpu->cd.mips.hi,
1558  cpu->cd.mips.lo1, cpu->cd.mips.lo);
1559  } else {
1560  debug("cpu%i: hi = 0x%016" PRIx64" lo = 0x%016"
1561  PRIx64"\n", cpu->cpu_id,
1562  (uint64_t) cpu->cd.mips.hi,
1563  (uint64_t) cpu->cd.mips.lo);
1564  }
1565 
1566  /* General registers: */
1567  if (bits128) {
1568  /* 128-bit: */
1569  for (i=0; i<32; i++) {
1570  int r = (i >> 1) + ((i & 1) << 4);
1571  if ((i & 1) == 0)
1572  debug("cpu%i:", cpu->cpu_id);
1573  if (r == MIPS_GPR_ZERO)
1574  debug(" "
1575  " ");
1576  else
1577  debug(" %3s=%016" PRIx64"%016" PRIx64,
1578  regnames[r], (uint64_t)
1579  cpu->cd.mips.gpr_quadhi[r],
1580  (uint64_t)cpu->cd.mips.gpr[r]);
1581  if ((i & 1) == 1)
1582  debug("\n");
1583  }
1584  } else if (bits32) {
1585  /* 32-bit: */
1586  for (i=0; i<32; i++) {
1587  if ((i & 3) == 0)
1588  debug("cpu%i:", cpu->cpu_id);
1589  if (i == MIPS_GPR_ZERO)
1590  debug(" ");
1591  else
1592  debug(" %3s = %08" PRIx32, regnames[i],
1593  (uint32_t)cpu->cd.mips.gpr[i]);
1594  if ((i & 3) == 3)
1595  debug("\n");
1596  }
1597  } else {
1598  /* 64-bit: */
1599  for (i=0; i<32; i++) {
1600  int r = (i >> 1) + ((i & 1) << 4);
1601  if ((i & 1) == 0)
1602  debug("cpu%i:", cpu->cpu_id);
1603  if (r == MIPS_GPR_ZERO)
1604  debug(" ");
1605  else
1606  debug(" %3s = 0x%016" PRIx64,
1607  regnames[r],
1608  (uint64_t)cpu->cd.mips.gpr[r]);
1609  if ((i & 1) == 1)
1610  debug("\n");
1611  }
1612  }
1613  }
1614 
1615  for (coprocnr=0; coprocnr<4; coprocnr++) {
1616  int nm1 = 1;
1617 
1618  if (bits32)
1619  nm1 = 3;
1620 
1621  if (!(coprocs & (1<<coprocnr)))
1622  continue;
1623  if (cpu->cd.mips.coproc[coprocnr] == NULL) {
1624  debug("cpu%i: no coprocessor %i\n",
1625  cpu->cpu_id, coprocnr);
1626  continue;
1627  }
1628 
1629  /* Coprocessor registers: */
1630  for (i=0; i<32; i++) {
1631  /* 32-bit: */
1632  if ((i & nm1) == 0)
1633  debug("cpu%i:", cpu->cpu_id);
1634 
1635  if (coprocnr == 0)
1636  debug(" %8s", cop0_names[i]);
1637  else
1638  debug(" c%i,%02i", coprocnr, i);
1639 
1640  if (bits32)
1641  debug("=%08x", (int)cpu->cd.mips.
1642  coproc[coprocnr]->reg[i]);
1643  else {
1644  if (coprocnr == 0 && (i == COP0_COUNT
1645  || i == COP0_COMPARE || i == COP0_INDEX
1646  || i == COP0_RANDOM || i == COP0_WIRED))
1647  debug(" = 0x%08x",
1648  (int) cpu->cd.mips.coproc[
1649  coprocnr]->reg[i]);
1650  else
1651  debug(" = 0x%016" PRIx64, (uint64_t)
1652  cpu->cd.mips.coproc[
1653  coprocnr]->reg[i]);
1654  }
1655 
1656  if ((i & nm1) == nm1)
1657  debug("\n");
1658 
1659  /* Skip the last 16 cop0 registers on R3000 etc. */
1660  if (coprocnr == 0 && cpu->cd.mips.cpu_type.isa_level < 3
1661  && i == 15)
1662  i = 31;
1663  }
1664 
1665  if (coprocnr == 0 && cpu->cd.mips.cpu_type.isa_level >= 32) {
1666  debug("cpu%i: ", cpu->cpu_id);
1667  debug("config_select1 = 0x");
1668  if (cpu->is_32bit)
1669  debug("%08" PRIx32,
1670  (uint32_t)cpu->cd.mips.cop0_config_select1);
1671  else
1672  debug("%016" PRIx64,
1673  (uint64_t)cpu->cd.mips.cop0_config_select1);
1674  debug("\n");
1675  }
1676 
1677  /* Floating point control registers: */
1678  if (coprocnr == 1) {
1679  for (i=0; i<32; i++)
1680  switch (i) {
1681  case MIPS_FPU_FCIR:
1682  printf("cpu%i: fcr0 (fcir) = 0x%08x\n",
1683  cpu->cpu_id, (int)cpu->cd.mips.
1684  coproc[coprocnr]->fcr[i]);
1685  break;
1686  case MIPS_FPU_FCCR:
1687  printf("cpu%i: fcr25 (fccr) = 0x%08x\n",
1688  cpu->cpu_id, (int)cpu->cd.mips.
1689  coproc[coprocnr]->fcr[i]);
1690  break;
1691  case MIPS_FPU_FCSR:
1692  printf("cpu%i: fcr31 (fcsr) = 0x%08x\n",
1693  cpu->cpu_id, (int)cpu->cd.mips.
1694  coproc[coprocnr]->fcr[i]);
1695  break;
1696  }
1697  }
1698  }
1699 
1700  if (cpu->cd.mips.rmw) {
1701  printf("cpu%i: Read-Modify-Write in progress, address "
1702  "0x%016" PRIx64"\n", cpu->cpu_id, cpu->cd.mips.rmw_addr);
1703  }
1704 }
1705 
1706 
1707 /*
1708  * mips_cpu_interrupt_assert(), mips_cpu_interrupt_deassert():
1709  *
1710  * Assert or deassert a MIPS CPU interrupt by masking in or out bits
1711  * in the CAUSE register of coprocessor 0.
1712  */
1714 {
1715  struct cpu *cpu = (struct cpu *) interrupt->extra;
1717 }
1719 {
1720  struct cpu *cpu = (struct cpu *) interrupt->extra;
1722 }
1723 
1724 
1725 /*
1726  * mips_cpu_exception():
1727  *
1728  * Cause an exception in a CPU. This sets a couple of coprocessor 0
1729  * registers, and the program counter.
1730  *
1731  * exccode the exception code
1732  * tlb set to non-zero if the exception handler at
1733  * 0x80000000 should be used. (normal = 0x80000180)
1734  * vaddr virtual address (for some exceptions)
1735  * coproc_nr coprocessor number (for some exceptions)
1736  * vaddr_vpn2 vpn2 (for some exceptions)
1737  * vaddr_asid asid (for some exceptions)
1738  * x_64 non-zero for 64-bit mode for R4000-style tlb misses
1739  */
1740 void mips_cpu_exception(struct cpu *cpu, int exccode, int tlb, uint64_t vaddr,
1741  int coproc_nr, uint64_t vaddr_vpn2, int vaddr_asid, int x_64)
1742 {
1743  uint64_t base;
1744  uint64_t *reg = &cpu->cd.mips.coproc[0]->reg[0];
1745  int exc_model = cpu->cd.mips.cpu_type.exc_model;
1746 
1747  if (cpu->is_halted) {
1748  /*
1749  * If the exception occurred on a 'wait' instruction, then let
1750  * the instruction following the wait instruction be the one
1751  * we continue at when the interrupt service routine returns.
1752  */
1753  cpu->is_halted = 0;
1754  cpu->pc += sizeof(uint32_t);
1755  }
1756 
1757  if (!quiet_mode) {
1758  uint64_t offset;
1759  int x;
1761  cpu->pc, &offset);
1762 
1763  debug("[ ");
1764  if (cpu->machine->ncpus > 1)
1765  debug("cpu%i: ", cpu->cpu_id);
1766 
1767  debug("exception %s%s",
1768  exception_names[exccode], tlb? " <tlb>" : "");
1769 
1770  switch (exccode) {
1771 
1772  case EXCEPTION_INT:
1773  debug(" cause_im=0x%02x", (int)
1775  >> CAUSE_IP_SHIFT));
1776  break;
1777 
1778  case EXCEPTION_SYS:
1779  debug(" v0=%i", (int)cpu->cd.mips.gpr[MIPS_GPR_V0]);
1780  for (x=0; x<4; x++) {
1781  int64_t d = cpu->cd.mips.gpr[MIPS_GPR_A0 + x];
1782  char strbuf[30];
1783 
1784  if (d > -256 && d < 256) {
1785  debug(" a%i=%i", x, (int)d);
1786  } else if (memory_points_to_string(cpu,
1787  cpu->mem, d, 1)) {
1788  debug(" a%i=\"%s\"", x,
1790  d, strbuf, sizeof(strbuf)));
1791  } else {
1792  if (cpu->is_32bit)
1793  debug(" a%i=0x%" PRIx32, x,
1794  (uint32_t)d);
1795  else
1796  debug(" a%i=0x%" PRIx64, x,
1797  (uint64_t)d);
1798  }
1799  }
1800  break;
1801 
1802  case EXCEPTION_CPU:
1803  debug(" coproc_nr=%i", coproc_nr);
1804  break;
1805 
1806  default:
1807  if (cpu->is_32bit)
1808  debug(" vaddr=0x%08x", (int)vaddr);
1809  else
1810  debug(" vaddr=0x%016" PRIx64, (uint64_t)vaddr);
1811  }
1812 
1813  if (cpu->is_32bit)
1814  debug(" pc=0x%08" PRIx32" ", (uint32_t)cpu->pc);
1815  else
1816  debug(" pc=0x%016" PRIx64" ", (uint64_t)cpu->pc);
1817 
1818  if (symbol != NULL)
1819  debug("<%s> ]\n", symbol);
1820  else
1821  debug("]\n");
1822  }
1823 
1824  if (tlb && vaddr < 0x1000) {
1825  uint64_t offset;
1827  cpu->pc, &offset);
1828  fatal("[ ");
1829  if (cpu->machine->ncpus > 1)
1830  fatal("cpu%i: ", cpu->cpu_id);
1831  fatal("warning: LOW reference: vaddr=");
1832  if (cpu->is_32bit)
1833  fatal("0x%08" PRIx32, (uint32_t) vaddr);
1834  else
1835  fatal("0x%016" PRIx64, (uint64_t) vaddr);
1836  fatal(", exception %s, pc=", exception_names[exccode]);
1837  if (cpu->is_32bit)
1838  fatal("0x%08" PRIx32, (uint32_t) cpu->pc);
1839  else
1840  fatal("0x%016" PRIx64, (uint64_t)cpu->pc);
1841  fatal(" <%s> ]\n", symbol? symbol : "(no symbol)");
1842  }
1843 
1844  /* Clear the exception code bits of the cause register... */
1845  if (exc_model == EXC3K)
1847  else
1849 
1850  /* ... and OR in the exception code: */
1851  reg[COP0_CAUSE] |= (exccode << CAUSE_EXCCODE_SHIFT);
1852 
1853  /* Always set CE (according to the R5000 manual): */
1855  reg[COP0_CAUSE] |= (coproc_nr << CAUSE_CE_SHIFT);
1856 
1857  if (tlb || (exccode >= EXCEPTION_MOD && exccode <= EXCEPTION_ADES) ||
1858  exccode == EXCEPTION_VCEI || exccode == EXCEPTION_VCED) {
1859  reg[COP0_BADVADDR] = vaddr;
1860  if (cpu->is_32bit)
1861  reg[COP0_BADVADDR] = (int32_t)reg[COP0_BADVADDR];
1862 
1863  if (exc_model == EXC3K) {
1865  reg[COP0_CONTEXT] |= ((vaddr_vpn2 <<
1868 
1870  | (vaddr_asid << R2K3K_ENTRYHI_ASID_SHIFT);
1871 
1872  /* Sign-extend: */
1873  reg[COP0_CONTEXT] = (int64_t)(int32_t)reg[COP0_CONTEXT];
1874  reg[COP0_ENTRYHI] = (int64_t)(int32_t)reg[COP0_ENTRYHI];
1875  } else {
1876  if (cpu->cd.mips.cpu_type.rev == MIPS_R4100) {
1877  reg[COP0_CONTEXT] &=
1879  reg[COP0_CONTEXT] |= ((vaddr_vpn2 <<
1882 
1883  /* TODO: fix these */
1887  reg[COP0_XCONTEXT] |= ((vaddr >> 62) & 0x3) << XCONTEXT_R_SHIFT;
1888 
1889  /* reg[COP0_PAGEMASK] = cpu->cd.mips.coproc[0]->tlbs[0].mask & PAGEMASK_MASK; */
1890 
1891  reg[COP0_ENTRYHI] = (vaddr & (ENTRYHI_R_MASK | ENTRYHI_VPN2_MASK | 0x1800)) | vaddr_asid;
1892  } else {
1895 
1899  reg[COP0_XCONTEXT] |= ((vaddr >> 62) & 0x3) << XCONTEXT_R_SHIFT;
1900 
1901  /* reg[COP0_PAGEMASK] = cpu->cd.mips.coproc[0]->tlbs[0].mask & PAGEMASK_MASK; */
1902 
1903  // Actually, the R10000 manual says:
1904  // "When either a TLB refill, TLB invalid, or TLB modified exception occurs, the
1905  // EntryHi register is loaded with the virtual page number (VPN2) and the ASID of
1906  // the virtual address that did not have a matching TLB entry."
1907  // Strange that it does not mention the 2 top bits (R).
1908  //
1909  // However, the MIPS64 manual says:
1910  // "A TLB exception (TLB Refill, XTLB Refill, TLB Invalid, or TLB Modified) causes
1911  // the bits of the virtual address corresponding to the R and VPN2 fields to be
1912  // written into the EntryHi register."
1913 
1914  if ((reg[COP0_ENTRYHI] & ENTRYHI_ASID) != vaddr_asid)
1915  fatal("[ huh? vaddr_asid 0x%02x not same as in ENTRYHI 0x%02x ]\n",
1916  vaddr_asid, reg[COP0_ENTRYHI] & ENTRYHI_ASID);
1917 
1918  if (cpu->cd.mips.cpu_type.mmu_model == MMU10K)
1919  reg[COP0_ENTRYHI] = (vaddr & (ENTRYHI_R_MASK | ENTRYHI_VPN2_MASK_R10K)) | vaddr_asid;
1920  else
1921  reg[COP0_ENTRYHI] = (vaddr & (ENTRYHI_R_MASK | ENTRYHI_VPN2_MASK)) | vaddr_asid;
1922  }
1923  }
1924  }
1925 
1926  if (exc_model != EXC3K && reg[COP0_STATUS] & STATUS_EXL) {
1927  /*
1928  * Don't set EPC if STATUS_EXL is set, for R4000 and up.
1929  * This actually happens when running IRIX and Ultrix, when
1930  * they handle interrupts and/or tlb updates, I think, so
1931  * printing this with debug() looks better than with fatal().
1932  */
1933  /* debug("[ warning: cpu%i exception while EXL is set,"
1934  " not setting EPC ]\n", cpu->cpu_id); */
1935  } else {
1936  if (cpu->delay_slot) {
1937  reg[COP0_EPC] = cpu->pc - 4;
1938  reg[COP0_CAUSE] |= CAUSE_BD;
1939  } else {
1940  reg[COP0_EPC] = cpu->pc;
1941  reg[COP0_CAUSE] &= ~CAUSE_BD;
1942  }
1943  }
1944 
1945  if (cpu->delay_slot)
1947  else
1949 
1950  /* TODO: This is true for MIPS64, but how about others? */
1951  if (reg[COP0_STATUS] & STATUS_BEV)
1952  base = 0xffffffffbfc00200ULL;
1953  else
1954  base = 0xffffffff80000000ULL;
1955 
1956  switch (exc_model) {
1957  case EXC3K:
1958  /* Userspace tlb, vs others: */
1959  if (tlb && !(vaddr & 0x80000000ULL) &&
1960  (exccode == EXCEPTION_TLBL || exccode == EXCEPTION_TLBS) )
1961  cpu->pc = base + 0x000;
1962  else
1963  cpu->pc = base + 0x080;
1964  break;
1965  default:
1966  /*
1967  * These offsets are according to the MIPS64 manual, but
1968  * should work with R4000 and the rest too (I hope).
1969  *
1970  * 0x000 TLB refill, if EXL=0
1971  * 0x080 64-bit XTLB refill, if EXL=0
1972  * 0x100 cache error (not implemented yet)
1973  * 0x180 general exception
1974  * 0x200 interrupt (if CAUSE_IV is set)
1975  */
1976  if (tlb && (exccode == EXCEPTION_TLBL ||
1977  exccode == EXCEPTION_TLBS) &&
1978  !(reg[COP0_STATUS] & STATUS_EXL)) {
1979  if (x_64)
1980  cpu->pc = base + 0x080;
1981  else
1982  cpu->pc = base + 0x000;
1983  } else {
1984  if (exccode == EXCEPTION_INT &&
1985  (reg[COP0_CAUSE] & CAUSE_IV))
1986  cpu->pc = base + 0x200;
1987  else
1988  cpu->pc = base + 0x180;
1989  }
1990  }
1991 
1992  if (exc_model == EXC3K) {
1993  /* R{2,3}000: Shift the lowest 6 bits to the left two steps:*/
1994  reg[COP0_STATUS] = (reg[COP0_STATUS] & ~0x3f) +
1995  ((reg[COP0_STATUS] & 0xf) << 2);
1996  } else {
1997  /* R4000: */
1999  }
2000 
2001  /* Sign-extend: */
2002  reg[COP0_CAUSE] = (int64_t)(int32_t)reg[COP0_CAUSE];
2003  reg[COP0_STATUS] = (int64_t)(int32_t)reg[COP0_STATUS];
2004 
2005  if (cpu->is_32bit) {
2006  reg[COP0_EPC] = (int64_t)(int32_t)reg[COP0_EPC];
2008  } else {
2010  }
2011 }
2012 
2013 
2014 #include "memory_mips.cc"
2015 
2016 
2017 #include "tmp_mips_tail.cc"
2018 
MMI2_PMADDH
#define MMI2_PMADDH
Definition: opcodes_mips.h:365
SPECIAL_MFLO
#define SPECIAL_MFLO
Definition: opcodes_mips.h:187
MIPS_R2000
#define MIPS_R2000
Definition: mips_cpuregs.h:697
mips_cpu::gpr_quadhi
uint64_t gpr_quadhi[N_MIPS_GPRS]
Definition: cpu_mips.h:248
mips_cpu::rmw_addr
uint64_t rmw_addr
Definition: cpu_mips.h:234
mips_cpu_type_def::pdcache
int pdcache
Definition: cpu_mips.h:60
mips_cpu::cpu_type
struct mips_cpu_type_def cpu_type
Definition: cpu_mips.h:206
mips_coproc::reg
uint64_t reg[N_MIPS_COPROC_REGS]
Definition: cpu_mips.h:102
mips_cpu::cache_linesize
int cache_linesize[2]
Definition: cpu_mips.h:271
mips_cpu::cache_pdcache
int cache_pdcache
Definition: cpu_mips.h:261
instr
#define instr(n)
Definition: tmp_alpha_head.cc:43
HI6_SW
#define HI6_SW
Definition: opcodes_mips.h:459
MIPS_GPR_A0
#define MIPS_GPR_A0
Definition: cpu_mips.h:138
mips_cpu::coproc
struct mips_coproc * coproc[N_MIPS_COPROCS]
Definition: cpu_mips.h:219
SPECIAL_TEQ
#define SPECIAL_TEQ
Definition: opcodes_mips.h:221
ENTRYLO_V
#define ENTRYLO_V
Definition: cop0.h:68
HI6_SWL
#define HI6_SWL
Definition: opcodes_mips.h:458
mips_cpu::hi
uint64_t hi
Definition: cpu_mips.h:215
SPECIAL_MOVN
#define SPECIAL_MOVN
Definition: opcodes_mips.h:180
XCONTEXT_BADVPN2_SHIFT
#define XCONTEXT_BADVPN2_SHIFT
Definition: cop0.h:150
mips_cpu_type_def::isa_revision
char isa_revision
Definition: cpu_mips.h:54
INTERRUPT_CONNECT
#define INTERRUPT_CONNECT(name, istruct)
Definition: interrupt.h:77
MIPS_REGISTER_NAMES
#define MIPS_REGISTER_NAMES
Definition: cpu_mips.h:128
MMI0_PMAXW
#define MMI0_PMAXW
Definition: opcodes_mips.h:332
memory_mips.cc
cpu::cpu_id
int cpu_id
Definition: cpu.h:359
MMI3_POR
#define MMI3_POR
Definition: opcodes_mips.h:415
HI6_BLEZ
#define HI6_BLEZ
Definition: opcodes_mips.h:258
HI6_LQ_MDMX
#define HI6_LQ_MDMX
Definition: opcodes_mips.h:429
COP0_EPC
#define COP0_EPC
Definition: cop0.h:140
interrupt::interrupt_deassert
void(* interrupt_deassert)(struct interrupt *)
Definition: interrupt.h:39
EXC3K
#define EXC3K
Definition: mips_cpu_types.h:39
machine::symbol_context
struct symbol_context symbol_context
Definition: machine.h:144
HI6_LH
#define HI6_LH
Definition: opcodes_mips.h:449
MIPS_GPR_SP
#define MIPS_GPR_SP
Definition: cpu_mips.h:163
mips_cpu::cache_secondary_linesize
int cache_secondary_linesize
Definition: cpu_mips.h:265
BSHFL_WSBH
#define BSHFL_WSBH
Definition: opcodes_mips.h:441
HI6_SDC2
#define HI6_SDC2
Definition: opcodes_mips.h:478
settings.h
cop0.h
CONTEXT_BADVPN2_SHIFT
#define CONTEXT_BADVPN2_SHIFT
Definition: cop0.h:80
REGIMM_TLTIU
#define REGIMM_TLTIU
Definition: opcodes_mips.h:242
memory
Definition: memory.h:75
MMI2_PMADDW
#define MMI2_PMADDW
Definition: opcodes_mips.h:355
mips_cpu_type_def::sways
int sways
Definition: cpu_mips.h:65
SPECIAL_DMULT
#define SPECIAL_DMULT
Definition: opcodes_mips.h:197
HI6_NAMES
#define HI6_NAMES
Definition: opcodes_mips.h:60
HI6_LWC1
#define HI6_LWC1
Definition: opcodes_mips.h:465
debug
#define debug
Definition: dev_adb.cc:57
mips_cpu::cache_secondary
int cache_secondary
Definition: cpu_mips.h:262
REGIMM_TGEI
#define REGIMM_TGEI
Definition: opcodes_mips.h:239
SPECIAL_TLTU
#define SPECIAL_TLTU
Definition: opcodes_mips.h:220
machine::cpus
struct cpu ** cpus
Definition: machine.h:140
HI6_SDR
#define HI6_SDR
Definition: opcodes_mips.h:461
SPECIAL2_DCLZ
#define SPECIAL2_DCLZ
Definition: opcodes_mips.h:321
MMU10K
#define MMU10K
Definition: mips_cpu_types.h:47
SPECIAL_SRAV
#define SPECIAL_SRAV
Definition: opcodes_mips.h:176
HI6_ORI
#define HI6_ORI
Definition: opcodes_mips.h:265
SPECIAL_DSUBU
#define SPECIAL_DSUBU
Definition: opcodes_mips.h:216
HI6_BNEL
#define HI6_BNEL
Definition: opcodes_mips.h:306
get_symbol_name
char * get_symbol_name(struct symbol_context *, uint64_t addr, uint64_t *offset)
Definition: symbol.cc:188
MMI0_PPACB
#define MMI0_PPACB
Definition: opcodes_mips.h:351
MIPS_FPU_FCCR
#define MIPS_FPU_FCCR
Definition: cpu_mips.h:93
HI6_ADDIU
#define HI6_ADDIU
Definition: opcodes_mips.h:261
NOT_DELAYED
#define NOT_DELAYED
Definition: cpu.h:305
COP0_ENTRYHI
#define COP0_ENTRYHI
Definition: cop0.h:93
COP0_RANDOM
#define COP0_RANDOM
Definition: cop0.h:56
COP0_NAMES
#define COP0_NAMES
Definition: cop0.h:40
MMI2_PMFLO
#define MMI2_PMFLO
Definition: opcodes_mips.h:360
SPECIAL3_RDHWR
#define SPECIAL3_RDHWR
Definition: opcodes_mips.h:447
mips_cpu::cache_mask
int cache_mask[2]
Definition: cpu_mips.h:272
REGIMM_TLTI
#define REGIMM_TLTI
Definition: opcodes_mips.h:241
SPECIAL_DSRA32
#define SPECIAL_DSRA32
Definition: opcodes_mips.h:232
EXCEPTION_TLBS
#define EXCEPTION_TLBS
Definition: cop0.h:186
XCONTEXT_BADVPN2_MASK
#define XCONTEXT_BADVPN2_MASK
Definition: cop0.h:149
HI6_SWC2
#define HI6_SWC2
Definition: opcodes_mips.h:474
mips_coproc::tlbs
struct mips_tlb * tlbs
Definition: cpu_mips.h:105
CAUSE_EXCCODE_SHIFT
#define CAUSE_EXCCODE_SHIFT
Definition: cop0.h:139
MMI1_PEXTUB
#define MMI1_PEXTUB
Definition: opcodes_mips.h:404
REGIMM_BGEZ
#define REGIMM_BGEZ
Definition: opcodes_mips.h:236
HI6_LL
#define HI6_LL
Definition: opcodes_mips.h:464
REGIMM_BLTZL
#define REGIMM_BLTZL
Definition: opcodes_mips.h:237
mips32_run_instr
int mips32_run_instr(struct cpu *cpu)
mips_cpu_type_def::name
const char * name
Definition: cpu_mips.h:47
N_MIPS_COPROC_REGS
#define N_MIPS_COPROC_REGS
Definition: cpu_mips.h:78
HI6_JAL
#define HI6_JAL
Definition: opcodes_mips.h:255
RANDOM_MASK
#define RANDOM_MASK
Definition: cop0.h:57
coproc_function
void coproc_function(struct cpu *cpu, struct mips_coproc *cp, int cpnr, uint32_t function, int unassemble_only, int running)
Definition: cpu_mips_coproc.cc:1995
mips_cpu_list_available_types
void mips_cpu_list_available_types(void)
Definition: cpu_mips.cc:430
EXCEPTION_MOD
#define EXCEPTION_MOD
Definition: cop0.h:184
SPECIAL2_DCLO
#define SPECIAL2_DCLO
Definition: opcodes_mips.h:322
STATUS_IM_SHIFT
#define STATUS_IM_SHIFT
Definition: cop0.h:118
mips_cpu_type_def::pilinesize
int pilinesize
Definition: cpu_mips.h:58
MIPS_GPR_V0
#define MIPS_GPR_V0
Definition: cpu_mips.h:136
HI6_ANDI
#define HI6_ANDI
Definition: opcodes_mips.h:264
HI6_COP0
#define HI6_COP0
Definition: opcodes_mips.h:268
MMI0_PEXTLB
#define MMI0_PEXTLB
Definition: opcodes_mips.h:350
tmp_mips_head.cc
R2K3K_RANDOM_MASK
#define R2K3K_RANDOM_MASK
Definition: cop0.h:58
CAUSE_EXCCODE_MASK
#define CAUSE_EXCCODE_MASK
Definition: cop0.h:137
STATUS_EXL
#define STATUS_EXL
Definition: cop0.h:125
SPECIAL_SUBU
#define SPECIAL_SUBU
Definition: opcodes_mips.h:204
cpu::instruction_has_delayslot
int(* instruction_has_delayslot)(struct cpu *cpu, unsigned char *ib)
Definition: cpu.h:382
mips_coproc_new
struct mips_coproc * mips_coproc_new(struct cpu *cpu, int coproc_nr)
Definition: cpu_mips_coproc.cc:356
HI6_SLTI
#define HI6_SLTI
Definition: opcodes_mips.h:262
MMI2_PSLLVW
#define MMI2_PSLLVW
Definition: opcodes_mips.h:356
EXCEPTION_CPU
#define EXCEPTION_CPU
Definition: cop0.h:194
SPECIAL_DADD
#define SPECIAL_DADD
Definition: opcodes_mips.h:213
opcodes_mips.h
cpu::byte_order
uint8_t byte_order
Definition: cpu.h:347
mips_cpu::cache_picache_linesize
int cache_picache_linesize
Definition: cpu_mips.h:263
EMUL_BIG_ENDIAN
#define EMUL_BIG_ENDIAN
Definition: misc.h:165
cpu::update_translation_table
void(* update_translation_table)(struct cpu *, uint64_t vaddr_page, unsigned char *host_page, int writeflag, uint64_t paddr_page)
Definition: cpu.h:374
interrupt::extra
void * extra
Definition: interrupt.h:59
COP0_CAUSE
#define COP0_CAUSE
Definition: cop0.h:129
R2K3K_ENTRYLO_D
#define R2K3K_ENTRYLO_D
Definition: cop0.h:74
MMI0_PPACH
#define MMI0_PPACH
Definition: opcodes_mips.h:347
MMI1_PEXTUW
#define MMI1_PEXTUW
Definition: opcodes_mips.h:398
mips32_invalidate_translation_caches
void mips32_invalidate_translation_caches(struct cpu *cpu, uint64_t, int)
translate_v2p_mmu3k
int translate_v2p_mmu3k(struct cpu *cpu, uint64_t vaddr, uint64_t *return_addr, int flags)
MMU32
#define MMU32
Definition: mips_cpu_types.h:48
LE32_TO_HOST
#define LE32_TO_HOST(x)
Definition: misc.h:180
addr
uint32_t addr
Definition: tmp_arm_multi.cc:52
mips_cpu::cache_last_paddr
uint64_t cache_last_paddr[2]
Definition: cpu_mips.h:269
SPECIAL2_CLO
#define SPECIAL2_CLO
Definition: opcodes_mips.h:320
R2K3K_CONTEXT_BADVPN_SHIFT
#define R2K3K_CONTEXT_BADVPN_SHIFT
Definition: cop0.h:82
machine::prom_emulation
int prom_emulation
Definition: machine.h:149
mips_cpu_type_def
Definition: cpu_mips.h:46
CAUSE_BD
#define CAUSE_BD
Definition: cop0.h:130
cpu::mips
struct mips_cpu mips
Definition: cpu.h:446
SPECIAL_DIVU
#define SPECIAL_DIVU
Definition: opcodes_mips.h:196
mips32_update_translation_table
void mips32_update_translation_table(struct cpu *cpu, uint64_t vaddr_page, unsigned char *host_page, int writeflag, uint64_t paddr_page)
HI6_BGTZL
#define HI6_BGTZL
Definition: opcodes_mips.h:308
MMI2_PMULTW
#define MMI2_PMULTW
Definition: opcodes_mips.h:362
SPECIAL3_DEXTU
#define SPECIAL3_DEXTU
Definition: opcodes_mips.h:434
MIPS_FPU_FCIR
#define MIPS_FPU_FCIR
Definition: cpu_mips.h:92
SPECIAL3_DEXT
#define SPECIAL3_DEXT
Definition: opcodes_mips.h:435
BSHFL_DSBH
#define BSHFL_DSBH
Definition: opcodes_mips.h:445
ENTRYHI_R_MASK
#define ENTRYHI_R_MASK
Definition: cop0.h:95
HI6_LWL
#define HI6_LWL
Definition: opcodes_mips.h:450
MIPS_R5900
#define MIPS_R5900
Definition: mips_cpuregs.h:723
ENTRYHI_VPN2_MASK_R10K
#define ENTRYHI_VPN2_MASK_R10K
Definition: cop0.h:98
CPU_SETTINGS_ADD_REGISTER64
#define CPU_SETTINGS_ADD_REGISTER64(name, var)
Definition: cpu.h:489
cpu_mips.h
BE32_TO_HOST
#define BE32_TO_HOST(x)
Definition: misc.h:181
R2K3K_CONTEXT_BADVPN_MASK
#define R2K3K_CONTEXT_BADVPN_MASK
Definition: cop0.h:81
mips_cpu_type_def::isa_level
char isa_level
Definition: cpu_mips.h:53
REGIMM_BGEZALL
#define REGIMM_BGEZALL
Definition: opcodes_mips.h:248
SPECIAL_MTHI
#define SPECIAL_MTHI
Definition: opcodes_mips.h:186
SPECIAL_SLTU
#define SPECIAL_SLTU
Definition: opcodes_mips.h:212
EXCEPTION_VCEI
#define EXCEPTION_VCEI
Definition: cop0.h:197
SPECIAL_MTSA
#define SPECIAL_MTSA
Definition: opcodes_mips.h:210
MMU8K
#define MMU8K
Definition: mips_cpu_types.h:46
COP0_TAGDATA_HI
#define COP0_TAGDATA_HI
Definition: cop0.h:159
HI6_LDR
#define HI6_LDR
Definition: opcodes_mips.h:312
mips_tlb::lo1
uint64_t lo1
Definition: cpu_mips.h:82
HI6_LWU
#define HI6_LWU
Definition: opcodes_mips.h:455
SPECIAL_DSRL32
#define SPECIAL_DSRL32
Definition: opcodes_mips.h:231
SPECIAL_JALR
#define SPECIAL_JALR
Definition: opcodes_mips.h:178
mips_cpu_register_dump
void mips_cpu_register_dump(struct cpu *cpu, int gprs, int coprocs)
Definition: cpu_mips.cc:1523
DEFAULT_PCACHE_SIZE
#define DEFAULT_PCACHE_SIZE
Definition: cpu_mips.h:175
mips_cpu::hi1
uint64_t hi1
Definition: cpu_mips.h:249
COP0_INDEX
#define COP0_INDEX
Definition: cop0.h:50
HI6_SWC1
#define HI6_SWC1
Definition: opcodes_mips.h:473
HI6_SWR
#define HI6_SWR
Definition: opcodes_mips.h:462
cpu::invalidate_code_translation
void(* invalidate_code_translation)(struct cpu *, uint64_t paddr, int flags)
Definition: cpu.h:379
mips_cpu_instruction_has_delayslot
int mips_cpu_instruction_has_delayslot(struct cpu *cpu, unsigned char *ib)
Definition: cpu_mips.cc:452
MMI2_NAMES
#define MMI2_NAMES
Definition: opcodes_mips.h:138
MIPS_FPU_FCSR
#define MIPS_FPU_FCSR
Definition: cpu_mips.h:94
mips_memory_rw
int mips_memory_rw(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags)
SPECIAL_MTLO
#define SPECIAL_MTLO
Definition: opcodes_mips.h:188
REGIMM_TGEIU
#define REGIMM_TGEIU
Definition: opcodes_mips.h:240
HI6_LHU
#define HI6_LHU
Definition: opcodes_mips.h:453
mips_cpu_type_def::scache
int scache
Definition: cpu_mips.h:63
INDEX_MASK
#define INDEX_MASK
Definition: cop0.h:52
mips_cpu_new
int mips_cpu_new(struct cpu *cpu, struct memory *mem, struct machine *machine, int cpu_id, char *cpu_type_name)
Definition: cpu_mips.cc:89
HI6_LW
#define HI6_LW
Definition: opcodes_mips.h:451
MMI3_PNOR
#define MMI3_PNOR
Definition: opcodes_mips.h:416
CAUSE_IV
#define CAUSE_IV
Definition: cop0.h:133
HI6_LLD
#define HI6_LLD
Definition: opcodes_mips.h:468
debugger.h
SPECIAL_TGE
#define SPECIAL_TGE
Definition: opcodes_mips.h:217
SPECIAL2_NAMES
#define SPECIAL2_NAMES
Definition: opcodes_mips.h:97
SPECIAL_DMULTU
#define SPECIAL_DMULTU
Definition: opcodes_mips.h:198
HI6_SC
#define HI6_SC
Definition: opcodes_mips.h:472
BSHFL_SEB
#define BSHFL_SEB
Definition: opcodes_mips.h:442
MMI_MMI1
#define MMI_MMI1
Definition: opcodes_mips.h:387
SPECIAL3_DBSHFL
#define SPECIAL3_DBSHFL
Definition: opcodes_mips.h:444
HI6_BNE
#define HI6_BNE
Definition: opcodes_mips.h:257
MMI1_PMINH
#define MMI1_PMINH
Definition: opcodes_mips.h:394
MMI2_PMULTH
#define MMI2_PMULTH
Definition: opcodes_mips.h:373
strlen
void COMBINE() strlen(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
Definition: cpu_arm_instr.cc:2686
HI6_LDC2
#define HI6_LDC2
Definition: opcodes_mips.h:470
fatal
void fatal(const char *fmt,...)
Definition: main.cc:152
MMI_MMI3
#define MMI_MMI3
Definition: opcodes_mips.h:406
mips_update_translation_table
void mips_update_translation_table(struct cpu *cpu, uint64_t vaddr_page, unsigned char *host_page, int writeflag, uint64_t paddr_page)
MMI0_PEXTLW
#define MMI0_PEXTLW
Definition: opcodes_mips.h:342
BSHFL_SEH
#define BSHFL_SEH
Definition: opcodes_mips.h:443
HI6_REGIMM
#define HI6_REGIMM
Definition: opcodes_mips.h:234
HI6_LWC2
#define HI6_LWC2
Definition: opcodes_mips.h:466
ENTRYLO_D
#define ENTRYLO_D
Definition: cop0.h:67
HI6_LWC3
#define HI6_LWC3
Definition: opcodes_mips.h:467
HI6_DADDIU
#define HI6_DADDIU
Definition: opcodes_mips.h:310
EXCEPTION_ADES
#define EXCEPTION_ADES
Definition: cop0.h:188
HI6_SWC3
#define HI6_SWC3
Definition: opcodes_mips.h:475
SPECIAL_MFHI
#define SPECIAL_MFHI
Definition: opcodes_mips.h:185
SPECIAL_BREAK
#define SPECIAL_BREAK
Definition: opcodes_mips.h:182
HI6_SCD
#define HI6_SCD
Definition: opcodes_mips.h:476
R2K3K_ENTRYLO_N
#define R2K3K_ENTRYLO_N
Definition: cop0.h:73
cpu::cd
union cpu::@1 cd
MMI2_PMSUBW
#define MMI2_PMSUBW
Definition: opcodes_mips.h:358
r3000_cache_line::tag_paddr
uint32_t tag_paddr
Definition: cpu_mips.h:179
SPECIAL_SYSCALL
#define SPECIAL_SYSCALL
Definition: opcodes_mips.h:181
mips_pc_to_pointers
void mips_pc_to_pointers(struct cpu *)
SPECIAL3_DINSU
#define SPECIAL3_DINSU
Definition: opcodes_mips.h:438
machine.h
HI6_CACHE
#define HI6_CACHE
Definition: opcodes_mips.h:463
machine
Definition: machine.h:97
cpu::vaddr_mask
uint64_t vaddr_mask
Definition: cpu.h:365
cpu::name
char * name
Definition: cpu.h:334
R2K3K_CAUSE_EXCCODE_MASK
#define R2K3K_CAUSE_EXCCODE_MASK
Definition: cop0.h:138
mips_run_instr
int mips_run_instr(struct cpu *cpu)
HI6_LB
#define HI6_LB
Definition: opcodes_mips.h:448
R2K3K_ENTRYLO_V
#define R2K3K_ENTRYLO_V
Definition: cop0.h:75
EXCEPTION_NAMES
#define EXCEPTION_NAMES
Definition: cop0.h:176
SPECIAL_NOR
#define SPECIAL_NOR
Definition: opcodes_mips.h:208
quiet_mode
int quiet_mode
Definition: emul.cc:68
SPECIAL_MULT
#define SPECIAL_MULT
Definition: opcodes_mips.h:193
EXCEPTION_VCED
#define EXCEPTION_VCED
Definition: cop0.h:207
CACHE_INSTRUCTION
#define CACHE_INSTRUCTION
Definition: memory.h:122
R2K3K_RANDOM_SHIFT
#define R2K3K_RANDOM_SHIFT
Definition: cop0.h:59
mips_tlb::lo0
uint64_t lo0
Definition: cpu_mips.h:81
MMU3K
#define MMU3K
Definition: mips_cpu_types.h:44
translate_v2p_mmu4100
int translate_v2p_mmu4100(struct cpu *cpu, uint64_t vaddr, uint64_t *return_addr, int flags)
mips_cpu::cache
unsigned char * cache[2]
Definition: cpu_mips.h:267
MMI2_PHMADH
#define MMI2_PHMADH
Definition: opcodes_mips.h:366
ENTRYHI_VPN2_MASK
#define ENTRYHI_VPN2_MASK
Definition: cop0.h:99
SPECIAL3_INS
#define SPECIAL3_INS
Definition: opcodes_mips.h:436
mips_cpu_type_def::picache
int picache
Definition: cpu_mips.h:57
REGIMM_BGEZAL
#define REGIMM_BGEZAL
Definition: opcodes_mips.h:246
MMI0_PEXTLH
#define MMI0_PEXTLH
Definition: opcodes_mips.h:346
mips_cpu::lo1
uint64_t lo1
Definition: cpu_mips.h:250
CAUSE_IP_MASK
#define CAUSE_IP_MASK
Definition: cop0.h:135
CACHE_DATA
#define CACHE_DATA
Definition: memory.h:121
emul.h
R2K3K_ENTRYLO_G
#define R2K3K_ENTRYLO_G
Definition: cop0.h:76
MIPS_R4100
#define MIPS_R4100
Definition: mips_cpuregs.h:707
SPECIAL2_CLZ
#define SPECIAL2_CLZ
Definition: opcodes_mips.h:319
r3000_cache_line::tag_valid
int tag_valid
Definition: cpu_mips.h:180
MMI_MMI0
#define MMI_MMI0
Definition: opcodes_mips.h:328
MMI3_PINTEH
#define MMI3_PINTEH
Definition: opcodes_mips.h:411
SPECIAL_DSUB
#define SPECIAL_DSUB
Definition: opcodes_mips.h:215
MMI0_PPACW
#define MMI0_PPACW
Definition: opcodes_mips.h:343
mips32_pc_to_pointers
void mips32_pc_to_pointers(struct cpu *)
cpu::invalidate_translation_caches
void(* invalidate_translation_caches)(struct cpu *, uint64_t paddr, int flags)
Definition: cpu.h:377
SPECIAL_SUB
#define SPECIAL_SUB
Definition: opcodes_mips.h:203
mips_cpu_type_def::rev
int rev
Definition: cpu_mips.h:48
SPECIAL_SRLV
#define SPECIAL_SRLV
Definition: opcodes_mips.h:175
SPECIAL_NAMES
#define SPECIAL_NAMES
Definition: opcodes_mips.h:76
SPECIAL_TGEU
#define SPECIAL_TGEU
Definition: opcodes_mips.h:218
HI6_ADDI
#define HI6_ADDI
Definition: opcodes_mips.h:260
cpu::is_32bit
uint8_t is_32bit
Definition: cpu.h:350
EXCEPTION_TLBL
#define EXCEPTION_TLBL
Definition: cop0.h:185
SPECIAL_ADD
#define SPECIAL_ADD
Definition: opcodes_mips.h:201
mips_cpu_type_def::exc_model
char exc_model
Definition: cpu_mips.h:51
MMI_MADDU
#define MMI_MADDU
Definition: opcodes_mips.h:326
SPECIAL_DDIVU
#define SPECIAL_DDIVU
Definition: opcodes_mips.h:200
translate_v2p_mmu8k
int translate_v2p_mmu8k(struct cpu *cpu, uint64_t vaddr, uint64_t *return_addr, int flags)
SPECIAL_SRA
#define SPECIAL_SRA
Definition: opcodes_mips.h:172
symbol.h
XCONTEXT_R_SHIFT
#define XCONTEXT_R_SHIFT
Definition: cop0.h:148
HI6_COP2
#define HI6_COP2
Definition: opcodes_mips.h:303
TLB_G
#define TLB_G
Definition: cop0.h:102
cpu.h
SPECIAL3_EXT
#define SPECIAL3_EXT
Definition: opcodes_mips.h:432
mips_cpu_type_def::mmu_model
char mmu_model
Definition: cpu_mips.h:52
SPECIAL_DSLL32
#define SPECIAL_DSLL32
Definition: opcodes_mips.h:229
SPECIAL_JR
#define SPECIAL_JR
Definition: opcodes_mips.h:177
cpu::translate_v2p
int(* translate_v2p)(struct cpu *, uint64_t vaddr, uint64_t *return_paddr, int flags)
Definition: cpu.h:372
REGIMM_SYNCI
#define REGIMM_SYNCI
Definition: opcodes_mips.h:251
SPECIAL_DSRA
#define SPECIAL_DSRA
Definition: opcodes_mips.h:228
SPECIAL2_MUL
#define SPECIAL2_MUL
Definition: opcodes_mips.h:316
mips_cpu::irq_compare
struct interrupt irq_compare
Definition: cpu_mips.h:228
SPECIAL_AND
#define SPECIAL_AND
Definition: opcodes_mips.h:205
HI6_LWR
#define HI6_LWR
Definition: opcodes_mips.h:454
HI6_XORI
#define HI6_XORI
Definition: opcodes_mips.h:266
mips_cpu_dumpinfo
void mips_cpu_dumpinfo(struct cpu *cpu)
Definition: cpu_mips.cc:356
mips_cpu_interrupt_deassert
void mips_cpu_interrupt_deassert(struct interrupt *interrupt)
Definition: cpu_mips.cc:1718
SPECIAL_DSLL
#define SPECIAL_DSLL
Definition: opcodes_mips.h:225
MMI1_PMINW
#define MMI1_PMINW
Definition: opcodes_mips.h:390
R2K3K_ENTRYHI_ASID_SHIFT
#define R2K3K_ENTRYHI_ASID_SHIFT
Definition: cop0.h:107
cpu::mem
struct memory * mem
Definition: cpu.h:362
SPECIAL2_MADDU
#define SPECIAL2_MADDU
Definition: opcodes_mips.h:315
MMI0_PMAXH
#define MMI0_PMAXH
Definition: opcodes_mips.h:336
R2K3K_ENTRYHI_ASID_MASK
#define R2K3K_ENTRYHI_ASID_MASK
Definition: cop0.h:106
SPECIAL_DADDU
#define SPECIAL_DADDU
Definition: opcodes_mips.h:214
REGIMM_TNEI
#define REGIMM_TNEI
Definition: opcodes_mips.h:244
mips_cpu::rmw
int rmw
Definition: cpu_mips.h:232
EMUL_LITTLE_ENDIAN
#define EMUL_LITTLE_ENDIAN
Definition: misc.h:164
SPECIAL_DSRAV
#define SPECIAL_DSRAV
Definition: opcodes_mips.h:192
MMI2_PHMSBH
#define MMI2_PHMSBH
Definition: opcodes_mips.h:370
cpu::machine
struct machine * machine
Definition: cpu.h:328
EXCEPTION_INT
#define EXCEPTION_INT
Definition: cop0.h:183
cpu::delay_slot
uint8_t delay_slot
Definition: cpu.h:356
SPECIAL_MULTU
#define SPECIAL_MULTU
Definition: opcodes_mips.h:194
MMI3_NAMES
#define MMI3_NAMES
Definition: opcodes_mips.h:148
mips_cpu::cop0_config_select1
uint64_t cop0_config_select1
Definition: cpu_mips.h:220
MMI3_PSRAVW
#define MMI3_PSRAVW
Definition: opcodes_mips.h:408
SPECIAL3_DINSM
#define SPECIAL3_DINSM
Definition: opcodes_mips.h:437
reg
#define reg(x)
Definition: tmp_alpha_tail.cc:53
SPECIAL_DDIV
#define SPECIAL_DDIV
Definition: opcodes_mips.h:199
cpu::is_halted
char is_halted
Definition: cpu.h:400
MIPS_CPU_TYPE_DEFS
#define MIPS_CPU_TYPE_DEFS
Definition: mips_cpu_types.h:67
HI6_SQ_SPECIAL3
#define HI6_SQ_SPECIAL3
Definition: opcodes_mips.h:431
mips_cpu::cache_pdcache_linesize
int cache_pdcache_linesize
Definition: cpu_mips.h:264
mips_cpu::cache_picache
int cache_picache
Definition: cpu_mips.h:260
SPECIAL_DSRL
#define SPECIAL_DSRL
Definition: opcodes_mips.h:227
CONTEXT_BADVPN2_MASK_R4100
#define CONTEXT_BADVPN2_MASK_R4100
Definition: cop0.h:79
MMI_MADD
#define MMI_MADD
Definition: opcodes_mips.h:325
MMI2_PMSUBH
#define MMI2_PMSUBH
Definition: opcodes_mips.h:369
REGIMM_TEQI
#define REGIMM_TEQI
Definition: opcodes_mips.h:243
STATUS_BEV
#define STATUS_BEV
Definition: cop0.h:115
HI6_COP3
#define HI6_COP3
Definition: opcodes_mips.h:304
mips_cpu_exception
void mips_cpu_exception(struct cpu *cpu, int exccode, int tlb, uint64_t vaddr, int coproc_nr, uint64_t vaddr_vpn2, int vaddr_asid, int x_64)
Definition: cpu_mips.cc:1740
CAUSE_CE_SHIFT
#define CAUSE_CE_SHIFT
Definition: cop0.h:132
mips32_invalidate_code_translation
void mips32_invalidate_code_translation(struct cpu *cpu, uint64_t, int)
HI6_COP1
#define HI6_COP1
Definition: opcodes_mips.h:302
R2K3K_INDEX_MASK
#define R2K3K_INDEX_MASK
Definition: cop0.h:54
SPECIAL_OR
#define SPECIAL_OR
Definition: opcodes_mips.h:206
symbol
Definition: symbol.h:37
SPECIAL_SYNC
#define SPECIAL_SYNC
Definition: opcodes_mips.h:184
SPECIAL2_MADD
#define SPECIAL2_MADD
Definition: opcodes_mips.h:314
REGIMM_BGEZL
#define REGIMM_BGEZL
Definition: opcodes_mips.h:238
HI6_BLEZL
#define HI6_BLEZL
Definition: opcodes_mips.h:307
store_32bit_word
int store_32bit_word(struct cpu *cpu, uint64_t addr, uint64_t data32)
Definition: memory.cc:783
EXCEPTION_SYS
#define EXCEPTION_SYS
Definition: cop0.h:191
HI6_BEQ
#define HI6_BEQ
Definition: opcodes_mips.h:256
REGIMM_NAMES
#define REGIMM_NAMES
Definition: opcodes_mips.h:70
R2K3K_INDEX_SHIFT
#define R2K3K_INDEX_SHIFT
Definition: cop0.h:55
mips_cpu_type_def::piways
int piways
Definition: cpu_mips.h:59
HI6_BEQL
#define HI6_BEQL
Definition: opcodes_mips.h:305
SPECIAL_XOR
#define SPECIAL_XOR
Definition: opcodes_mips.h:207
SPECIAL3_DEXTM
#define SPECIAL3_DEXTM
Definition: opcodes_mips.h:433
SPECIAL_SLT
#define SPECIAL_SLT
Definition: opcodes_mips.h:211
mips_cpu_disassemble_instr
int mips_cpu_disassemble_instr(struct cpu *cpu, unsigned char *originstr, int running, uint64_t dumpaddr)
Definition: cpu_mips.cc:708
SPECIAL_MOVZ
#define SPECIAL_MOVZ
Definition: opcodes_mips.h:179
CONTEXT_BADVPN2_MASK
#define CONTEXT_BADVPN2_MASK
Definition: cop0.h:78
SPECIAL2_MSUB
#define SPECIAL2_MSUB
Definition: opcodes_mips.h:317
INITIAL_STACK_POINTER
#define INITIAL_STACK_POINTER
Definition: cpu_mips.h:69
HI6_LUI
#define HI6_LUI
Definition: opcodes_mips.h:267
HI6_LDL
#define HI6_LDL
Definition: opcodes_mips.h:311
SPECIAL3_BSHFL
#define SPECIAL3_BSHFL
Definition: opcodes_mips.h:440
REGIMM_BLTZAL
#define REGIMM_BLTZAL
Definition: opcodes_mips.h:245
HI6_SPECIAL
#define HI6_SPECIAL
Definition: opcodes_mips.h:168
mips_cpu::gpr
uint64_t gpr[N_MIPS_GPRS]
Definition: cpu_mips.h:209
mips_cpu::cache_size
int cache_size[2]
Definition: cpu_mips.h:270
SPECIAL_ADDU
#define SPECIAL_ADDU
Definition: opcodes_mips.h:202
cpu::run_instr
int(* run_instr)(struct cpu *cpu)
Definition: cpu.h:367
HI6_LBU
#define HI6_LBU
Definition: opcodes_mips.h:452
SPECIAL_SLL
#define SPECIAL_SLL
Definition: opcodes_mips.h:169
MMI3_PMADDUW
#define MMI3_PMADDUW
Definition: opcodes_mips.h:407
HI6_SH
#define HI6_SH
Definition: opcodes_mips.h:457
mips_tlb::mask
uint64_t mask
Definition: cpu_mips.h:83
HI6_BGTZ
#define HI6_BGTZ
Definition: opcodes_mips.h:259
COP0_BADVADDR
#define COP0_BADVADDR
Definition: cop0.h:91
CAUSE_CE_MASK
#define CAUSE_CE_MASK
Definition: cop0.h:131
interrupt::line
uint32_t line
Definition: interrupt.h:51
XCONTEXT_R_MASK
#define XCONTEXT_R_MASK
Definition: cop0.h:147
MMI2_PINTH
#define MMI2_PINTH
Definition: opcodes_mips.h:361
COP0_WIRED
#define COP0_WIRED
Definition: cop0.h:89
DEBUG_INDENTATION
#define DEBUG_INDENTATION
Definition: misc.h:212
memory_points_to_string
int memory_points_to_string(struct cpu *cpu, struct memory *mem, uint64_t addr, int min_string_length)
Definition: memory.cc:190
interrupt::interrupt_assert
void(* interrupt_assert)(struct interrupt *)
Definition: interrupt.h:38
SPECIAL_MFSA
#define SPECIAL_MFSA
Definition: opcodes_mips.h:209
HI6_SD
#define HI6_SD
Definition: opcodes_mips.h:479
ENTRYHI_ASID
#define ENTRYHI_ASID
Definition: cop0.h:101
HI6_SLTIU
#define HI6_SLTIU
Definition: opcodes_mips.h:263
mips_cpu::cache_tags
void * cache_tags[2]
Definition: cpu_mips.h:268
interrupt_handler_register
void interrupt_handler_register(struct interrupt *templ)
Definition: interrupt.cc:81
COP0_COMPARE
#define COP0_COMPARE
Definition: cop0.h:108
interrupt::name
char * name
Definition: interrupt.h:66
MMI1_PEXTUH
#define MMI1_PEXTUH
Definition: opcodes_mips.h:401
HI6_SDL
#define HI6_SDL
Definition: opcodes_mips.h:460
interrupt
Definition: interrupt.h:36
R2K3K_ENTRYHI_VPN_MASK
#define R2K3K_ENTRYHI_VPN_MASK
Definition: cop0.h:104
MMI3_PMTLO
#define MMI3_PMTLO
Definition: opcodes_mips.h:410
mips_invalidate_translation_caches
void mips_invalidate_translation_caches(struct cpu *cpu, uint64_t, int)
r3000_cache_line
Definition: cpu_mips.h:178
arcbios.h
mips_coproc
Definition: cpu_mips.h:100
tmp_mips_tail.cc
mips_tlb::hi
uint64_t hi
Definition: cpu_mips.h:80
devices.h
HI6_J
#define HI6_J
Definition: opcodes_mips.h:254
mips_cpu::lo
uint64_t lo
Definition: cpu_mips.h:216
mips_cpu_type_def::pdways
int pdways
Definition: cpu_mips.h:62
COP0_CONTEXT
#define COP0_CONTEXT
Definition: cop0.h:77
SPECIAL_DSRLV
#define SPECIAL_DSRLV
Definition: opcodes_mips.h:191
cpu
Definition: cpu.h:326
HI6_LD
#define HI6_LD
Definition: opcodes_mips.h:471
MMI3_PMTHI
#define MMI3_PMTHI
Definition: opcodes_mips.h:409
R2K3K_ENTRYLO_PFN_MASK
#define R2K3K_ENTRYLO_PFN_MASK
Definition: cop0.h:71
IMPOSSIBLE_PADDR
#define IMPOSSIBLE_PADDR
Definition: cpu_mips.h:173
mips_invalidate_code_translation
void mips_invalidate_code_translation(struct cpu *cpu, uint64_t, int)
SPECIAL_ROT_NAMES
#define SPECIAL_ROT_NAMES
Definition: opcodes_mips.h:87
mips_cpu_type_def::slinesize
int slinesize
Definition: cpu_mips.h:64
REGIMM_BLTZ
#define REGIMM_BLTZ
Definition: opcodes_mips.h:235
SPECIAL_SRL
#define SPECIAL_SRL
Definition: opcodes_mips.h:171
MIPS_GPR_ZERO
#define MIPS_GPR_ZERO
Definition: cpu_mips.h:134
N_MIPS_GPRS
#define N_MIPS_GPRS
Definition: cpu_mips.h:115
translate_v2p_generic
int translate_v2p_generic(struct cpu *cpu, uint64_t vaddr, uint64_t *return_addr, int flags)
HI6_SDC1
#define HI6_SDC1
Definition: opcodes_mips.h:477
EXCEPTION_IN_DELAY_SLOT
#define EXCEPTION_IN_DELAY_SLOT
Definition: cpu.h:308
COP0_COUNT
#define COP0_COUNT
Definition: cop0.h:92
SPECIAL_TLT
#define SPECIAL_TLT
Definition: opcodes_mips.h:219
HI6_SPECIAL2
#define HI6_SPECIAL2
Definition: opcodes_mips.h:313
HI6_SB
#define HI6_SB
Definition: opcodes_mips.h:456
SPECIAL2_MSUBU
#define SPECIAL2_MSUBU
Definition: opcodes_mips.h:318
cpu::memory_rw
int(* memory_rw)(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags)
Definition: cpu.h:368
MMI0_NAMES
#define MMI0_NAMES
Definition: opcodes_mips.h:118
MMI_NAMES
#define MMI_NAMES
Definition: opcodes_mips.h:108
SPECIAL_TNE
#define SPECIAL_TNE
Definition: opcodes_mips.h:223
MMI1_NAMES
#define MMI1_NAMES
Definition: opcodes_mips.h:128
mips_cpu_tlbdump
void mips_cpu_tlbdump(struct machine *m, int x, int rawflag)
Definition: cpu_mips.cc:508
HI6_DADDI
#define HI6_DADDI
Definition: opcodes_mips.h:309
ENTRYLO_PFN_SHIFT
#define ENTRYLO_PFN_SHIFT
Definition: cop0.h:64
SPECIAL_DIV
#define SPECIAL_DIV
Definition: opcodes_mips.h:195
memory_conv_to_string
char * memory_conv_to_string(struct cpu *cpu, struct memory *mem, uint64_t addr, char *buf, int bufsize)
Definition: memory.cc:220
SPECIAL_DSLLV
#define SPECIAL_DSLLV
Definition: opcodes_mips.h:189
cpu::path
char * path
Definition: cpu.h:337
SPECIAL3_DINS
#define SPECIAL3_DINS
Definition: opcodes_mips.h:439
DEFAULT_PCACHE_LINESIZE
#define DEFAULT_PCACHE_LINESIZE
Definition: cpu_mips.h:176
cpu::pc
uint64_t pc
Definition: cpu.h:386
mips_cpu_interrupt_assert
void mips_cpu_interrupt_assert(struct interrupt *interrupt)
Definition: cpu_mips.cc:1713
HI6_LDC1
#define HI6_LDC1
Definition: opcodes_mips.h:469
COP0_XCONTEXT
#define COP0_XCONTEXT
Definition: cop0.h:146
memory.h
SPECIAL3_NAMES
#define SPECIAL3_NAMES
Definition: opcodes_mips.h:158
mips_cpu_type_def::nr_of_tlb_entries
int nr_of_tlb_entries
Definition: cpu_mips.h:55
mips_cpu_types.h
mips_cpu_type_def::pdlinesize
int pdlinesize
Definition: cpu_mips.h:61
BSHFL_DSHD
#define BSHFL_DSHD
Definition: opcodes_mips.h:446
REGIMM_BLTZALL
#define REGIMM_BLTZALL
Definition: opcodes_mips.h:247
SPECIAL_SLLV
#define SPECIAL_SLLV
Definition: opcodes_mips.h:173
MIPS_R3000
#define MIPS_R3000
Definition: mips_cpuregs.h:698
CAUSE_IP_SHIFT
#define CAUSE_IP_SHIFT
Definition: cop0.h:136
MMI2_PMFHI
#define MMI2_PMFHI
Definition: opcodes_mips.h:359
debug_indentation
void debug_indentation(int diff)
Definition: main.cc:120
COP0_STATUS
#define COP0_STATUS
Definition: cop0.h:109
COP0_TAGDATA_LO
#define COP0_TAGDATA_LO
Definition: cop0.h:158
machine::ncpus
int ncpus
Definition: machine.h:139
STATUS_FR
#define STATUS_FR
Definition: cop0.h:113
translate_v2p_mmu10k
int translate_v2p_mmu10k(struct cpu *cpu, uint64_t vaddr, uint64_t *return_addr, int flags)
ENTRYLO_PFN_MASK
#define ENTRYLO_PFN_MASK
Definition: cop0.h:63
MMI3_PMULTUW
#define MMI3_PMULTUW
Definition: opcodes_mips.h:412
MMI_MMI2
#define MMI_MMI2
Definition: opcodes_mips.h:354
CHECK_ALLOCATION
#define CHECK_ALLOCATION(ptr)
Definition: misc.h:239

Generated on Tue Aug 25 2020 19:25:06 for GXemul by doxygen 1.8.18