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

Generated on Sun Sep 30 2018 16:05:18 for GXemul by doxygen 1.8.13