cpu_mips.cc Source File

Back to the index.

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

Generated on Fri Dec 7 2018 19:52:23 for GXemul by doxygen 1.8.13