/[gxemul]/trunk/src/cpu_mips.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk/src/cpu_mips.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10 - (hide annotations)
Mon Oct 8 16:18:27 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 119881 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.815 2005/06/27 23:04:35 debug Exp $
20050617	Experimenting some more with netbooting OpenBSD/sgi. Adding
		a hack which allows emulated ethernet networks to be
		distributed across multiple emulator processes.
20050618	Minor updates (documentation, dummy YAMON emulation, etc).
20050620	strcpy/strcat -> strlcpy/strlcat updates.
		Some more progress on evbmips (Malta).
20050621	Adding a section to doc/configfiles.html about ethernet
		emulation across multiple hosts.
		Beginning the work on the ARM translation engine (using the
		dynamic-but-not-binary translation method).
		Fixing a bintrans bug: 0x9fc00000 should always be treated as
		PROM area, just as 0xbfc00000 is.
		Minor progress on Malta emulation (the PCI-ISA bus).
20050622	NetBSD/evbmips can now be installed (using another emulated
		machine) and run (including userland and so on). :-)
		Spliting up the bintrans haddr_entry field into two (one for
		read, one for write). Probably not much of a speed increase,
		though.
		Updating some NetBSD 2.0 -> 2.0.2 in the documentation.
20050623	Minor updates (documentation, the TODO file, etc).
		gzipped kernels are now always automagically gunzipped when
		loaded.
20050624	Adding a dummy Playstation Portable (PSP) mode, just barely
		enough to run Hello World (in weird colors :-).
		Removing the -b command line option; old bintrans is enabled
		by default instead. It makes more sense.
		Trying to finally fix the non-working performance measurement
		thing (instr/second etc).
20050625	Continuing on the essential basics for ARM emulation. Two
		instructions seem to work, a branch and a simple "mov". (The
		mov arguments are not correct yet.) Performance is definitely
		reasonable.
		Various other minor updates.
		Adding the ARM "bl" instruction.
		Adding support for combining multiple ARM instructions into one
		function call. ("mov" + "mov" is the only one implemented so
		far, but it seems to work.)
		Cleaning up some IP32 interrupt things (crime/mace); disabling
		the PS/2 keyboard controller on IP32, so that NetBSD/sgimips
		boots into userland again.
20050626	Finally! NetBSD/sgimips netboots. Adding instructions to
		doc/guestoses.html on how to set up an nfs server etc.
		Various other minor fixes.
		Playstation Portable ".pbp" files can now be used directly.
		(The ELF part of the .pbp is extracted transparently.)
		Converting some sprintf -> snprintf.
		Adding some more instructions to the ARM disassembler.
20050627	More ARM updates. Adding some simple ldr(b), str(b),
		cmps, and conditional branch instructions, enough to run
		a simple Hello World program.
		All ARM instructions are now inlined/generated for all possible
		condition codes.
		Adding add and sub, and more load/store instructions.
		Removing dummy files: cpu_alpha.c, cpu_hppa.c, and cpu_sparc.c.
		Some minor documentation updates; preparing for a 0.3.4
		release. Updating some URLs.

==============  RELEASE 0.3.4  ==============


1 dpavlin 2 /*
2     * Copyright (C) 2003-2005 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 dpavlin 10 * $Id: cpu_mips.c,v 1.46 2005/06/26 22:23:42 debug Exp $
29 dpavlin 2 *
30     * MIPS core CPU emulation.
31     */
32    
33     #include <stdio.h>
34     #include <stdlib.h>
35     #include <string.h>
36     #include <sys/types.h>
37     #include <ctype.h>
38    
39     #include "../config.h"
40    
41    
42     #ifndef ENABLE_MIPS
43    
44    
45     #include "cpu_mips.h"
46    
47     /*
48     * mips_cpu_family_init():
49     *
50     * Bogus function.
51     */
52     int mips_cpu_family_init(struct cpu_family *fp)
53     {
54     return 0;
55     }
56    
57    
58     /* TODO: Maybe it isn't very nice to have these global like this... */
59     void mips_cpu_exception(struct cpu *cpu, int exccode, int tlb, uint64_t vaddr,
60     int coproc_nr, uint64_t vaddr_vpn2, int vaddr_asid, int x_64) { }
61    
62    
63     #else /* ENABLE_MIPS */
64    
65    
66     #include "arcbios.h"
67     #include "bintrans.h"
68     #include "cop0.h"
69     #include "cpu.h"
70     #include "cpu_mips.h"
71     #include "debugger.h"
72     #include "devices.h"
73     #include "emul.h"
74     #include "machine.h"
75     #include "memory.h"
76     #include "mips_cpu_types.h"
77     #include "opcodes_mips.h"
78     #include "symbol.h"
79    
80    
81     extern volatile int single_step;
82     extern int show_opcode_statistics;
83     extern int old_show_trace_tree;
84     extern int old_instruction_trace;
85     extern int old_quiet_mode;
86     extern int quiet_mode;
87    
88     static char *exception_names[] = EXCEPTION_NAMES;
89    
90     static char *hi6_names[] = HI6_NAMES;
91     static char *regimm_names[] = REGIMM_NAMES;
92     static char *special_names[] = SPECIAL_NAMES;
93     static char *special2_names[] = SPECIAL2_NAMES;
94    
95     static char *regnames[] = MIPS_REGISTER_NAMES;
96     static char *cop0_names[] = COP0_NAMES;
97    
98    
99     #include "cpu_mips16.c"
100    
101    
102     /*
103     * regname():
104     *
105     * Convert a register number into either 'r0', 'r31' etc, or a symbolic
106     * name, depending on machine->show_symbolic_register_names.
107     *
108     * NOTE: _NOT_ reentrant.
109     */
110     static char *regname(struct machine *machine, int r)
111     {
112     static char ch[4];
113     ch[3] = ch[2] = '\0';
114    
115     if (r<0 || r>=32)
116 dpavlin 10 strlcpy(ch, "xx", sizeof(ch));
117 dpavlin 2 else if (machine->show_symbolic_register_names)
118 dpavlin 10 strlcpy(ch, regnames[r], sizeof(ch));
119 dpavlin 2 else
120 dpavlin 10 snprintf(ch, sizeof(ch), "r%i", r);
121 dpavlin 2
122     return ch;
123     }
124    
125    
126     /*
127     * mips_cpu_new():
128     *
129     * Create a new MIPS cpu object.
130 dpavlin 10 *
131     * Returns 1 on success, 0 if there was no valid MIPS processor with
132     * a matching name.
133 dpavlin 2 */
134 dpavlin 10 int mips_cpu_new(struct cpu *cpu, struct memory *mem, struct machine *machine,
135 dpavlin 2 int cpu_id, char *cpu_type_name)
136     {
137     int i, found, j, tags_size, n_cache_lines, size_per_cache_line;
138     struct mips_cpu_type_def cpu_type_defs[] = MIPS_CPU_TYPE_DEFS;
139     int64_t secondary_cache_size;
140     int x, linesize;
141    
142     /* Scan the cpu_type_defs list for this cpu type: */
143     i = 0;
144     found = -1;
145     while (i >= 0 && cpu_type_defs[i].name != NULL) {
146     if (strcasecmp(cpu_type_defs[i].name, cpu_type_name) == 0) {
147     found = i;
148     break;
149     }
150     i++;
151     }
152    
153     if (found == -1)
154 dpavlin 10 return 0;
155 dpavlin 2
156     cpu->memory_rw = mips_memory_rw;
157     cpu->cd.mips.cpu_type = cpu_type_defs[found];
158     cpu->name = cpu->cd.mips.cpu_type.name;
159     cpu->byte_order = EMUL_LITTLE_ENDIAN;
160     cpu->cd.mips.gpr[MIPS_GPR_SP] = INITIAL_STACK_POINTER;
161    
162     if (cpu_id == 0)
163     debug("%s", cpu->cd.mips.cpu_type.name);
164    
165     /*
166     * CACHES:
167     *
168     * 1) Use DEFAULT_PCACHE_SIZE and DEFAULT_PCACHE_LINESIZE etc.
169     * 2) If there are specific values defined for this type of cpu,
170     * in its cpu_type substruct, then let's use those.
171     * 3) Values in the emul struct override both of the above.
172     *
173     * Once we've decided which values to use, they are stored in
174     * the emul struct so they can be used from src/machine.c etc.
175     */
176    
177     x = DEFAULT_PCACHE_SIZE;
178     if (cpu->cd.mips.cpu_type.default_pdcache)
179     x = cpu->cd.mips.cpu_type.default_pdcache;
180     if (machine->cache_pdcache == 0)
181     machine->cache_pdcache = x;
182    
183     x = DEFAULT_PCACHE_SIZE;
184     if (cpu->cd.mips.cpu_type.default_picache)
185     x = cpu->cd.mips.cpu_type.default_picache;
186     if (machine->cache_picache == 0)
187     machine->cache_picache = x;
188    
189     if (machine->cache_secondary == 0)
190     machine->cache_secondary = cpu->cd.mips.cpu_type.default_scache;
191    
192     linesize = DEFAULT_PCACHE_LINESIZE;
193     if (cpu->cd.mips.cpu_type.default_pdlinesize)
194     linesize = cpu->cd.mips.cpu_type.default_pdlinesize;
195     if (machine->cache_pdcache_linesize == 0)
196     machine->cache_pdcache_linesize = linesize;
197    
198     linesize = DEFAULT_PCACHE_LINESIZE;
199     if (cpu->cd.mips.cpu_type.default_pilinesize)
200     linesize = cpu->cd.mips.cpu_type.default_pilinesize;
201     if (machine->cache_picache_linesize == 0)
202     machine->cache_picache_linesize = linesize;
203    
204     linesize = 0;
205     if (cpu->cd.mips.cpu_type.default_slinesize)
206     linesize = cpu->cd.mips.cpu_type.default_slinesize;
207     if (machine->cache_secondary_linesize == 0)
208     machine->cache_secondary_linesize = linesize;
209    
210    
211     /*
212     * Primary Data and Instruction caches:
213     */
214     for (i=CACHE_DATA; i<=CACHE_INSTRUCTION; i++) {
215     switch (i) {
216     case CACHE_DATA:
217     x = 1 << machine->cache_pdcache;
218     linesize = 1 << machine->cache_pdcache_linesize;
219     break;
220     case CACHE_INSTRUCTION:
221     x = 1 << machine->cache_picache;
222     linesize = 1 << machine->cache_picache_linesize;
223     break;
224     }
225    
226     /* Primary cache size and linesize: */
227     cpu->cd.mips.cache_size[i] = x;
228     cpu->cd.mips.cache_linesize[i] = linesize;
229    
230     switch (cpu->cd.mips.cpu_type.rev) {
231     case MIPS_R2000:
232     case MIPS_R3000:
233     size_per_cache_line = sizeof(struct r3000_cache_line);
234     break;
235     default:
236     size_per_cache_line = sizeof(struct r4000_cache_line);
237     }
238    
239     cpu->cd.mips.cache_mask[i] = cpu->cd.mips.cache_size[i] - 1;
240     cpu->cd.mips.cache_miss_penalty[i] = 10; /* TODO ? */
241    
242     cpu->cd.mips.cache[i] = malloc(cpu->cd.mips.cache_size[i]);
243     if (cpu->cd.mips.cache[i] == NULL) {
244     fprintf(stderr, "out of memory\n");
245     }
246    
247     n_cache_lines = cpu->cd.mips.cache_size[i] /
248     cpu->cd.mips.cache_linesize[i];
249     tags_size = n_cache_lines * size_per_cache_line;
250    
251     cpu->cd.mips.cache_tags[i] = malloc(tags_size);
252     if (cpu->cd.mips.cache_tags[i] == NULL) {
253     fprintf(stderr, "out of memory\n");
254     }
255    
256     /* Initialize the cache tags: */
257     switch (cpu->cd.mips.cpu_type.rev) {
258     case MIPS_R2000:
259     case MIPS_R3000:
260     for (j=0; j<n_cache_lines; j++) {
261     struct r3000_cache_line *rp;
262     rp = (struct r3000_cache_line *)
263     cpu->cd.mips.cache_tags[i];
264     rp[j].tag_paddr = 0;
265     rp[j].tag_valid = 0;
266     }
267     break;
268     default:
269     ;
270     }
271    
272     /* Set cache_last_paddr to something "impossible": */
273     cpu->cd.mips.cache_last_paddr[i] = IMPOSSIBLE_PADDR;
274     }
275    
276     /*
277     * Secondary cache:
278     */
279     secondary_cache_size = 0;
280     if (machine->cache_secondary)
281     secondary_cache_size = 1 << machine->cache_secondary;
282     /* TODO: linesize... */
283    
284     if (cpu_id == 0) {
285     debug(" (I+D = %i+%i KB",
286     (int)(cpu->cd.mips.cache_size[CACHE_INSTRUCTION] / 1024),
287     (int)(cpu->cd.mips.cache_size[CACHE_DATA] / 1024));
288    
289     if (secondary_cache_size != 0) {
290     debug(", L2 = ");
291     if (secondary_cache_size >= 1048576)
292     debug("%i MB", (int)
293     (secondary_cache_size / 1048576));
294     else
295     debug("%i KB", (int)
296     (secondary_cache_size / 1024));
297     }
298    
299     debug(")");
300     }
301    
302     /* System coprocessor (0), and FPU (1): */
303     cpu->cd.mips.coproc[0] = mips_coproc_new(cpu, 0);
304     cpu->cd.mips.coproc[1] = mips_coproc_new(cpu, 1);
305    
306     /*
307     * Initialize the cpu->cd.mips.pc_last_* cache (a 1-entry cache of the
308     * last program counter value). For pc_last_virtual_page, any
309     * "impossible" value will do. The pc should never ever get this
310     * value. (The other pc_last* variables do not need initialization,
311     * as they are not used before pc_last_virtual_page.)
312     */
313     cpu->cd.mips.pc_last_virtual_page = PC_LAST_PAGE_IMPOSSIBLE_VALUE;
314    
315     switch (cpu->cd.mips.cpu_type.mmu_model) {
316     case MMU3K:
317     cpu->translate_address = translate_address_mmu3k;
318     break;
319     case MMU8K:
320     cpu->translate_address = translate_address_mmu8k;
321     break;
322     case MMU10K:
323     cpu->translate_address = translate_address_mmu10k;
324     break;
325     default:
326     if (cpu->cd.mips.cpu_type.rev == MIPS_R4100)
327     cpu->translate_address = translate_address_mmu4100;
328     else
329     cpu->translate_address = translate_address_generic;
330     }
331    
332 dpavlin 10 return 1;
333 dpavlin 2 }
334    
335    
336     /*
337     * mips_cpu_show_full_statistics():
338     *
339     * Show detailed statistics on opcode usage on each cpu.
340     */
341     void mips_cpu_show_full_statistics(struct machine *m)
342     {
343     int i, s1, s2, iadd = 4;
344    
345     if (m->bintrans_enable)
346     fatal("NOTE: Dynamic binary translation is used; this list"
347     " of opcode usage\n only includes instructions that"
348     " were interpreted manually!\n");
349    
350     for (i=0; i<m->ncpus; i++) {
351     fatal("cpu%i opcode statistics:\n", i);
352     debug_indentation(iadd);
353    
354     for (s1=0; s1<N_HI6; s1++) {
355     if (m->cpus[i]->cd.mips.stats_opcode[s1] > 0)
356     fatal("opcode %02x (%7s): %li\n", s1,
357     hi6_names[s1],
358     m->cpus[i]->cd.mips.stats_opcode[s1]);
359    
360     debug_indentation(iadd);
361     if (s1 == HI6_SPECIAL)
362     for (s2=0; s2<N_SPECIAL; s2++)
363     if (m->cpus[i]->cd.mips.stats__special[
364     s2] > 0)
365     fatal("special %02x (%7s): "
366     "%li\n", s2, special_names[
367     s2], m->cpus[i]->cd.mips.
368     stats__special[s2]);
369     if (s1 == HI6_REGIMM)
370     for (s2=0; s2<N_REGIMM; s2++)
371     if (m->cpus[i]->cd.mips.stats__regimm[
372     s2] > 0)
373     fatal("regimm %02x (%7s): "
374     "%li\n", s2, regimm_names[
375     s2], m->cpus[i]->cd.mips.
376     stats__regimm[s2]);
377     if (s1 == HI6_SPECIAL2)
378     for (s2=0; s2<N_SPECIAL; s2++)
379     if (m->cpus[i]->cd.mips.stats__special2
380     [s2] > 0)
381     fatal("special2 %02x (%7s): "
382     "%li\n", s2,
383     special2_names[s2], m->
384     cpus[i]->cd.mips.
385     stats__special2[s2]);
386     debug_indentation(-iadd);
387     }
388    
389     debug_indentation(-iadd);
390     }
391     }
392    
393    
394     /*
395     * mips_cpu_tlbdump():
396     *
397     * Called from the debugger to dump the TLB in a readable format.
398     * x is the cpu number to dump, or -1 to dump all CPUs.
399     *
400     * If rawflag is nonzero, then the TLB contents isn't formated nicely,
401     * just dumped.
402     */
403     void mips_cpu_tlbdump(struct machine *m, int x, int rawflag)
404     {
405     int i, j;
406    
407     /* Nicely formatted output: */
408     if (!rawflag) {
409     for (i=0; i<m->ncpus; i++) {
410     int pageshift = 12;
411    
412     if (x >= 0 && i != x)
413     continue;
414    
415     if (m->cpus[i]->cd.mips.cpu_type.rev == MIPS_R4100)
416     pageshift = 10;
417    
418     /* Print index, random, and wired: */
419     printf("cpu%i: (", i);
420     switch (m->cpus[i]->cd.mips.cpu_type.isa_level) {
421     case 1:
422     case 2:
423     printf("index=0x%x random=0x%x",
424     (int) ((m->cpus[i]->cd.mips.coproc[0]->
425     reg[COP0_INDEX] & R2K3K_INDEX_MASK)
426     >> R2K3K_INDEX_SHIFT),
427     (int) ((m->cpus[i]->cd.mips.coproc[0]->
428     reg[COP0_RANDOM] & R2K3K_RANDOM_MASK)
429     >> R2K3K_RANDOM_SHIFT));
430     break;
431     default:
432     printf("index=0x%x random=0x%x",
433     (int) (m->cpus[i]->cd.mips.coproc[0]->
434     reg[COP0_INDEX] & INDEX_MASK),
435     (int) (m->cpus[i]->cd.mips.coproc[0]->
436     reg[COP0_RANDOM] & RANDOM_MASK));
437     printf(" wired=0x%llx", (long long)
438     m->cpus[i]->cd.mips.coproc[0]->
439     reg[COP0_WIRED]);
440     }
441    
442     printf(")\n");
443    
444     for (j=0; j<m->cpus[i]->cd.mips.cpu_type.
445     nr_of_tlb_entries; j++) {
446     uint64_t hi,lo0,lo1,mask;
447     hi = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi;
448     lo0 = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0;
449     lo1 = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo1;
450     mask = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].mask;
451    
452     printf("%3i: ", j);
453     switch (m->cpus[i]->cd.mips.cpu_type.mmu_model) {
454     case MMU3K:
455     if (!(lo0 & R2K3K_ENTRYLO_V)) {
456     printf("(invalid)\n");
457     continue;
458     }
459     printf("vaddr=0x%08x ",
460     (int) (hi&R2K3K_ENTRYHI_VPN_MASK));
461     if (lo0 & R2K3K_ENTRYLO_G)
462     printf("(global), ");
463     else
464     printf("(asid %02x),",
465     (int) ((hi & R2K3K_ENTRYHI_ASID_MASK)
466     >> R2K3K_ENTRYHI_ASID_SHIFT));
467     printf(" paddr=0x%08x ",
468     (int) (lo0&R2K3K_ENTRYLO_PFN_MASK));
469     if (lo0 & R2K3K_ENTRYLO_N)
470     printf("N");
471     if (lo0 & R2K3K_ENTRYLO_D)
472     printf("D");
473     printf("\n");
474     break;
475     default:
476     /* TODO: MIPS32 doesn't need 0x16llx */
477     if (m->cpus[i]->cd.mips.cpu_type.mmu_model == MMU10K)
478     printf("vaddr=0x%1x..%011llx ",
479     (int) (hi >> 60),
480     (long long) (hi&ENTRYHI_VPN2_MASK_R10K));
481     else
482     printf("vaddr=0x%1x..%010llx ",
483     (int) (hi >> 60),
484     (long long) (hi&ENTRYHI_VPN2_MASK));
485     if (hi & TLB_G)
486     printf("(global): ");
487     else
488     printf("(asid %02x):",
489     (int) (hi & ENTRYHI_ASID));
490    
491     /* TODO: Coherency bits */
492    
493     if (!(lo0 & ENTRYLO_V))
494     printf(" p0=(invalid) ");
495     else
496     printf(" p0=0x%09llx ", (long long)
497     (((lo0&ENTRYLO_PFN_MASK) >> ENTRYLO_PFN_SHIFT) << pageshift));
498     printf(lo0 & ENTRYLO_D? "D" : " ");
499    
500     if (!(lo1 & ENTRYLO_V))
501     printf(" p1=(invalid) ");
502     else
503     printf(" p1=0x%09llx ", (long long)
504     (((lo1&ENTRYLO_PFN_MASK) >> ENTRYLO_PFN_SHIFT) << pageshift));
505     printf(lo1 & ENTRYLO_D? "D" : " ");
506     mask |= (1 << (pageshift+1)) - 1;
507     switch (mask) {
508     case 0x7ff: printf(" (1KB)"); break;
509     case 0x1fff: printf(" (4KB)"); break;
510     case 0x7fff: printf(" (16KB)"); break;
511     case 0x1ffff: printf(" (64KB)"); break;
512     case 0x7ffff: printf(" (256KB)"); break;
513     case 0x1fffff: printf(" (1MB)"); break;
514     case 0x7fffff: printf(" (4MB)"); break;
515     case 0x1ffffff: printf(" (16MB)"); break;
516     case 0x7ffffff: printf(" (64MB)"); break;
517     default:
518     printf(" (mask=%08x?)", (int)mask);
519     }
520     printf("\n");
521     }
522     }
523     }
524    
525     return;
526     }
527    
528     /* Raw output: */
529     for (i=0; i<m->ncpus; i++) {
530     if (x >= 0 && i != x)
531     continue;
532    
533     /* Print index, random, and wired: */
534     printf("cpu%i: (", i);
535    
536     if (m->cpus[i]->cd.mips.cpu_type.isa_level < 3 ||
537     m->cpus[i]->cd.mips.cpu_type.isa_level == 32)
538     printf("index=0x%08x random=0x%08x",
539     (int)m->cpus[i]->cd.mips.coproc[0]->reg[COP0_INDEX],
540     (int)m->cpus[i]->cd.mips.coproc[0]->reg[COP0_RANDOM]);
541     else
542     printf("index=0x%016llx random=0x%016llx", (long long)
543     m->cpus[i]->cd.mips.coproc[0]->reg[COP0_INDEX],
544     (long long)m->cpus[i]->cd.mips.coproc[0]->reg
545     [COP0_RANDOM]);
546    
547     if (m->cpus[i]->cd.mips.cpu_type.isa_level >= 3)
548     printf(" wired=0x%llx", (long long)
549     m->cpus[i]->cd.mips.coproc[0]->reg[COP0_WIRED]);
550    
551     printf(")\n");
552    
553     for (j=0; j<m->cpus[i]->cd.mips.cpu_type.nr_of_tlb_entries; j++) {
554     if (m->cpus[i]->cd.mips.cpu_type.mmu_model == MMU3K)
555     printf("%3i: hi=0x%08x lo=0x%08x\n",
556     j,
557     (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi,
558     (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0);
559     else if (m->cpus[i]->cd.mips.cpu_type.isa_level < 3 ||
560     m->cpus[i]->cd.mips.cpu_type.isa_level == 32)
561     printf("%3i: hi=0x%08x mask=0x%08x "
562     "lo0=0x%08x lo1=0x%08x\n", j,
563     (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi,
564     (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].mask,
565     (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0,
566     (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo1);
567     else
568     printf("%3i: hi=0x%016llx mask=0x%016llx "
569     "lo0=0x%016llx lo1=0x%016llx\n", j,
570     (long long)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi,
571     (long long)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].mask,
572     (long long)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0,
573     (long long)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo1);
574     }
575     }
576     }
577    
578    
579     /*
580     * mips_cpu_register_match():
581     */
582     void mips_cpu_register_match(struct machine *m, char *name,
583     int writeflag, uint64_t *valuep, int *match_register)
584     {
585     int cpunr = 0;
586    
587     /* CPU number: */
588    
589     /* TODO */
590    
591     /* Register name: */
592     if (strcasecmp(name, "pc") == 0) {
593     if (writeflag) {
594     m->cpus[cpunr]->pc = *valuep;
595     if (m->cpus[cpunr]->cd.mips.delay_slot) {
596     printf("NOTE: Clearing the delay slot"
597     " flag! (It was set before.)\n");
598     m->cpus[cpunr]->cd.mips.delay_slot = 0;
599     }
600     if (m->cpus[cpunr]->cd.mips.nullify_next) {
601     printf("NOTE: Clearing the nullify-ne"
602     "xt flag! (It was set before.)\n");
603     m->cpus[cpunr]->cd.mips.nullify_next = 0;
604     }
605     } else
606     *valuep = m->cpus[cpunr]->pc;
607     *match_register = 1;
608     } else if (strcasecmp(name, "hi") == 0) {
609     if (writeflag)
610     m->cpus[cpunr]->cd.mips.hi = *valuep;
611     else
612     *valuep = m->cpus[cpunr]->cd.mips.hi;
613     *match_register = 1;
614     } else if (strcasecmp(name, "lo") == 0) {
615     if (writeflag)
616     m->cpus[cpunr]->cd.mips.lo = *valuep;
617     else
618     *valuep = m->cpus[cpunr]->cd.mips.lo;
619     *match_register = 1;
620     } else if (name[0] == 'r' && isdigit((int)name[1])) {
621     int nr = atoi(name + 1);
622     if (nr >= 0 && nr < N_MIPS_GPRS) {
623     if (writeflag) {
624     if (nr != 0)
625     m->cpus[cpunr]->cd.mips.gpr[nr] = *valuep;
626     else
627     printf("WARNING: Attempt to modify r0.\n");
628     } else
629     *valuep = m->cpus[cpunr]->cd.mips.gpr[nr];
630     *match_register = 1;
631     }
632     } else {
633     /* Check for a symbolic name such as "t6" or "at": */
634     int nr;
635     for (nr=0; nr<N_MIPS_GPRS; nr++)
636     if (strcmp(name, regnames[nr]) == 0) {
637     if (writeflag) {
638     if (nr != 0)
639     m->cpus[cpunr]->cd.mips.gpr[nr] = *valuep;
640     else
641     printf("WARNING: Attempt to modify r0.\n");
642     } else
643     *valuep = m->cpus[cpunr]->cd.mips.gpr[nr];
644     *match_register = 1;
645     }
646     }
647    
648     if (!(*match_register)) {
649     /* Check for a symbolic coproc0 name: */
650     int nr;
651     for (nr=0; nr<32; nr++)
652     if (strcmp(name, cop0_names[nr]) == 0) {
653     if (writeflag) {
654     coproc_register_write(m->cpus[cpunr],
655     m->cpus[cpunr]->cd.mips.coproc[0], nr,
656 dpavlin 10 valuep, 1, 0);
657 dpavlin 2 } else {
658     /* TODO: Use coproc_register_read instead? */
659     *valuep = m->cpus[cpunr]->cd.mips.coproc[0]->reg[nr];
660     }
661     *match_register = 1;
662     }
663     }
664    
665     /* TODO: Coprocessor 1,2,3 registers. */
666     }
667    
668    
669     /*
670     * cpu_flags():
671     *
672     * Returns a pointer to a string containing "(d)" "(j)" "(dj)" or "",
673     * depending on the cpu's current delay_slot and last_was_jumptoself
674     * flags.
675     */
676     static const char *cpu_flags(struct cpu *cpu)
677     {
678     if (cpu->cd.mips.delay_slot) {
679     if (cpu->cd.mips.last_was_jumptoself)
680     return " (dj)";
681     else
682     return " (d)";
683     } else {
684     if (cpu->cd.mips.last_was_jumptoself)
685     return " (j)";
686     else
687     return "";
688     }
689     }
690    
691    
692     /*
693     * mips_cpu_disassemble_instr():
694     *
695     * Convert an instruction word into human readable format, for instruction
696     * tracing.
697     *
698     * If running is 1, cpu->pc should be the address of the instruction.
699     *
700     * If running is 0, things that depend on the runtime environment (eg.
701     * register contents) will not be shown, and addr will be used instead of
702     * cpu->pc for relative addresses.
703     *
704     * NOTE 2: coprocessor instructions are not decoded nicely yet (TODO)
705     */
706     int mips_cpu_disassemble_instr(struct cpu *cpu, unsigned char *originstr,
707     int running, uint64_t dumpaddr, int bintrans)
708     {
709     int hi6, special6, regimm5;
710     int rt, rd, rs, sa, imm, copz, cache_op, which_cache, showtag;
711     uint64_t addr, offset;
712     uint32_t instrword;
713     unsigned char instr[4];
714     char *symbol;
715    
716     if (running)
717     dumpaddr = cpu->pc;
718    
719 dpavlin 4 if ((dumpaddr & 3) != 0)
720     printf("WARNING: Unaligned address!\n");
721    
722 dpavlin 2 symbol = get_symbol_name(&cpu->machine->symbol_context,
723     dumpaddr, &offset);
724     if (symbol != NULL && offset==0)
725     debug("<%s>\n", symbol);
726    
727     if (cpu->machine->ncpus > 1 && running)
728     debug("cpu%i: ", cpu->cpu_id);
729    
730     if (cpu->cd.mips.cpu_type.isa_level < 3 ||
731     cpu->cd.mips.cpu_type.isa_level == 32)
732     debug("%08x", (int)dumpaddr);
733     else
734     debug("%016llx", (long long)dumpaddr);
735    
736     *((uint32_t *)&instr[0]) = *((uint32_t *)&originstr[0]);
737    
738     /*
739     * The rest of the code is written for little endian,
740     * so swap if necessary:
741     */
742     if (cpu->byte_order == EMUL_BIG_ENDIAN) {
743     int tmp = instr[0]; instr[0] = instr[3];
744     instr[3] = tmp;
745     tmp = instr[1]; instr[1] = instr[2];
746     instr[2] = tmp;
747     }
748    
749     debug(": %02x%02x%02x%02x",
750     instr[3], instr[2], instr[1], instr[0]);
751    
752     if (running)
753     debug("%s", cpu_flags(cpu));
754    
755     debug("\t");
756    
757     if (bintrans && running) {
758     debug("(bintrans)");
759     goto disasm_ret;
760     }
761    
762     /*
763     * Decode the instruction:
764     */
765    
766     if (cpu->cd.mips.nullify_next && running) {
767     debug("(nullified)");
768     goto disasm_ret;
769     }
770    
771     hi6 = (instr[3] >> 2) & 0x3f;
772    
773     switch (hi6) {
774     case HI6_SPECIAL:
775     special6 = instr[0] & 0x3f;
776     switch (special6) {
777     case SPECIAL_SLL:
778     case SPECIAL_SRL:
779     case SPECIAL_SRA:
780     case SPECIAL_DSLL:
781     case SPECIAL_DSRL:
782     case SPECIAL_DSRA:
783     case SPECIAL_DSLL32:
784     case SPECIAL_DSRL32:
785     case SPECIAL_DSRA32:
786     rt = instr[2] & 31;
787     rd = (instr[1] >> 3) & 31;
788     sa = ((instr[1] & 7) << 2) + ((instr[0] >> 6) & 3);
789    
790     if (rd == 0 && special6 == SPECIAL_SLL) {
791     if (sa == 0)
792     debug("nop");
793     else if (sa == 1)
794     debug("ssnop");
795     else
796     debug("nop (weird, sa=%i)", sa);
797     goto disasm_ret;
798     } else
799     debug("%s\t%s,",
800     special_names[special6],
801     regname(cpu->machine, rd));
802     debug("%s,%i", regname(cpu->machine, rt), sa);
803     break;
804     case SPECIAL_DSRLV:
805     case SPECIAL_DSRAV:
806     case SPECIAL_DSLLV:
807     case SPECIAL_SLLV:
808     case SPECIAL_SRAV:
809     case SPECIAL_SRLV:
810     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
811     rt = instr[2] & 31;
812     rd = (instr[1] >> 3) & 31;
813     debug("%s\t%s",
814     special_names[special6], regname(cpu->machine, rd));
815     debug(",%s", regname(cpu->machine, rt));
816     debug(",%s", regname(cpu->machine, rs));
817     break;
818     case SPECIAL_JR:
819     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
820     symbol = get_symbol_name(&cpu->machine->symbol_context,
821     cpu->cd.mips.gpr[rs], &offset);
822     debug("jr\t%s", regname(cpu->machine, rs));
823     if (running && symbol != NULL)
824     debug("\t<%s>", symbol);
825     break;
826     case SPECIAL_JALR:
827     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
828     rd = (instr[1] >> 3) & 31;
829     symbol = get_symbol_name(&cpu->machine->symbol_context,
830     cpu->cd.mips.gpr[rs], &offset);
831     debug("jalr\t%s", regname(cpu->machine, rd));
832     debug(",%s", regname(cpu->machine, rs));
833     if (running && symbol != NULL)
834     debug("\t<%s>", symbol);
835     break;
836     case SPECIAL_MFHI:
837     case SPECIAL_MFLO:
838     rd = (instr[1] >> 3) & 31;
839     debug("%s\t%s", special_names[special6],
840     regname(cpu->machine, rd));
841     break;
842     case SPECIAL_MTLO:
843     case SPECIAL_MTHI:
844     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
845     debug("%s\t%s", special_names[special6],
846     regname(cpu->machine, rs));
847     break;
848     case SPECIAL_ADD:
849     case SPECIAL_ADDU:
850     case SPECIAL_SUB:
851     case SPECIAL_SUBU:
852     case SPECIAL_AND:
853     case SPECIAL_OR:
854     case SPECIAL_XOR:
855     case SPECIAL_NOR:
856     case SPECIAL_SLT:
857     case SPECIAL_SLTU:
858     case SPECIAL_DADD:
859     case SPECIAL_DADDU:
860     case SPECIAL_DSUB:
861     case SPECIAL_DSUBU:
862     case SPECIAL_MOVZ:
863     case SPECIAL_MOVN:
864     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
865     rt = instr[2] & 31;
866     rd = (instr[1] >> 3) & 31;
867     if ((special6 == SPECIAL_ADDU ||
868     special6 == SPECIAL_DADDU ||
869     special6 == SPECIAL_SUBU ||
870     special6 == SPECIAL_DSUBU) && rt == 0) {
871     /* Special case 1: addu/daddu/subu/dsubu with
872     rt = the zero register ==> move */
873     debug("move\t%s", regname(cpu->machine, rd));
874     debug(",%s", regname(cpu->machine, rs));
875     } else if ((special6 == SPECIAL_ADDU ||
876     special6 == SPECIAL_DADDU) && rs == 0) {
877     /* Special case 2: addu/daddu with
878     rs = the zero register ==> move */
879     debug("move\t%s", regname(cpu->machine, rd));
880     debug(",%s", regname(cpu->machine, rt));
881     } else {
882     debug("%s\t%s", special_names[special6],
883     regname(cpu->machine, rd));
884     debug(",%s", regname(cpu->machine, rs));
885     debug(",%s", regname(cpu->machine, rt));
886     }
887     break;
888     case SPECIAL_MULT:
889     case SPECIAL_MULTU:
890     case SPECIAL_DMULT:
891     case SPECIAL_DMULTU:
892     case SPECIAL_DIV:
893     case SPECIAL_DIVU:
894     case SPECIAL_DDIV:
895     case SPECIAL_DDIVU:
896     case SPECIAL_TGE:
897     case SPECIAL_TGEU:
898     case SPECIAL_TLT:
899     case SPECIAL_TLTU:
900     case SPECIAL_TEQ:
901     case SPECIAL_TNE:
902     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
903     rt = instr[2] & 31;
904     rd = (instr[1] >> 3) & 31;
905     if (special6 == SPECIAL_MULT) {
906     if (rd != 0) {
907     debug("mult_xx\t%s",
908     regname(cpu->machine, rd));
909     debug(",%s", regname(cpu->machine, rs));
910     debug(",%s", regname(cpu->machine, rt));
911     goto disasm_ret;
912     }
913     }
914     debug("%s\t%s", special_names[special6],
915     regname(cpu->machine, rs));
916     debug(",%s", regname(cpu->machine, rt));
917     break;
918     case SPECIAL_SYNC:
919     imm = ((instr[1] & 7) << 2) + (instr[0] >> 6);
920     debug("sync\t0x%02x", imm);
921     break;
922     case SPECIAL_SYSCALL:
923     imm = (((instr[3] << 24) + (instr[2] << 16) +
924     (instr[1] << 8) + instr[0]) >> 6) & 0xfffff;
925     if (imm != 0)
926     debug("syscall\t0x%05x", imm);
927     else
928     debug("syscall");
929     break;
930     case SPECIAL_BREAK:
931     /* TODO: imm, as in 'syscall'? */
932     debug("break");
933     break;
934     case SPECIAL_MFSA:
935     rd = (instr[1] >> 3) & 31;
936     debug("mfsa\t%s", regname(cpu->machine, rd));
937     break;
938     case SPECIAL_MTSA:
939     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
940     debug("mtsa\t%s", regname(cpu->machine, rs));
941     break;
942     default:
943     debug("unimplemented special6 = 0x%02x", special6);
944     }
945     break;
946     case HI6_BEQ:
947     case HI6_BEQL:
948     case HI6_BNE:
949     case HI6_BNEL:
950     case HI6_BGTZ:
951     case HI6_BGTZL:
952     case HI6_BLEZ:
953     case HI6_BLEZL:
954     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
955     rt = instr[2] & 31;
956     imm = (instr[1] << 8) + instr[0];
957     if (imm >= 32768)
958     imm -= 65536;
959     addr = (dumpaddr + 4) + (imm << 2);
960     debug("%s\t", hi6_names[hi6]);
961    
962     switch (hi6) {
963     case HI6_BEQ:
964     case HI6_BEQL:
965     case HI6_BNE:
966     case HI6_BNEL:
967     debug("%s,", regname(cpu->machine, rt));
968     }
969    
970     debug("%s,", regname(cpu->machine, rs));
971    
972     if (cpu->cd.mips.cpu_type.isa_level < 3 ||
973     cpu->cd.mips.cpu_type.isa_level == 32)
974     debug("0x%08x", (int)addr);
975     else
976     debug("0x%016llx", (long long)addr);
977    
978     symbol = get_symbol_name(&cpu->machine->symbol_context,
979     addr, &offset);
980     if (symbol != NULL && offset != addr)
981     debug("\t<%s>", symbol);
982     break;
983     case HI6_ADDI:
984     case HI6_ADDIU:
985     case HI6_DADDI:
986     case HI6_DADDIU:
987     case HI6_SLTI:
988     case HI6_SLTIU:
989     case HI6_ANDI:
990     case HI6_ORI:
991     case HI6_XORI:
992     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
993     rt = instr[2] & 31;
994     imm = (instr[1] << 8) + instr[0];
995     if (imm >= 32768)
996     imm -= 65536;
997     debug("%s\t%s,", hi6_names[hi6], regname(cpu->machine, rt));
998     debug("%s,", regname(cpu->machine, rs));
999     if (hi6 == HI6_ANDI || hi6 == HI6_ORI || hi6 == HI6_XORI)
1000     debug("0x%04x", imm & 0xffff);
1001     else
1002     debug("%i", imm);
1003     break;
1004     case HI6_LUI:
1005     rt = instr[2] & 31;
1006     imm = (instr[1] << 8) + instr[0];
1007     debug("lui\t%s,0x%x", regname(cpu->machine, rt), imm);
1008     break;
1009     case HI6_LB:
1010     case HI6_LBU:
1011     case HI6_LH:
1012     case HI6_LHU:
1013     case HI6_LW:
1014     case HI6_LWU:
1015     case HI6_LD:
1016     case HI6_LQ_MDMX:
1017     case HI6_LWC1:
1018     case HI6_LWC2:
1019     case HI6_LWC3:
1020     case HI6_LDC1:
1021     case HI6_LDC2:
1022     case HI6_LL:
1023     case HI6_LLD:
1024     case HI6_SB:
1025     case HI6_SH:
1026     case HI6_SW:
1027     case HI6_SD:
1028     case HI6_SQ:
1029     case HI6_SC:
1030     case HI6_SCD:
1031     case HI6_SWC1:
1032     case HI6_SWC2:
1033     case HI6_SWC3:
1034     case HI6_SDC1:
1035     case HI6_SDC2:
1036     case HI6_LWL:
1037     case HI6_LWR:
1038     case HI6_LDL:
1039     case HI6_LDR:
1040     case HI6_SWL:
1041     case HI6_SWR:
1042     case HI6_SDL:
1043     case HI6_SDR:
1044     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1045     rt = instr[2] & 31;
1046     imm = (instr[1] << 8) + instr[0];
1047     if (imm >= 32768)
1048     imm -= 65536;
1049     symbol = get_symbol_name(&cpu->machine->symbol_context,
1050     cpu->cd.mips.gpr[rs] + imm, &offset);
1051    
1052     /* LWC3 is PREF in the newer ISA levels: */
1053     /* TODO: Which ISAs? cpu->cd.mips.cpu_type.isa_level >= 4? */
1054     if (hi6 == HI6_LWC3) {
1055     debug("pref\t0x%x,%i(%s)",
1056     rt, imm, regname(cpu->machine, rs));
1057    
1058     if (running) {
1059     debug("\t[0x%016llx = %s]",
1060     (long long)(cpu->cd.mips.gpr[rs] + imm));
1061     if (symbol != NULL)
1062     debug(" = %s", symbol);
1063     debug("]");
1064     }
1065     goto disasm_ret;
1066     }
1067    
1068     debug("%s\t", hi6_names[hi6]);
1069    
1070     if (hi6 == HI6_SWC1 || hi6 == HI6_SWC2 || hi6 == HI6_SWC3 ||
1071     hi6 == HI6_SDC1 || hi6 == HI6_SDC2 ||
1072     hi6 == HI6_LWC1 || hi6 == HI6_LWC2 || hi6 == HI6_LWC3 ||
1073     hi6 == HI6_LDC1 || hi6 == HI6_LDC2)
1074     debug("r%i", rt);
1075     else
1076     debug("%s", regname(cpu->machine, rt));
1077    
1078     debug(",%i(%s)", imm, regname(cpu->machine, rs));
1079    
1080     if (running) {
1081     debug("\t[");
1082    
1083     if (cpu->cd.mips.cpu_type.isa_level < 3 ||
1084     cpu->cd.mips.cpu_type.isa_level == 32)
1085     debug("0x%08x", (int)(cpu->cd.mips.gpr[rs] + imm));
1086     else
1087     debug("0x%016llx",
1088     (long long)(cpu->cd.mips.gpr[rs] + imm));
1089    
1090     if (symbol != NULL)
1091     debug(" = %s", symbol);
1092    
1093     debug(", data=");
1094     } else
1095     break;
1096     /* NOTE: No break here (if we are running) as it is up
1097     to the caller to print 'data'. */
1098     return sizeof(instrword);
1099     case HI6_J:
1100     case HI6_JAL:
1101     imm = (((instr[3] & 3) << 24) + (instr[2] << 16) +
1102     (instr[1] << 8) + instr[0]) << 2;
1103     addr = (dumpaddr + 4) & ~((1 << 28) - 1);
1104     addr |= imm;
1105     symbol = get_symbol_name(&cpu->machine->symbol_context,
1106     addr, &offset);
1107     debug("%s\t0x", hi6_names[hi6]);
1108     if (cpu->cd.mips.cpu_type.isa_level < 3 ||
1109     cpu->cd.mips.cpu_type.isa_level == 32)
1110     debug("%08x", (int)addr);
1111     else
1112     debug("%016llx", (long long)addr);
1113     if (symbol != NULL)
1114     debug("\t<%s>", symbol);
1115     break;
1116     case HI6_COP0:
1117     case HI6_COP1:
1118     case HI6_COP2:
1119     case HI6_COP3:
1120     imm = (instr[3] << 24) + (instr[2] << 16) +
1121     (instr[1] << 8) + instr[0];
1122     imm &= ((1 << 26) - 1);
1123    
1124     /* Call coproc_function(), but ONLY disassembly, no exec: */
1125     coproc_function(cpu, cpu->cd.mips.coproc[hi6 - HI6_COP0],
1126     hi6 - HI6_COP0, imm, 1, running);
1127     return sizeof(instrword);
1128     case HI6_CACHE:
1129     rt = ((instr[3] & 3) << 3) + (instr[2] >> 5); /* base */
1130     copz = instr[2] & 31;
1131     imm = (instr[1] << 8) + instr[0];
1132     cache_op = copz >> 2;
1133     which_cache = copz & 3;
1134     showtag = 0;
1135     debug("cache\t0x%02x,0x%04x(%s)", copz, imm,
1136     regname(cpu->machine, rt));
1137     if (which_cache==0) debug(" [ primary I-cache");
1138     if (which_cache==1) debug(" [ primary D-cache");
1139     if (which_cache==2) debug(" [ secondary I-cache");
1140     if (which_cache==3) debug(" [ secondary D-cache");
1141     debug(", ");
1142     if (cache_op==0) debug("index invalidate");
1143     if (cache_op==1) debug("index load tag");
1144     if (cache_op==2) debug("index store tag"), showtag=1;
1145     if (cache_op==3) debug("create dirty exclusive");
1146     if (cache_op==4) debug("hit invalidate");
1147     if (cache_op==5) debug("fill OR hit writeback invalidate");
1148     if (cache_op==6) debug("hit writeback");
1149     if (cache_op==7) debug("hit set virtual");
1150     if (running)
1151     debug(", addr 0x%016llx",
1152     (long long)(cpu->cd.mips.gpr[rt] + imm));
1153     if (showtag)
1154     debug(", taghi=%08lx lo=%08lx",
1155     (long)cpu->cd.mips.coproc[0]->reg[COP0_TAGDATA_HI],
1156     (long)cpu->cd.mips.coproc[0]->reg[COP0_TAGDATA_LO]);
1157     debug(" ]");
1158     break;
1159     case HI6_SPECIAL2:
1160     special6 = instr[0] & 0x3f;
1161     instrword = (instr[3] << 24) + (instr[2] << 16) +
1162     (instr[1] << 8) + instr[0];
1163     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1164     rt = instr[2] & 31;
1165     rd = (instr[1] >> 3) & 31;
1166     if ((instrword & 0xfc0007ffULL) == 0x70000000) {
1167     debug("madd\t%s", regname(cpu->machine, rd));
1168     debug(",%s", regname(cpu->machine, rs));
1169     debug(",%s", regname(cpu->machine, rt));
1170     } else if (special6 == SPECIAL2_MUL) {
1171     /* TODO: this is just a guess, I don't have the
1172     docs in front of me */
1173     debug("mul\t%s", regname(cpu->machine, rd));
1174     debug(",%s", regname(cpu->machine, rs));
1175     debug(",%s", regname(cpu->machine, rt));
1176     } else if (special6 == SPECIAL2_CLZ) {
1177     debug("clz\t%s", regname(cpu->machine, rd));
1178     debug(",%s", regname(cpu->machine, rs));
1179     } else if (special6 == SPECIAL2_CLO) {
1180     debug("clo\t%s", regname(cpu->machine, rd));
1181     debug(",%s", regname(cpu->machine, rs));
1182     } else if (special6 == SPECIAL2_DCLZ) {
1183     debug("dclz\t%s", regname(cpu->machine, rd));
1184     debug(",%s", regname(cpu->machine, rs));
1185     } else if (special6 == SPECIAL2_DCLO) {
1186     debug("dclo\t%s", regname(cpu->machine, rd));
1187     debug(",%s", regname(cpu->machine, rs));
1188     } else if ((instrword & 0xffff07ffULL) == 0x70000209
1189     || (instrword & 0xffff07ffULL) == 0x70000249) {
1190     if (instr[0] == 0x49) {
1191     debug("pmflo\t%s", regname(cpu->machine, rd));
1192     debug(" (rs=%s)", regname(cpu->machine, rs));
1193     } else {
1194     debug("pmfhi\t%s", regname(cpu->machine, rd));
1195     debug(" (rs=%s)", regname(cpu->machine, rs));
1196     }
1197     } else if ((instrword & 0xfc1fffff) == 0x70000269
1198     || (instrword & 0xfc1fffff) == 0x70000229) {
1199     if (instr[0] == 0x69) {
1200     debug("pmtlo\t%s", regname(cpu->machine, rs));
1201     } else {
1202     debug("pmthi\t%s", regname(cpu->machine, rs));
1203     }
1204     } else if ((instrword & 0xfc0007ff) == 0x700004a9) {
1205     debug("por\t%s", regname(cpu->machine, rd));
1206     debug(",%s", regname(cpu->machine, rs));
1207     debug(",%s", regname(cpu->machine, rt));
1208     } else if ((instrword & 0xfc0007ff) == 0x70000488) {
1209     debug("pextlw\t%s", regname(cpu->machine, rd));
1210     debug(",%s", regname(cpu->machine, rs));
1211     debug(",%s", regname(cpu->machine, rt));
1212     } else {
1213     debug("unimplemented special2 = 0x%02x", special6);
1214     }
1215     break;
1216     case HI6_REGIMM:
1217     regimm5 = instr[2] & 0x1f;
1218     switch (regimm5) {
1219     case REGIMM_BLTZ:
1220     case REGIMM_BGEZ:
1221     case REGIMM_BLTZL:
1222     case REGIMM_BGEZL:
1223     case REGIMM_BLTZAL:
1224     case REGIMM_BLTZALL:
1225     case REGIMM_BGEZAL:
1226     case REGIMM_BGEZALL:
1227     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1228     imm = (instr[1] << 8) + instr[0];
1229     if (imm >= 32768)
1230     imm -= 65536;
1231    
1232     debug("%s\t%s,", regimm_names[regimm5],
1233     regname(cpu->machine, rs));
1234    
1235     addr = (dumpaddr + 4) + (imm << 2);
1236    
1237     if (cpu->cd.mips.cpu_type.isa_level < 3 ||
1238     cpu->cd.mips.cpu_type.isa_level == 32)
1239     debug("0x%08x", (int)addr);
1240     else
1241     debug("0x%016llx", (long long)addr);
1242     break;
1243     default:
1244     debug("unimplemented regimm5 = 0x%02x", regimm5);
1245     }
1246     break;
1247     default:
1248     debug("unimplemented hi6 = 0x%02x", hi6);
1249     }
1250    
1251     disasm_ret:
1252     debug("\n");
1253     return sizeof(instrword);
1254     }
1255    
1256    
1257     /*
1258     * mips_cpu_register_dump():
1259     *
1260     * Dump cpu registers in a relatively readable format.
1261     *
1262     * gprs: set to non-zero to dump GPRs and hi/lo/pc
1263     * coprocs: set bit 0..3 to dump registers in coproc 0..3.
1264     */
1265     void mips_cpu_register_dump(struct cpu *cpu, int gprs, int coprocs)
1266     {
1267     int coprocnr, i, bits32;
1268     uint64_t offset;
1269     char *symbol;
1270    
1271     bits32 = (cpu->cd.mips.cpu_type.isa_level < 3 ||
1272     cpu->cd.mips.cpu_type.isa_level == 32)? 1 : 0;
1273    
1274     if (gprs) {
1275     /* Special registers (pc, hi/lo) first: */
1276     symbol = get_symbol_name(&cpu->machine->symbol_context,
1277     cpu->pc, &offset);
1278    
1279     if (bits32)
1280     debug("cpu%i: pc = %08x", cpu->cpu_id, (int)cpu->pc);
1281     else
1282     debug("cpu%i: pc = %016llx",
1283     cpu->cpu_id, (long long)cpu->pc);
1284    
1285     debug(" <%s>\n", symbol != NULL? symbol :
1286     " no symbol ");
1287    
1288     if (bits32)
1289     debug("cpu%i: hi = %08x lo = %08x\n",
1290     cpu->cpu_id, (int)cpu->cd.mips.hi, (int)cpu->cd.mips.lo);
1291     else
1292     debug("cpu%i: hi = %016llx lo = %016llx\n",
1293     cpu->cpu_id, (long long)cpu->cd.mips.hi,
1294     (long long)cpu->cd.mips.lo);
1295    
1296     /* General registers: */
1297     if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
1298     /* 128-bit: */
1299     for (i=0; i<32; i++) {
1300     if ((i & 1) == 0)
1301     debug("cpu%i:", cpu->cpu_id);
1302     debug(" %3s=%016llx%016llx",
1303     regname(cpu->machine, i),
1304     (long long)cpu->cd.mips.gpr_quadhi[i],
1305     (long long)cpu->cd.mips.gpr[i]);
1306     if ((i & 1) == 1)
1307     debug("\n");
1308     }
1309     } else if (bits32) {
1310     /* 32-bit: */
1311     for (i=0; i<32; i++) {
1312     if ((i & 3) == 0)
1313     debug("cpu%i:", cpu->cpu_id);
1314     debug(" %3s = %08x", regname(cpu->machine, i),
1315     (int)cpu->cd.mips.gpr[i]);
1316     if ((i & 3) == 3)
1317     debug("\n");
1318     }
1319     } else {
1320     /* 64-bit: */
1321     for (i=0; i<32; i++) {
1322     if ((i & 1) == 0)
1323     debug("cpu%i:", cpu->cpu_id);
1324     debug(" %3s = %016llx",
1325     regname(cpu->machine, i),
1326     (long long)cpu->cd.mips.gpr[i]);
1327     if ((i & 1) == 1)
1328     debug("\n");
1329     }
1330     }
1331     }
1332    
1333     for (coprocnr=0; coprocnr<4; coprocnr++) {
1334     int nm1 = 1;
1335    
1336     if (bits32)
1337     nm1 = 3;
1338    
1339     if (!(coprocs & (1<<coprocnr)))
1340     continue;
1341     if (cpu->cd.mips.coproc[coprocnr] == NULL) {
1342     debug("cpu%i: no coprocessor %i\n",
1343     cpu->cpu_id, coprocnr);
1344     continue;
1345     }
1346    
1347     /* Coprocessor registers: */
1348     /* TODO: multiple selections per register? */
1349     for (i=0; i<32; i++) {
1350     /* 32-bit: */
1351     if ((i & nm1) == 0)
1352     debug("cpu%i:", cpu->cpu_id);
1353    
1354     if (cpu->machine->show_symbolic_register_names &&
1355     coprocnr == 0)
1356     debug(" %8s", cop0_names[i]);
1357     else
1358     debug(" c%i,%02i", coprocnr, i);
1359    
1360     if (bits32)
1361     debug("=%08x", (int)cpu->cd.mips.coproc[coprocnr]->reg[i]);
1362     else
1363     debug(" = 0x%016llx", (long long)
1364     cpu->cd.mips.coproc[coprocnr]->reg[i]);
1365    
1366     if ((i & nm1) == nm1)
1367     debug("\n");
1368    
1369     /* Skip the last 16 cop0 registers on R3000 etc. */
1370     if (coprocnr == 0 && cpu->cd.mips.cpu_type.isa_level < 3
1371     && i == 15)
1372     i = 31;
1373     }
1374    
1375     /* Floating point control registers: */
1376     if (coprocnr == 1) {
1377     for (i=0; i<32; i++)
1378     switch (i) {
1379     case 0: printf("cpu%i: fcr0 (fcir) = 0x%08x\n",
1380     cpu->cpu_id, (int)cpu->cd.mips.coproc[coprocnr]->fcr[i]);
1381     break;
1382     case 25:printf("cpu%i: fcr25 (fccr) = 0x%08x\n",
1383     cpu->cpu_id, (int)cpu->cd.mips.coproc[coprocnr]->fcr[i]);
1384     break;
1385     case 31:printf("cpu%i: fcr31 (fcsr) = 0x%08x\n",
1386     cpu->cpu_id, (int)cpu->cd.mips.coproc[coprocnr]->fcr[i]);
1387     break;
1388     }
1389     }
1390     }
1391     }
1392    
1393    
1394     /*
1395     * show_trace():
1396     *
1397     * Show trace tree. This function should be called every time
1398     * a function is called. cpu->cd.mips.trace_tree_depth is increased here
1399     * and should not be increased by the caller.
1400     *
1401     * Note: This function should not be called if show_trace_tree == 0.
1402     */
1403     static void show_trace(struct cpu *cpu, uint64_t addr)
1404     {
1405     uint64_t offset;
1406     int x, n_args_to_print;
1407     char strbuf[50];
1408     char *symbol;
1409    
1410     cpu->cd.mips.trace_tree_depth ++;
1411    
1412     if (cpu->machine->ncpus > 1)
1413     debug("cpu%i:", cpu->cpu_id);
1414    
1415     symbol = get_symbol_name(&cpu->machine->symbol_context, addr, &offset);
1416    
1417     for (x=0; x<cpu->cd.mips.trace_tree_depth; x++)
1418     debug(" ");
1419    
1420     /* debug("<%s>\n", symbol!=NULL? symbol : "no symbol"); */
1421    
1422     if (symbol != NULL)
1423     debug("<%s(", symbol);
1424     else {
1425     debug("<0x");
1426     if (cpu->cd.mips.cpu_type.isa_level < 3 ||
1427     cpu->cd.mips.cpu_type.isa_level == 32)
1428     debug("%08x", (int)addr);
1429     else
1430     debug("%016llx", (long long)addr);
1431     debug("(");
1432     }
1433    
1434     /*
1435     * TODO: The number of arguments and the symbol type of each
1436     * argument should be taken from the symbol table, in some way.
1437     *
1438     * The MIPS binary calling convention is that the first 4
1439     * arguments are in registers a0..a3.
1440     *
1441     * Choose a value greater than 4 (eg 5) to print all values in
1442     * the A0..A3 registers and then add a ".." to indicate that
1443     * there might be more arguments.
1444     */
1445     n_args_to_print = 5;
1446    
1447     for (x=0; x<n_args_to_print; x++) {
1448     int64_t d = cpu->cd.mips.gpr[x + MIPS_GPR_A0];
1449    
1450     if (d > -256 && d < 256)
1451     debug("%i", (int)d);
1452     else if (memory_points_to_string(cpu, cpu->mem, d, 1))
1453     debug("\"%s\"", memory_conv_to_string(cpu,
1454     cpu->mem, d, strbuf, sizeof(strbuf)));
1455     else {
1456     if (cpu->cd.mips.cpu_type.isa_level < 3 ||
1457     cpu->cd.mips.cpu_type.isa_level == 32)
1458     debug("0x%x", (int)d);
1459     else
1460     debug("0x%llx", (long long)d);
1461     }
1462    
1463     if (x < n_args_to_print - 1)
1464     debug(",");
1465    
1466     /* Cannot go beyound MIPS_GPR_A3: */
1467     if (x == 3)
1468     break;
1469     }
1470    
1471     if (n_args_to_print > 4)
1472     debug("..");
1473    
1474     debug(")>\n");
1475     }
1476    
1477    
1478     /*
1479     * mips_cpu_interrupt():
1480     *
1481     * Cause an interrupt. If irq_nr is 2..7, then it is a MIPS hardware
1482     * interrupt. 0 and 1 are ignored (software interrupts).
1483     *
1484     * If irq_nr is >= 8, then this function calls md_interrupt().
1485     */
1486     int mips_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)
1487     {
1488     if (irq_nr >= 8) {
1489     if (cpu->machine->md_interrupt != NULL)
1490     cpu->machine->md_interrupt(cpu->machine, cpu, irq_nr, 1);
1491     else
1492     fatal("mips_cpu_interrupt(): irq_nr = %i, but md_interrupt = NULL ?\n", irq_nr);
1493     return 1;
1494     }
1495    
1496     if (irq_nr < 2)
1497     return 0;
1498    
1499     cpu->cd.mips.coproc[0]->reg[COP0_CAUSE] |= ((1 << irq_nr) << STATUS_IM_SHIFT);
1500     cpu->cd.mips.cached_interrupt_is_possible = 1;
1501     return 1;
1502     }
1503    
1504    
1505     /*
1506     * mips_cpu_interrupt_ack():
1507     *
1508     * Acknowledge an interrupt. If irq_nr is 2..7, then it is a MIPS hardware
1509     * interrupt. Interrupts 0..1 are ignored (software interrupts).
1510     *
1511     * If irq_nr is >= 8, then it is machine dependant, and md_interrupt() is
1512     * called.
1513     */
1514     int mips_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)
1515     {
1516     if (irq_nr >= 8) {
1517     if (cpu->machine->md_interrupt != NULL)
1518     cpu->machine->md_interrupt(cpu->machine, cpu, irq_nr, 0);
1519     else
1520     fatal("mips_cpu_interrupt_ack(): irq_nr = %i, but md_interrupt = NULL ?\n", irq_nr);
1521     return 1;
1522     }
1523    
1524     if (irq_nr < 2)
1525     return 0;
1526    
1527     cpu->cd.mips.coproc[0]->reg[COP0_CAUSE] &= ~((1 << irq_nr) << STATUS_IM_SHIFT);
1528     if (!(cpu->cd.mips.coproc[0]->reg[COP0_CAUSE] & STATUS_IM_MASK))
1529     cpu->cd.mips.cached_interrupt_is_possible = 0;
1530    
1531     return 1;
1532     }
1533    
1534    
1535     /*
1536     * mips_cpu_exception():
1537     *
1538     * Cause an exception in a CPU. This sets a couple of coprocessor 0
1539     * registers, and the program counter.
1540     *
1541     * exccode the exception code
1542     * tlb set to non-zero if the exception handler at
1543     * 0x80000000 should be used. (normal = 0x80000180)
1544     * vaddr virtual address (for some exceptions)
1545     * coproc_nr coprocessor number (for some exceptions)
1546     * vaddr_vpn2 vpn2 (for some exceptions)
1547     * vaddr_asid asid (for some exceptions)
1548     * x_64 non-zero for 64-bit mode for R4000-style tlb misses
1549     */
1550     void mips_cpu_exception(struct cpu *cpu, int exccode, int tlb, uint64_t vaddr,
1551     int coproc_nr, uint64_t vaddr_vpn2, int vaddr_asid, int x_64)
1552     {
1553     uint64_t base;
1554     uint64_t *reg = &cpu->cd.mips.coproc[0]->reg[0];
1555     int exc_model = cpu->cd.mips.cpu_type.exc_model;
1556    
1557     if (!quiet_mode) {
1558     uint64_t offset;
1559     int x;
1560     char *symbol = get_symbol_name(
1561     &cpu->machine->symbol_context, cpu->cd.mips.pc_last, &offset);
1562    
1563     debug("[ ");
1564     if (cpu->machine->ncpus > 1)
1565     debug("cpu%i: ", cpu->cpu_id);
1566    
1567     debug("exception %s%s",
1568     exception_names[exccode], tlb? " <tlb>" : "");
1569    
1570     switch (exccode) {
1571     case EXCEPTION_INT:
1572     debug(" cause_im=0x%02x", (int)((reg[COP0_CAUSE] & CAUSE_IP_MASK) >> CAUSE_IP_SHIFT));
1573     break;
1574     case EXCEPTION_SYS:
1575     debug(" v0=%i", (int)cpu->cd.mips.gpr[MIPS_GPR_V0]);
1576     for (x=0; x<4; x++) {
1577     int64_t d = cpu->cd.mips.gpr[MIPS_GPR_A0 + x];
1578     char strbuf[30];
1579    
1580     if (d > -256 && d < 256)
1581     debug(" a%i=%i", x, (int)d);
1582     else if (memory_points_to_string(cpu, cpu->mem, d, 1))
1583     debug(" a%i=\"%s\"", x, memory_conv_to_string(cpu, cpu->mem, d, strbuf, sizeof(strbuf)));
1584     else
1585     debug(" a%i=0x%llx", x, (long long)d);
1586     }
1587     break;
1588     default:
1589     debug(" vaddr=0x%016llx", (long long)vaddr);
1590     }
1591    
1592     debug(" pc=%08llx ", (long long)cpu->cd.mips.pc_last);
1593    
1594     if (symbol != NULL)
1595     debug("<%s> ]\n", symbol);
1596     else
1597     debug("]\n");
1598     }
1599    
1600     if (tlb && vaddr < 0x1000) {
1601     uint64_t offset;
1602 dpavlin 4 char *symbol = get_symbol_name(&cpu->machine->symbol_context,
1603     cpu->cd.mips.pc_last, &offset);
1604 dpavlin 6 fatal("[ ");
1605     if (cpu->machine->ncpus > 1)
1606     fatal("cpu%i: ", cpu->cpu_id);
1607     fatal("warning: LOW reference vaddr=0x%08llx, exception %s, "
1608     "pc=%08llx <%s> ]\n", (long long)vaddr,
1609     exception_names[exccode], (long long)cpu->cd.mips.pc_last,
1610 dpavlin 4 symbol? symbol : "(no symbol)");
1611 dpavlin 8
1612     #ifdef TRACE_NULL_CRASHES
1613     /* This can be useful for debugging kernel bugs: */
1614     {
1615     int i = cpu->trace_null_index;
1616     do {
1617     fatal("TRACE: 0x%016llx\n",
1618     cpu->trace_null_addr[i]);
1619     i ++;
1620     i %= TRACE_NULL_N_ENTRIES;
1621     } while (i != cpu->trace_null_index);
1622     }
1623     cpu->running = 0;
1624     cpu->dead = 1;
1625     #endif
1626 dpavlin 2 }
1627    
1628     /* Clear the exception code bits of the cause register... */
1629     if (exc_model == EXC3K) {
1630     reg[COP0_CAUSE] &= ~R2K3K_CAUSE_EXCCODE_MASK;
1631     #if 0
1632     if (exccode >= 16) {
1633     fatal("exccode = %i (there are only 16 exceptions on R3000 and lower)\n", exccode);
1634     cpu->running = 0;
1635     return;
1636     }
1637     #endif
1638     } else
1639     reg[COP0_CAUSE] &= ~CAUSE_EXCCODE_MASK;
1640    
1641     /* ... and OR in the exception code: */
1642     reg[COP0_CAUSE] |= (exccode << CAUSE_EXCCODE_SHIFT);
1643    
1644     /* Always set CE (according to the R5000 manual): */
1645     reg[COP0_CAUSE] &= ~CAUSE_CE_MASK;
1646     reg[COP0_CAUSE] |= (coproc_nr << CAUSE_CE_SHIFT);
1647    
1648     /* TODO: On R4000, vaddr should NOT be set on bus errors!!! */
1649     #if 0
1650     if (exccode == EXCEPTION_DBE) {
1651     reg[COP0_BADVADDR] = vaddr;
1652     /* sign-extend vaddr, if it is 32-bit */
1653     if ((vaddr >> 32) == 0 && (vaddr & 0x80000000ULL))
1654     reg[COP0_BADVADDR] |=
1655     0xffffffff00000000ULL;
1656     }
1657     #endif
1658    
1659     if (tlb || (exccode >= EXCEPTION_MOD && exccode <= EXCEPTION_ADES) ||
1660     exccode == EXCEPTION_VCEI || exccode == EXCEPTION_VCED) {
1661     reg[COP0_BADVADDR] = vaddr;
1662     #if 1
1663     /* TODO: This should be removed. */
1664     /* sign-extend vaddr, if it is 32-bit */
1665     if ((vaddr >> 32) == 0 && (vaddr & 0x80000000ULL))
1666     reg[COP0_BADVADDR] |=
1667     0xffffffff00000000ULL;
1668     #endif
1669     if (exc_model == EXC3K) {
1670     reg[COP0_CONTEXT] &= ~R2K3K_CONTEXT_BADVPN_MASK;
1671     reg[COP0_CONTEXT] |= ((vaddr_vpn2 << R2K3K_CONTEXT_BADVPN_SHIFT) & R2K3K_CONTEXT_BADVPN_MASK);
1672    
1673     reg[COP0_ENTRYHI] = (vaddr & R2K3K_ENTRYHI_VPN_MASK)
1674     | (vaddr_asid << R2K3K_ENTRYHI_ASID_SHIFT);
1675    
1676     /* Sign-extend: */
1677     reg[COP0_CONTEXT] = (int64_t)(int32_t)reg[COP0_CONTEXT];
1678     reg[COP0_ENTRYHI] = (int64_t)(int32_t)reg[COP0_ENTRYHI];
1679     } else {
1680     if (cpu->cd.mips.cpu_type.rev == MIPS_R4100) {
1681     reg[COP0_CONTEXT] &= ~CONTEXT_BADVPN2_MASK_R4100;
1682     reg[COP0_CONTEXT] |= ((vaddr_vpn2 << CONTEXT_BADVPN2_SHIFT) & CONTEXT_BADVPN2_MASK_R4100);
1683    
1684     /* TODO: fix these */
1685     reg[COP0_XCONTEXT] &= ~XCONTEXT_R_MASK;
1686     reg[COP0_XCONTEXT] &= ~XCONTEXT_BADVPN2_MASK;
1687     reg[COP0_XCONTEXT] |= (vaddr_vpn2 << XCONTEXT_BADVPN2_SHIFT) & XCONTEXT_BADVPN2_MASK;
1688     reg[COP0_XCONTEXT] |= ((vaddr >> 62) & 0x3) << XCONTEXT_R_SHIFT;
1689    
1690     /* reg[COP0_PAGEMASK] = cpu->cd.mips.coproc[0]->tlbs[0].mask & PAGEMASK_MASK; */
1691    
1692     reg[COP0_ENTRYHI] = (vaddr & (ENTRYHI_R_MASK | ENTRYHI_VPN2_MASK | 0x1800)) | vaddr_asid;
1693     } else {
1694     reg[COP0_CONTEXT] &= ~CONTEXT_BADVPN2_MASK;
1695     reg[COP0_CONTEXT] |= ((vaddr_vpn2 << CONTEXT_BADVPN2_SHIFT) & CONTEXT_BADVPN2_MASK);
1696    
1697     reg[COP0_XCONTEXT] &= ~XCONTEXT_R_MASK;
1698     reg[COP0_XCONTEXT] &= ~XCONTEXT_BADVPN2_MASK;
1699     reg[COP0_XCONTEXT] |= (vaddr_vpn2 << XCONTEXT_BADVPN2_SHIFT) & XCONTEXT_BADVPN2_MASK;
1700     reg[COP0_XCONTEXT] |= ((vaddr >> 62) & 0x3) << XCONTEXT_R_SHIFT;
1701    
1702     /* reg[COP0_PAGEMASK] = cpu->cd.mips.coproc[0]->tlbs[0].mask & PAGEMASK_MASK; */
1703    
1704     if (cpu->cd.mips.cpu_type.mmu_model == MMU10K)
1705     reg[COP0_ENTRYHI] = (vaddr & (ENTRYHI_R_MASK | ENTRYHI_VPN2_MASK_R10K)) | vaddr_asid;
1706     else
1707     reg[COP0_ENTRYHI] = (vaddr & (ENTRYHI_R_MASK | ENTRYHI_VPN2_MASK)) | vaddr_asid;
1708     }
1709     }
1710     }
1711    
1712     if (exc_model == EXC4K && reg[COP0_STATUS] & STATUS_EXL) {
1713     /*
1714     * Don't set EPC if STATUS_EXL is set, for R4000 and up.
1715     * This actually happens when running IRIX and Ultrix, when
1716     * they handle interrupts and/or tlb updates, I think, so
1717     * printing this with debug() looks better than with fatal().
1718     */
1719     /* debug("[ warning: cpu%i exception while EXL is set, not setting EPC ]\n", cpu->cpu_id); */
1720     } else {
1721     if (cpu->cd.mips.delay_slot || cpu->cd.mips.nullify_next) {
1722     reg[COP0_EPC] = cpu->cd.mips.pc_last - 4;
1723     reg[COP0_CAUSE] |= CAUSE_BD;
1724    
1725     /* TODO: Should the BD flag actually be set
1726     on nullified slots? */
1727     } else {
1728     reg[COP0_EPC] = cpu->cd.mips.pc_last;
1729     reg[COP0_CAUSE] &= ~CAUSE_BD;
1730     }
1731     }
1732    
1733     cpu->cd.mips.delay_slot = NOT_DELAYED;
1734     cpu->cd.mips.nullify_next = 0;
1735    
1736     /* TODO: This is true for MIPS64, but how about others? */
1737     if (reg[COP0_STATUS] & STATUS_BEV)
1738     base = 0xffffffffbfc00200ULL;
1739     else
1740     base = 0xffffffff80000000ULL;
1741    
1742     switch (exc_model) {
1743     case EXC3K:
1744     /* Userspace tlb, vs others: */
1745     if (tlb && !(vaddr & 0x80000000ULL) &&
1746     (exccode == EXCEPTION_TLBL || exccode == EXCEPTION_TLBS) )
1747     cpu->pc = base + 0x000;
1748     else
1749     cpu->pc = base + 0x080;
1750     break;
1751     default:
1752     /*
1753     * These offsets are according to the MIPS64 manual, but
1754     * should work with R4000 and the rest too (I hope).
1755     *
1756     * 0x000 TLB refill, if EXL=0
1757     * 0x080 64-bit XTLB refill, if EXL=0
1758     * 0x100 cache error (not implemented yet)
1759     * 0x180 general exception
1760     * 0x200 interrupt (if CAUSE_IV is set)
1761     */
1762     if (tlb && (exccode == EXCEPTION_TLBL ||
1763     exccode == EXCEPTION_TLBS) &&
1764     !(reg[COP0_STATUS] & STATUS_EXL)) {
1765     if (x_64)
1766     cpu->pc = base + 0x080;
1767     else
1768     cpu->pc = base + 0x000;
1769     } else {
1770     if (exccode == EXCEPTION_INT &&
1771     (reg[COP0_CAUSE] & CAUSE_IV))
1772     cpu->pc = base + 0x200;
1773     else
1774     cpu->pc = base + 0x180;
1775     }
1776     }
1777    
1778     if (exc_model == EXC3K) {
1779     /* R2000/R3000: Shift the lowest 6 bits to the left two steps: */
1780     reg[COP0_STATUS] =
1781     (reg[COP0_STATUS] & ~0x3f) +
1782     ((reg[COP0_STATUS] & 0xf) << 2);
1783     } else {
1784     /* R4000: */
1785     reg[COP0_STATUS] |= STATUS_EXL;
1786     }
1787    
1788     /* Sign-extend: */
1789     reg[COP0_CAUSE] = (int64_t)(int32_t)reg[COP0_CAUSE];
1790     reg[COP0_STATUS] = (int64_t)(int32_t)reg[COP0_STATUS];
1791     }
1792    
1793    
1794     #ifdef BINTRANS
1795     /*
1796     * mips_cpu_cause_simple_exception():
1797     *
1798     * Useful for causing raw exceptions from bintrans, for example
1799     * SYSCALL or BREAK.
1800     */
1801     void mips_cpu_cause_simple_exception(struct cpu *cpu, int exc_code)
1802     {
1803     mips_cpu_exception(cpu, exc_code, 0, 0, 0, 0, 0, 0);
1804     }
1805     #endif
1806    
1807    
1808     /* Included here for better cache characteristics: */
1809     #include "memory_mips.c"
1810    
1811    
1812     /*
1813     * mips_cpu_run_instr():
1814     *
1815     * Execute one instruction on a cpu.
1816     *
1817     * If we are in a delay slot, set cpu->pc to cpu->cd.mips.delay_jmpaddr
1818     * after the instruction is executed.
1819     *
1820     * Return value is the number of instructions executed during this call,
1821     * 0 if no instruction was executed.
1822     */
1823     int mips_cpu_run_instr(struct emul *emul, struct cpu *cpu)
1824     {
1825     int quiet_mode_cached = quiet_mode;
1826     int instruction_trace_cached = cpu->machine->instruction_trace;
1827     struct mips_coproc *cp0 = cpu->cd.mips.coproc[0];
1828     int i, tmp, ninstrs_executed;
1829     unsigned char instr[4];
1830     uint32_t instrword;
1831     uint64_t cached_pc;
1832     int hi6, special6, regimm5, rd, rs, rt, sa, imm;
1833     int copz, which_cache, cache_op;
1834    
1835     int cond, likely, and_link;
1836    
1837     /* for unaligned load/store */
1838     uint64_t dir, is_left, reg_ofs, reg_dir;
1839    
1840     uint64_t tmpvalue, tmpaddr;
1841    
1842     int cpnr; /* coprocessor nr */
1843    
1844     /* for load/store */
1845     uint64_t addr, value, value_hi, result_value;
1846     int wlen, st, signd, linked;
1847     unsigned char d[16]; /* room for at most 128 bits */
1848    
1849    
1850     /*
1851     * Update Coprocessor 0 registers:
1852     *
1853     * The COUNT register needs to be updated on every [other] instruction.
1854     * The RANDOM register should decrease for every instruction.
1855     */
1856    
1857     if (cpu->cd.mips.cpu_type.exc_model == EXC3K) {
1858     int r = (cp0->reg[COP0_RANDOM] & R2K3K_RANDOM_MASK) >> R2K3K_RANDOM_SHIFT;
1859     r --;
1860     if (r >= cp0->nr_of_tlbs || r < 8)
1861     r = cp0->nr_of_tlbs-1;
1862     cp0->reg[COP0_RANDOM] = r << R2K3K_RANDOM_SHIFT;
1863     } else {
1864     cp0->reg[COP0_RANDOM] --;
1865     if ((int64_t)cp0->reg[COP0_RANDOM] >= cp0->nr_of_tlbs ||
1866     (int64_t)cp0->reg[COP0_RANDOM] < (int64_t) cp0->reg[COP0_WIRED])
1867     cp0->reg[COP0_RANDOM] = cp0->nr_of_tlbs-1;
1868    
1869     /*
1870     * TODO: only increase count every other instruction,
1871     * according to the R4000 manual. But according to the
1872     * R5000 manual: increment every other clock cycle.
1873     * Which one is it? :-)
1874     */
1875     cp0->reg[COP0_COUNT] = (int64_t)(int32_t)(cp0->reg[COP0_COUNT] + 1);
1876    
1877     if (cpu->cd.mips.compare_register_set &&
1878     cp0->reg[COP0_COUNT] == cp0->reg[COP0_COMPARE]) {
1879     mips_cpu_interrupt(cpu, 7);
1880     cpu->cd.mips.compare_register_set = 0;
1881     }
1882     }
1883    
1884    
1885     #ifdef ENABLE_INSTRUCTION_DELAYS
1886     if (cpu->cd.mips.instruction_delay > 0) {
1887     cpu->cd.mips.instruction_delay --;
1888     return 1;
1889     }
1890     #endif
1891    
1892     /* Cache the program counter in a local variable: */
1893     cached_pc = cpu->pc;
1894    
1895 dpavlin 8 #ifdef TRACE_NULL_CRASHES
1896     cpu->trace_null_addr[cpu->trace_null_index] = cached_pc;
1897     cpu->trace_null_index ++;
1898     cpu->trace_null_index %= TRACE_NULL_N_ENTRIES;
1899     #endif
1900    
1901 dpavlin 2 /* Hardwire the zero register to 0: */
1902     cpu->cd.mips.gpr[MIPS_GPR_ZERO] = 0;
1903    
1904     if (cpu->cd.mips.delay_slot) {
1905     if (cpu->cd.mips.delay_slot == DELAYED) {
1906     cached_pc = cpu->pc = cpu->cd.mips.delay_jmpaddr;
1907     cpu->cd.mips.delay_slot = NOT_DELAYED;
1908     } else /* if (cpu->cd.mips.delay_slot == TO_BE_DELAYED) */ {
1909     /* next instruction will be delayed */
1910     cpu->cd.mips.delay_slot = DELAYED;
1911     }
1912     }
1913    
1914     if (cpu->cd.mips.last_was_jumptoself > 0)
1915     cpu->cd.mips.last_was_jumptoself --;
1916    
1917     /* Check PC against breakpoints: */
1918     if (!single_step)
1919     for (i=0; i<cpu->machine->n_breakpoints; i++)
1920     if (cached_pc == cpu->machine->breakpoint_addr[i]) {
1921     fatal("Breakpoint reached, pc=0x");
1922     if (cpu->cd.mips.cpu_type.isa_level < 3 ||
1923     cpu->cd.mips.cpu_type.isa_level == 32)
1924     fatal("%08x", (int)cached_pc);
1925     else
1926     fatal("%016llx", (long long)cached_pc);
1927     fatal("\n");
1928     single_step = 1;
1929     return 0;
1930     }
1931    
1932    
1933     /* Remember where we are, in case of interrupt or exception: */
1934     cpu->cd.mips.pc_last = cached_pc;
1935    
1936     /*
1937     * Any pending interrupts?
1938     *
1939     * If interrupts are enabled, and any interrupt has arrived (ie its
1940     * bit in the cause register is set) and corresponding enable bits
1941     * in the status register are set, then cause an interrupt exception
1942     * instead of executing the current instruction.
1943     *
1944     * NOTE: cached_interrupt_is_possible is set to 1 whenever an
1945     * interrupt bit in the cause register is set to one (in
1946     * mips_cpu_interrupt()) and set to 0 whenever all interrupt bits are
1947     * cleared (in mips_cpu_interrupt_ack()), so we don't need to do a
1948     * full check each time.
1949     */
1950     if (cpu->cd.mips.cached_interrupt_is_possible && !cpu->cd.mips.nullify_next) {
1951     if (cpu->cd.mips.cpu_type.exc_model == EXC3K) {
1952     /* R3000: */
1953     int enabled, mask;
1954     int status = cp0->reg[COP0_STATUS];
1955    
1956     enabled = status & MIPS_SR_INT_IE;
1957     mask = status & cp0->reg[COP0_CAUSE] & STATUS_IM_MASK;
1958     if (enabled && mask) {
1959     mips_cpu_exception(cpu, EXCEPTION_INT, 0, 0, 0, 0, 0, 0);
1960     return 0;
1961     }
1962     } else {
1963     /* R4000 and others: */
1964     int enabled, mask;
1965     int status = cp0->reg[COP0_STATUS];
1966    
1967     enabled = (status & STATUS_IE)
1968     && !(status & STATUS_EXL)
1969     && !(status & STATUS_ERL);
1970    
1971     mask = status & cp0->reg[COP0_CAUSE] & STATUS_IM_MASK;
1972     if (enabled && mask) {
1973     mips_cpu_exception(cpu, EXCEPTION_INT, 0, 0, 0, 0, 0, 0);
1974     return 0;
1975     }
1976     }
1977     }
1978    
1979    
1980     /*
1981 dpavlin 10 * ROM emulation: (0xbfcXXXXX or 0x9fcXXXXX)
1982 dpavlin 2 *
1983     * This assumes that a jal was made to a ROM address,
1984     * and we should return via gpr ra.
1985     */
1986 dpavlin 10 if ((cached_pc & 0xdff00000) == 0x9fc00000 &&
1987 dpavlin 2 cpu->machine->prom_emulation) {
1988 dpavlin 10 int rom_jal = 1, res = 1;
1989 dpavlin 2 switch (cpu->machine->machine_type) {
1990     case MACHINE_DEC:
1991     res = decstation_prom_emul(cpu);
1992     break;
1993     case MACHINE_PS2:
1994     res = playstation2_sifbios_emul(cpu);
1995     break;
1996     case MACHINE_ARC:
1997     case MACHINE_SGI:
1998     res = arcbios_emul(cpu);
1999     break;
2000 dpavlin 10 case MACHINE_EVBMIPS:
2001     res = yamon_emul(cpu);
2002     break;
2003 dpavlin 2 default:
2004     rom_jal = 0;
2005     }
2006    
2007     if (rom_jal) {
2008     /*
2009     * Special hack: If the PROM emulation layer needs
2010     * to loop (for example when emulating blocking
2011     * console input) then we should simply return, so
2012     * that the same PROM routine is called on the next
2013     * round as well.
2014     *
2015     * This still has to count as one or more
2016     * instructions, so 1000 is returned. (Ugly.)
2017     */
2018     if (!res)
2019     return 1000;
2020    
2021     cpu->pc = cpu->cd.mips.gpr[MIPS_GPR_RA];
2022     /* no need to update cached_pc, as we're returning */
2023     cpu->cd.mips.delay_slot = NOT_DELAYED;
2024    
2025     if (!quiet_mode_cached &&
2026     cpu->machine->show_trace_tree)
2027     cpu->cd.mips.trace_tree_depth --;
2028    
2029     /* TODO: how many instrs should this count as? */
2030     return 10;
2031     }
2032     }
2033    
2034     #ifdef ALWAYS_SIGNEXTEND_32
2035     /*
2036     * An extra check for 32-bit mode to make sure that all
2037     * registers are sign-extended: (Slow, but might be useful
2038     * to detect bugs that have to do with sign-extension.)
2039     */
2040     if (cpu->cd.mips.cpu_type.isa_level < 3 || cpu->cd.mips.cpu_type.isa_level == 32) {
2041     int warning = 0;
2042     uint64_t x;
2043    
2044     if (cpu->cd.mips.gpr[0] != 0) {
2045     fatal("\nWARNING: r0 was not zero! (%016llx)\n\n",
2046     (long long)cpu->cd.mips.gpr[0]);
2047     cpu->cd.mips.gpr[0] = 0;
2048     warning = 1;
2049     }
2050    
2051     if (cpu->pc != (int64_t)(int32_t)cpu->pc) {
2052     fatal("\nWARNING: pc was not sign-extended correctly"
2053     " (%016llx)\n\n", (long long)cpu->pc);
2054     cpu->pc = (int64_t)(int32_t)cpu->pc;
2055     warning = 1;
2056     }
2057    
2058     if (cpu->cd.mips.pc_last != (int64_t)(int32_t)cpu->cd.mips.pc_last) {
2059     fatal("\nWARNING: pc_last was not sign-extended correc"
2060     "tly (%016llx)\n\n", (long long)cpu->cd.mips.pc_last);
2061     cpu->cd.mips.pc_last = (int64_t)(int32_t)cpu->cd.mips.pc_last;
2062     warning = 1;
2063     }
2064    
2065     /* Sign-extend ALL registers, including coprocessor registers and tlbs: */
2066     for (i=1; i<32; i++) {
2067     x = cpu->cd.mips.gpr[i];
2068     cpu->cd.mips.gpr[i] &= 0xffffffff;
2069     if (cpu->cd.mips.gpr[i] & 0x80000000ULL)
2070     cpu->cd.mips.gpr[i] |= 0xffffffff00000000ULL;
2071     if (x != cpu->cd.mips.gpr[i]) {
2072     fatal("\nWARNING: r%i (%s) was not sign-"
2073     "extended correctly (%016llx != "
2074     "%016llx)\n\n", i, regname(cpu->machine, i),
2075     (long long)x, (long long)cpu->cd.mips.gpr[i]);
2076     warning = 1;
2077     }
2078     }
2079     for (i=0; i<32; i++) {
2080     x = cpu->cd.mips.coproc[0]->reg[i];
2081     cpu->cd.mips.coproc[0]->reg[i] &= 0xffffffffULL;
2082     if (cpu->cd.mips.coproc[0]->reg[i] & 0x80000000ULL)
2083     cpu->cd.mips.coproc[0]->reg[i] |=
2084     0xffffffff00000000ULL;
2085     if (x != cpu->cd.mips.coproc[0]->reg[i]) {
2086     fatal("\nWARNING: cop0,r%i was not sign-extended correctly (%016llx != %016llx)\n\n",
2087     i, (long long)x, (long long)cpu->cd.mips.coproc[0]->reg[i]);
2088     warning = 1;
2089     }
2090     }
2091     for (i=0; i<cpu->cd.mips.coproc[0]->nr_of_tlbs; i++) {
2092     x = cpu->cd.mips.coproc[0]->tlbs[i].hi;
2093     cpu->cd.mips.coproc[0]->tlbs[i].hi &= 0xffffffffULL;
2094     if (cpu->cd.mips.coproc[0]->tlbs[i].hi & 0x80000000ULL)
2095     cpu->cd.mips.coproc[0]->tlbs[i].hi |=
2096     0xffffffff00000000ULL;
2097     if (x != cpu->cd.mips.coproc[0]->tlbs[i].hi) {
2098     fatal("\nWARNING: tlb[%i].hi was not sign-extended correctly (%016llx != %016llx)\n\n",
2099     i, (long long)x, (long long)cpu->cd.mips.coproc[0]->tlbs[i].hi);
2100     warning = 1;
2101     }
2102    
2103     x = cpu->cd.mips.coproc[0]->tlbs[i].lo0;
2104     cpu->cd.mips.coproc[0]->tlbs[i].lo0 &= 0xffffffffULL;
2105     if (cpu->cd.mips.coproc[0]->tlbs[i].lo0 & 0x80000000ULL)
2106     cpu->cd.mips.coproc[0]->tlbs[i].lo0 |=
2107     0xffffffff00000000ULL;
2108     if (x != cpu->cd.mips.coproc[0]->tlbs[i].lo0) {
2109     fatal("\nWARNING: tlb[%i].lo0 was not sign-extended correctly (%016llx != %016llx)\n\n",
2110     i, (long long)x, (long long)cpu->cd.mips.coproc[0]->tlbs[i].lo0);
2111     warning = 1;
2112     }
2113     }
2114    
2115     if (warning) {
2116     fatal("Halting. pc = %016llx\n", (long long)cpu->pc);
2117     cpu->running = 0;
2118     }
2119     }
2120     #endif
2121    
2122     PREFETCH(cpu->cd.mips.pc_last_host_4k_page + (cached_pc & 0xfff));
2123    
2124     #ifdef HALT_IF_PC_ZERO
2125     /* Halt if PC = 0: */
2126     if (cached_pc == 0) {
2127     debug("cpu%i: pc=0, halting\n", cpu->cpu_id);
2128     cpu->running = 0;
2129     return 0;
2130     }
2131     #endif
2132    
2133    
2134    
2135     #ifdef BINTRANS
2136 dpavlin 4 if ((single_step || instruction_trace_cached)
2137 dpavlin 2 && cpu->machine->bintrans_enable)
2138     cpu->cd.mips.dont_run_next_bintrans = 1;
2139     #endif
2140    
2141    
2142     if (!quiet_mode_cached) {
2143     /* Dump CPU registers for debugging: */
2144     if (cpu->machine->register_dump) {
2145     debug("\n");
2146     mips_cpu_register_dump(cpu, 1, 0x1);
2147     }
2148    
2149     /* Trace tree: */
2150     if (cpu->machine->show_trace_tree && cpu->cd.mips.show_trace_delay > 0) {
2151     cpu->cd.mips.show_trace_delay --;
2152     if (cpu->cd.mips.show_trace_delay == 0)
2153     show_trace(cpu, cpu->cd.mips.show_trace_addr);
2154     }
2155     }
2156    
2157     #ifdef MFHILO_DELAY
2158     /* Decrease the MFHI/MFLO delays: */
2159     if (cpu->mfhi_delay > 0)
2160     cpu->mfhi_delay--;
2161     if (cpu->mflo_delay > 0)
2162     cpu->mflo_delay--;
2163     #endif
2164    
2165     /* Read an instruction from memory: */
2166     #ifdef ENABLE_MIPS16
2167     if (cpu->cd.mips.mips16 && (cached_pc & 1)) {
2168     /* 16-bit instruction word: */
2169     unsigned char instr16[2];
2170     int mips16_offset = 0;
2171    
2172     if (!cpu->memory_rw(cpu, cpu->mem, cached_pc ^ 1, &instr16[0],
2173     sizeof(instr16), MEM_READ, CACHE_INSTRUCTION))
2174     return 0;
2175    
2176     /* TODO: If Reverse-endian is set in the status cop0 register, and
2177     we are in usermode, then reverse endianness! */
2178    
2179     /* The rest of the code is written for little endian, so swap if necessary: */
2180     if (cpu->byte_order == EMUL_BIG_ENDIAN) {
2181     int tmp;
2182     tmp = instr16[0]; instr16[0] = instr16[1]; instr16[1] = tmp;
2183     }
2184    
2185     cpu->cd.mips.mips16_extend = 0;
2186    
2187     /*
2188     * Translate into 32-bit instruction, little endian (instr[3..0]):
2189     *
2190     * This ugly loop is necessary because if we would get an exception between
2191     * reading an extend instruction and the next instruction, and execution
2192     * continues on the second instruction, the extend data would be lost. So the
2193     * entire instruction (the two parts) need to be read in. If an exception is
2194     * caused, it will appear as if it was caused when reading the extend instruction.
2195     */
2196     while (mips16_to_32(cpu, instr16, instr) == 0) {
2197     if (instruction_trace_cached)
2198     debug("cpu%i @ %016llx: %02x%02x\t\t\textend\n",
2199     cpu->cpu_id, (cpu->cd.mips.pc_last ^ 1) + mips16_offset,
2200     instr16[1], instr16[0]);
2201    
2202     /* instruction with extend: */
2203     mips16_offset += 2;
2204     if (!cpu->memory_rw(cpu, cpu->mem, (cached_pc ^ 1) +
2205     mips16_offset, &instr16[0], sizeof(instr16),
2206     MEM_READ, CACHE_INSTRUCTION))
2207     return 0;
2208    
2209     if (cpu->byte_order == EMUL_BIG_ENDIAN) {
2210     int tmp;
2211     tmp = instr16[0]; instr16[0] = instr16[1]; instr16[1] = tmp;
2212     }
2213     }
2214    
2215     /* TODO: bintrans like in 32-bit mode? */
2216    
2217     /* Advance the program counter: */
2218     cpu->pc += sizeof(instr16) + mips16_offset;
2219     cached_pc = cpu->pc;
2220    
2221     if (instruction_trace_cached) {
2222     uint64_t offset;
2223     char *symbol = get_symbol_name(&cpu->machine->
2224     symbol_context, cpu->cd.mips.pc_last ^ 1, &offset);
2225     if (symbol != NULL && offset==0)
2226     debug("<%s>\n", symbol);
2227    
2228     debug("cpu%i @ %016llx: %02x%02x => %02x%02x%02x%02x%s\t",
2229     cpu->cpu_id, (cpu->cd.mips.pc_last ^ 1) + mips16_offset,
2230     instr16[1], instr16[0],
2231     instr[3], instr[2], instr[1], instr[0],
2232     cpu_flags(cpu));
2233     }
2234     } else
2235     #endif
2236     {
2237     /*
2238     * Fetch a 32-bit instruction word from memory:
2239     *
2240     * 1) The special case of reading an instruction from the
2241     * same host RAM page as the last one is handled here,
2242     * to gain a little bit performance.
2243     *
2244     * 2) Fallback to reading from memory the usual way.
2245     */
2246     if (cpu->cd.mips.pc_last_host_4k_page != NULL &&
2247     (cached_pc & ~0xfff) == cpu->cd.mips.pc_last_virtual_page) {
2248     /* NOTE: This only works on the host if offset is
2249     aligned correctly! (TODO) */
2250     *(uint32_t *)instr = *(uint32_t *)
2251     (cpu->cd.mips.pc_last_host_4k_page + (cached_pc & 0xfff));
2252     #ifdef BINTRANS
2253     cpu->cd.mips.pc_bintrans_paddr_valid = 1;
2254     cpu->cd.mips.pc_bintrans_paddr =
2255     cpu->cd.mips.pc_last_physical_page | (cached_pc & 0xfff);
2256     cpu->cd.mips.pc_bintrans_host_4kpage = cpu->cd.mips.pc_last_host_4k_page;
2257     #endif
2258     } else {
2259     if (!cpu->memory_rw(cpu, cpu->mem, cached_pc, &instr[0],
2260     sizeof(instr), MEM_READ, CACHE_INSTRUCTION))
2261     return 0;
2262     }
2263    
2264     #ifdef BINTRANS
2265     if (cpu->cd.mips.dont_run_next_bintrans) {
2266     cpu->cd.mips.dont_run_next_bintrans = 0;
2267     } else if (cpu->machine->bintrans_enable &&
2268     cpu->cd.mips.pc_bintrans_paddr_valid) {
2269     int res;
2270     cpu->cd.mips.bintrans_instructions_executed = 0;
2271    
2272     res = bintrans_attempt_translate(cpu,
2273     cpu->cd.mips.pc_bintrans_paddr);
2274    
2275     if (res >= 0) {
2276     /* debug("BINTRANS translation + hit,"
2277     " pc = %016llx\n", (long long)cached_pc); */
2278     if (res > 0 || cpu->pc != cached_pc) {
2279     if (instruction_trace_cached)
2280     mips_cpu_disassemble_instr(cpu, instr, 1, 0, 1);
2281     if (res & BINTRANS_DONT_RUN_NEXT)
2282     cpu->cd.mips.dont_run_next_bintrans = 1;
2283     res &= BINTRANS_N_MASK;
2284    
2285     if (cpu->cd.mips.cpu_type.exc_model != EXC3K) {
2286     int x = cp0->reg[COP0_COUNT], y = cp0->reg[COP0_COMPARE];
2287     int diff = x - y;
2288     if (diff < 0 && diff + (res-1) >= 0
2289     && cpu->cd.mips.compare_register_set) {
2290     mips_cpu_interrupt(cpu, 7);
2291     cpu->cd.mips.compare_register_set = 0;
2292     }
2293    
2294     cp0->reg[COP0_COUNT] = (int64_t)
2295     (int32_t)(cp0->reg[COP0_COUNT] + res-1);
2296     }
2297    
2298     return res;
2299     }
2300     }
2301     }
2302     #endif
2303    
2304     if (instruction_trace_cached)
2305     mips_cpu_disassemble_instr(cpu, instr, 1, 0, 0);
2306    
2307     /* Advance the program counter: */
2308     cpu->pc += sizeof(instr);
2309     cached_pc = cpu->pc;
2310    
2311     /*
2312     * TODO: If Reverse-endian is set in the status cop0 register
2313     * and we are in usermode, then reverse endianness!
2314     */
2315    
2316     /*
2317     * The rest of the code is written for little endian, so
2318     * swap if necessary:
2319     */
2320     if (cpu->byte_order == EMUL_BIG_ENDIAN) {
2321     instrword = instr[0]; instr[0] = instr[3];
2322     instr[3] = instrword;
2323     instrword = instr[1]; instr[1] = instr[2];
2324     instr[2] = instrword;
2325     }
2326     }
2327    
2328    
2329     /*
2330     * Nullify this instruction? (Set by a previous branch-likely
2331     * instruction.)
2332     *
2333     * Note: The return value is 1, even if no instruction was actually
2334     * executed.
2335     */
2336     if (cpu->cd.mips.nullify_next) {
2337     cpu->cd.mips.nullify_next = 0;
2338     return 1;
2339     }
2340    
2341    
2342     /*
2343     * Execute the instruction:
2344     */
2345    
2346     /* Get the top 6 bits of the instruction: */
2347     hi6 = instr[3] >> 2; /* & 0x3f */
2348    
2349     if (show_opcode_statistics)
2350     cpu->cd.mips.stats_opcode[hi6] ++;
2351    
2352     switch (hi6) {
2353     case HI6_SPECIAL:
2354     special6 = instr[0] & 0x3f;
2355    
2356     if (show_opcode_statistics)
2357     cpu->cd.mips.stats__special[special6] ++;
2358    
2359     switch (special6) {
2360     case SPECIAL_SLL:
2361     case SPECIAL_SRL:
2362     case SPECIAL_SRA:
2363     case SPECIAL_DSLL:
2364     case SPECIAL_DSRL:
2365     case SPECIAL_DSRA:
2366     case SPECIAL_DSLL32:
2367     case SPECIAL_DSRL32:
2368     case SPECIAL_DSRA32:
2369     rt = instr[2] & 31;
2370     rd = (instr[1] >> 3) & 31;
2371     sa = ((instr[1] & 7) << 2) + ((instr[0] >> 6) & 3);
2372    
2373     /*
2374     * Check for NOP:
2375     *
2376     * The R4000 manual says that a shift amount of zero
2377     * is treated as a nop by some assemblers. Checking
2378     * for sa == 0 here would not be correct, though,
2379     * because instructions such as sll r3,r4,0 are
2380     * possible, and are definitely not a nop.
2381     * Instead, check if the destination register is r0.
2382     *
2383     * TODO: ssnop should wait until the _next_
2384     * cycle boundary, or something like that. The
2385     * code here is incorrect.
2386     */
2387     if (rd == 0 && special6 == SPECIAL_SLL) {
2388     if (sa == 1) {
2389     /* ssnop */
2390     #ifdef ENABLE_INSTRUCTION_DELAYS
2391     cpu->cd.mips.instruction_delay +=
2392     cpu->cd.mips.cpu_type.
2393     instrs_per_cycle - 1;
2394     #endif
2395     }
2396     return 1;
2397     }
2398    
2399     if (special6 == SPECIAL_SLL) {
2400     switch (sa) {
2401     case 8: cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rt] << 8; break;
2402     case 16:cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rt] << 16; break;
2403     default:cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rt] << sa;
2404     }
2405     /* Sign-extend rd: */
2406     cpu->cd.mips.gpr[rd] = (int64_t) (int32_t) cpu->cd.mips.gpr[rd];
2407     }
2408     if (special6 == SPECIAL_DSLL) {
2409     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rt] << sa;
2410     }
2411     if (special6 == SPECIAL_DSRL) {
2412     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rt] >> sa;
2413     }
2414     if (special6 == SPECIAL_DSLL32) {
2415     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rt] << (sa + 32);
2416     }
2417     if (special6 == SPECIAL_SRL) {
2418     /*
2419     * Three cases:
2420     * shift amount = zero: just copy
2421     * high bit of rt zero: plain shift right (of all bits)
2422     * high bit of rt one: plain shift right (of lowest 32 bits)
2423     */
2424     if (sa == 0)
2425     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rt];
2426     else if (!(cpu->cd.mips.gpr[rt] & 0x80000000ULL)) {
2427     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rt] >> sa;
2428     } else
2429     cpu->cd.mips.gpr[rd] = (cpu->cd.mips.gpr[rt] & 0xffffffffULL) >> sa;
2430     }
2431     if (special6 == SPECIAL_SRA) {
2432     int topbit = cpu->cd.mips.gpr[rt] & 0x80000000ULL;
2433     switch (sa) {
2434     case 8: cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rt] >> 8; break;
2435     case 16:cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rt] >> 16; break;
2436     default:cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rt] >> sa;
2437     }
2438     if (topbit)
2439     cpu->cd.mips.gpr[rd] |= 0xffffffff00000000ULL;
2440     }
2441     if (special6 == SPECIAL_DSRL32) {
2442     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rt] >> (sa + 32);
2443     }
2444     if (special6 == SPECIAL_DSRA32 || special6 == SPECIAL_DSRA) {
2445     if (special6 == SPECIAL_DSRA32)
2446     sa += 32;
2447     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rt];
2448     while (sa > 0) {
2449     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rd] >> 1;
2450     sa--;
2451     if (cpu->cd.mips.gpr[rd] & ((uint64_t)1 << 62)) /* old signbit */
2452     cpu->cd.mips.gpr[rd] |= ((uint64_t)1 << 63);
2453     }
2454     }
2455     return 1;
2456     case SPECIAL_DSRLV:
2457     case SPECIAL_DSRAV:
2458     case SPECIAL_DSLLV:
2459     case SPECIAL_SLLV:
2460     case SPECIAL_SRAV:
2461     case SPECIAL_SRLV:
2462     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
2463     rt = instr[2] & 31;
2464     rd = (instr[1] >> 3) & 31;
2465    
2466     if (special6 == SPECIAL_DSRLV) {
2467     sa = cpu->cd.mips.gpr[rs] & 63;
2468     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rt] >> sa;
2469     }
2470     if (special6 == SPECIAL_DSRAV) {
2471     sa = cpu->cd.mips.gpr[rs] & 63;
2472     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rt];
2473     while (sa > 0) {
2474     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rd] >> 1;
2475     sa--;
2476     if (cpu->cd.mips.gpr[rd] & ((uint64_t)1 << 62)) /* old sign-bit */
2477     cpu->cd.mips.gpr[rd] |= ((uint64_t)1 << 63);
2478     }
2479     }
2480     if (special6 == SPECIAL_DSLLV) {
2481     sa = cpu->cd.mips.gpr[rs] & 63;
2482     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rt];
2483     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rd] << sa;
2484     }
2485     if (special6 == SPECIAL_SLLV) {
2486     sa = cpu->cd.mips.gpr[rs] & 31;
2487     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rt];
2488     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rd] << sa;
2489     /* Sign-extend rd: */
2490     cpu->cd.mips.gpr[rd] &= 0xffffffffULL;
2491     if (cpu->cd.mips.gpr[rd] & 0x80000000ULL)
2492     cpu->cd.mips.gpr[rd] |= 0xffffffff00000000ULL;
2493     }
2494     if (special6 == SPECIAL_SRAV) {
2495     sa = cpu->cd.mips.gpr[rs] & 31;
2496     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rt];
2497     /* Sign-extend rd: */
2498     cpu->cd.mips.gpr[rd] &= 0xffffffffULL;
2499     if (cpu->cd.mips.gpr[rd] & 0x80000000ULL)
2500     cpu->cd.mips.gpr[rd] |= 0xffffffff00000000ULL;
2501     while (sa > 0) {
2502     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rd] >> 1;
2503     sa--;
2504     }
2505     if (cpu->cd.mips.gpr[rd] & 0x80000000ULL)
2506     cpu->cd.mips.gpr[rd] |= 0xffffffff00000000ULL;
2507     }
2508     if (special6 == SPECIAL_SRLV) {
2509     sa = cpu->cd.mips.gpr[rs] & 31;
2510     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rt];
2511     cpu->cd.mips.gpr[rd] &= 0xffffffffULL;
2512     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rd] >> sa;
2513     /* And finally sign-extend rd: */
2514     if (cpu->cd.mips.gpr[rd] & 0x80000000ULL)
2515     cpu->cd.mips.gpr[rd] |= 0xffffffff00000000ULL;
2516     }
2517     return 1;
2518     case SPECIAL_JR:
2519     if (cpu->cd.mips.delay_slot) {
2520     fatal("jr: jump inside a jump's delay slot, or similar. TODO\n");
2521     cpu->running = 0;
2522     return 1;
2523     }
2524    
2525     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
2526    
2527     cpu->cd.mips.delay_slot = TO_BE_DELAYED;
2528     cpu->cd.mips.delay_jmpaddr = cpu->cd.mips.gpr[rs];
2529    
2530     if (!quiet_mode_cached && cpu->machine->show_trace_tree
2531     && rs == 31) {
2532     cpu->cd.mips.trace_tree_depth --;
2533     }
2534    
2535     return 1;
2536     case SPECIAL_JALR:
2537     if (cpu->cd.mips.delay_slot) {
2538     fatal("jalr: jump inside a jump's delay slot, or similar. TODO\n");
2539     cpu->running = 0;
2540     return 1;
2541     }
2542    
2543     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
2544     rd = (instr[1] >> 3) & 31;
2545    
2546     tmpvalue = cpu->cd.mips.gpr[rs];
2547     cpu->cd.mips.gpr[rd] = cached_pc + 4;
2548     /* already increased by 4 earlier */
2549    
2550     if (!quiet_mode_cached && cpu->machine->show_trace_tree
2551     && rd == 31) {
2552     cpu->cd.mips.show_trace_delay = 2;
2553     cpu->cd.mips.show_trace_addr = tmpvalue;
2554     }
2555    
2556     cpu->cd.mips.delay_slot = TO_BE_DELAYED;
2557     cpu->cd.mips.delay_jmpaddr = tmpvalue;
2558     return 1;
2559     case SPECIAL_MFHI:
2560     case SPECIAL_MFLO:
2561     rd = (instr[1] >> 3) & 31;
2562    
2563     if (special6 == SPECIAL_MFHI) {
2564     cpu->cd.mips.gpr[rd] = cpu->cd.mips.hi;
2565     #ifdef MFHILO_DELAY
2566     cpu->mfhi_delay = 3;
2567     #endif
2568     }
2569     if (special6 == SPECIAL_MFLO) {
2570     cpu->cd.mips.gpr[rd] = cpu->cd.mips.lo;
2571     #ifdef MFHILO_DELAY
2572     cpu->mflo_delay = 3;
2573     #endif
2574     }
2575     return 1;
2576     case SPECIAL_ADD:
2577     case SPECIAL_ADDU:
2578     case SPECIAL_SUB:
2579     case SPECIAL_SUBU:
2580     case SPECIAL_AND:
2581     case SPECIAL_OR:
2582     case SPECIAL_XOR:
2583     case SPECIAL_NOR:
2584     case SPECIAL_SLT:
2585     case SPECIAL_SLTU:
2586     case SPECIAL_MTLO:
2587     case SPECIAL_MTHI:
2588     case SPECIAL_MULT:
2589     case SPECIAL_MULTU:
2590     case SPECIAL_DMULT:
2591     case SPECIAL_DMULTU:
2592     case SPECIAL_DIV:
2593     case SPECIAL_DIVU:
2594     case SPECIAL_DDIV:
2595     case SPECIAL_DDIVU:
2596     case SPECIAL_TGE:
2597     case SPECIAL_TGEU:
2598     case SPECIAL_TLT:
2599     case SPECIAL_TLTU:
2600     case SPECIAL_TEQ:
2601     case SPECIAL_TNE:
2602     case SPECIAL_DADD:
2603     case SPECIAL_DADDU:
2604     case SPECIAL_DSUB:
2605     case SPECIAL_DSUBU:
2606     case SPECIAL_MOVZ:
2607     case SPECIAL_MOVN:
2608     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
2609     rt = instr[2] & 31;
2610     rd = (instr[1] >> 3) & 31;
2611    
2612     #ifdef MFHILO_DELAY
2613     if (cpu->mflo_delay > 0 && (
2614     special6 == SPECIAL_DDIV || special6 == SPECIAL_DDIVU ||
2615     special6 == SPECIAL_DIV || special6 == SPECIAL_DIVU ||
2616     special6 == SPECIAL_DMULT || special6 == SPECIAL_DMULTU ||
2617     special6 == SPECIAL_MTLO || special6 == SPECIAL_MULT
2618     || special6 == SPECIAL_MULTU
2619     ) )
2620     debug("warning: instruction modifying LO too early after mflo!\n");
2621    
2622     if (cpu->mfhi_delay > 0 && (
2623     special6 == SPECIAL_DDIV || special6 == SPECIAL_DDIVU ||
2624     special6 == SPECIAL_DIV || special6 == SPECIAL_DIVU ||
2625     special6 == SPECIAL_DMULT || special6 == SPECIAL_DMULTU ||
2626     special6 == SPECIAL_MTHI || special6 == SPECIAL_MULT
2627     || special6 == SPECIAL_MULTU
2628     ) )
2629     debug("warning: instruction modifying HI too early after mfhi!\n");
2630     #endif
2631    
2632     if (special6 == SPECIAL_ADDU) {
2633     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rs] + cpu->cd.mips.gpr[rt];
2634     cpu->cd.mips.gpr[rd] &= 0xffffffffULL;
2635     if (cpu->cd.mips.gpr[rd] & 0x80000000ULL)
2636     cpu->cd.mips.gpr[rd] |= 0xffffffff00000000ULL;
2637     break;
2638     }
2639     if (special6 == SPECIAL_ADD) {
2640     /* According to the MIPS64 manual: */
2641     uint64_t temp, temp1, temp2;
2642     temp1 = cpu->cd.mips.gpr[rs] + ((cpu->cd.mips.gpr[rs] & 0x80000000ULL) << 1);
2643     temp2 = cpu->cd.mips.gpr[rt] + ((cpu->cd.mips.gpr[rt] & 0x80000000ULL) << 1);
2644     temp = temp1 + temp2;
2645     #if 0
2646     /* TODO: apparently this doesn't work (an example of
2647     something that breaks is NetBSD/sgimips' mips3_TBIA() */
2648     /* If bits 32 and 31 of temp differ, then it's an overflow */
2649     temp1 = temp & 0x100000000ULL;
2650     temp2 = temp & 0x80000000ULL;
2651     if ((temp1 && !temp2) || (!temp1 && temp2)) {
2652     mips_cpu_exception(cpu, EXCEPTION_OV, 0, 0, 0, 0, 0, 0);
2653     break;
2654     }
2655     #endif
2656     cpu->cd.mips.gpr[rd] = temp & 0xffffffffULL;
2657     if (cpu->cd.mips.gpr[rd] & 0x80000000ULL)
2658     cpu->cd.mips.gpr[rd] |= 0xffffffff00000000ULL;
2659     break;
2660     }
2661     if (special6 == SPECIAL_SUBU) {
2662     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rs] - cpu->cd.mips.gpr[rt];
2663     cpu->cd.mips.gpr[rd] &= 0xffffffffULL;
2664     if (cpu->cd.mips.gpr[rd] & 0x80000000ULL)
2665     cpu->cd.mips.gpr[rd] |= 0xffffffff00000000ULL;
2666     break;
2667     }
2668     if (special6 == SPECIAL_SUB) {
2669     /* According to the MIPS64 manual: */
2670     uint64_t temp, temp1, temp2;
2671     temp1 = cpu->cd.mips.gpr[rs] + ((cpu->cd.mips.gpr[rs] & 0x80000000ULL) << 1);
2672     temp2 = cpu->cd.mips.gpr[rt] + ((cpu->cd.mips.gpr[rt] & 0x80000000ULL) << 1);
2673     temp = temp1 - temp2;
2674     #if 0
2675     /* If bits 32 and 31 of temp differ, then it's an overflow */
2676     temp1 = temp & 0x100000000ULL;
2677     temp2 = temp & 0x80000000ULL;
2678     if ((temp1 && !temp2) || (!temp1 && temp2)) {
2679     mips_cpu_exception(cpu, EXCEPTION_OV, 0, 0, 0, 0, 0, 0);
2680     break;
2681     }
2682     #endif
2683     cpu->cd.mips.gpr[rd] = temp & 0xffffffffULL;
2684     if (cpu->cd.mips.gpr[rd] & 0x80000000ULL)
2685     cpu->cd.mips.gpr[rd] |= 0xffffffff00000000ULL;
2686     break;
2687     }
2688    
2689     if (special6 == SPECIAL_AND) {
2690     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rs] & cpu->cd.mips.gpr[rt];
2691     break;
2692     }
2693     if (special6 == SPECIAL_OR) {
2694     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rs] | cpu->cd.mips.gpr[rt];
2695     break;
2696     }
2697     if (special6 == SPECIAL_XOR) {
2698     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rs] ^ cpu->cd.mips.gpr[rt];
2699     break;
2700     }
2701     if (special6 == SPECIAL_NOR) {
2702     cpu->cd.mips.gpr[rd] = ~(cpu->cd.mips.gpr[rs] | cpu->cd.mips.gpr[rt]);
2703     break;
2704     }
2705     if (special6 == SPECIAL_SLT) {
2706     cpu->cd.mips.gpr[rd] = (int64_t)cpu->cd.mips.gpr[rs] < (int64_t)cpu->cd.mips.gpr[rt];
2707     break;
2708     }
2709     if (special6 == SPECIAL_SLTU) {
2710     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rs] < cpu->cd.mips.gpr[rt];
2711     break;
2712     }
2713     if (special6 == SPECIAL_MTLO) {
2714     cpu->cd.mips.lo = cpu->cd.mips.gpr[rs];
2715     break;
2716     }
2717     if (special6 == SPECIAL_MTHI) {
2718     cpu->cd.mips.hi = cpu->cd.mips.gpr[rs];
2719     break;
2720     }
2721     if (special6 == SPECIAL_MULT) {
2722     int64_t f1, f2, sum;
2723     f1 = cpu->cd.mips.gpr[rs] & 0xffffffffULL;
2724     /* sign extend f1 */
2725     if (f1 & 0x80000000ULL)
2726     f1 |= 0xffffffff00000000ULL;
2727     f2 = cpu->cd.mips.gpr[rt] & 0xffffffffULL;
2728     /* sign extend f2 */
2729     if (f2 & 0x80000000ULL)
2730     f2 |= 0xffffffff00000000ULL;
2731     sum = f1 * f2;
2732    
2733     cpu->cd.mips.lo = sum & 0xffffffffULL;
2734     cpu->cd.mips.hi = ((uint64_t)sum >> 32) & 0xffffffffULL;
2735    
2736     /* sign-extend: */
2737     if (cpu->cd.mips.lo & 0x80000000ULL)
2738     cpu->cd.mips.lo |= 0xffffffff00000000ULL;
2739     if (cpu->cd.mips.hi & 0x80000000ULL)
2740     cpu->cd.mips.hi |= 0xffffffff00000000ULL;
2741    
2742     /*
2743     * NOTE: The stuff about rd!=0 is just a
2744     * guess, judging from how some NetBSD code
2745     * seems to execute. It is not documented in
2746     * the MIPS64 ISA docs :-/
2747     */
2748    
2749     if (rd != 0) {
2750     if (cpu->cd.mips.cpu_type.rev != MIPS_R5900)
2751     debug("WARNING! mult_xx is an undocumented instruction!");
2752     cpu->cd.mips.gpr[rd] = cpu->cd.mips.lo;
2753     }
2754     break;
2755     }
2756     if (special6 == SPECIAL_MULTU) {
2757     uint64_t f1, f2, sum;
2758     /* zero extend f1 and f2 */
2759     f1 = cpu->cd.mips.gpr[rs] & 0xffffffffULL;
2760     f2 = cpu->cd.mips.gpr[rt] & 0xffffffffULL;
2761     sum = f1 * f2;
2762     cpu->cd.mips.lo = sum & 0xffffffffULL;
2763     cpu->cd.mips.hi = (sum >> 32) & 0xffffffffULL;
2764    
2765     /* sign-extend: */
2766     if (cpu->cd.mips.lo & 0x80000000ULL)
2767     cpu->cd.mips.lo |= 0xffffffff00000000ULL;
2768     if (cpu->cd.mips.hi & 0x80000000ULL)
2769     cpu->cd.mips.hi |= 0xffffffff00000000ULL;
2770     break;
2771     }
2772     /*
2773     * TODO: I'm too tired to think now. DMULT is probably
2774     * correct, but is DMULTU? (Unsigned 64x64 multiply.)
2775     * Or, hm, perhaps it is dmult which is incorrect.
2776     */
2777     if (special6 == SPECIAL_DMULT || special6 == SPECIAL_DMULTU) {
2778     /* 64x64 = 128 bit multiplication: SLOW!!! TODO */
2779     uint64_t i, low_add, high_add;
2780    
2781     cpu->cd.mips.lo = cpu->cd.mips.hi = 0;
2782     for (i=0; i<64; i++) {
2783     uint64_t bit = cpu->cd.mips.gpr[rt] & ((uint64_t)1 << i);
2784     if (bit) {
2785     /* Add cpu->cd.mips.gpr[rs] to hi and lo: */
2786     low_add = (cpu->cd.mips.gpr[rs] << i);
2787     high_add = (cpu->cd.mips.gpr[rs] >> (64-i));
2788     if (i==0) /* WEIRD BUG in the compiler? Or maybe I'm just stupid */
2789     high_add = 0; /* these lines are necessary, a >> 64 doesn't seem to do anything */
2790     if (cpu->cd.mips.lo + low_add < cpu->cd.mips.lo)
2791     cpu->cd.mips.hi ++;
2792     cpu->cd.mips.lo += low_add;
2793     cpu->cd.mips.hi += high_add;
2794     }
2795     }
2796     break;
2797     }
2798     if (special6 == SPECIAL_DIV) {
2799     int64_t a, b;
2800     /* Signextend rs and rt: */
2801     a = cpu->cd.mips.gpr[rs] & 0xffffffffULL;
2802     if (a & 0x80000000ULL)
2803     a |= 0xffffffff00000000ULL;
2804     b = cpu->cd.mips.gpr[rt] & 0xffffffffULL;
2805     if (b & 0x80000000ULL)
2806     b |= 0xffffffff00000000ULL;
2807    
2808     if (b == 0) {
2809     /* undefined */
2810     cpu->cd.mips.lo = cpu->cd.mips.hi = 0;
2811     } else {
2812     cpu->cd.mips.lo = a / b;
2813     cpu->cd.mips.hi = a % b;
2814     }
2815     /* Sign-extend lo and hi: */
2816     cpu->cd.mips.lo &= 0xffffffffULL;
2817     if (cpu->cd.mips.lo & 0x80000000ULL)
2818     cpu->cd.mips.lo |= 0xffffffff00000000ULL;
2819     cpu->cd.mips.hi &= 0xffffffffULL;
2820     if (cpu->cd.mips.hi & 0x80000000ULL)
2821     cpu->cd.mips.hi |= 0xffffffff00000000ULL;
2822     break;
2823     }
2824     if (special6 == SPECIAL_DIVU) {
2825     int64_t a, b;
2826     /* Zero-extend rs and rt: */
2827     a = cpu->cd.mips.gpr[rs] & 0xffffffffULL;
2828     b = cpu->cd.mips.gpr[rt] & 0xffffffffULL;
2829     if (b == 0) {
2830     /* undefined */
2831     cpu->cd.mips.lo = cpu->cd.mips.hi = 0;
2832     } else {
2833     cpu->cd.mips.lo = a / b;
2834     cpu->cd.mips.hi = a % b;
2835     }
2836     /* Sign-extend lo and hi: */
2837     cpu->cd.mips.lo &= 0xffffffffULL;
2838     if (cpu->cd.mips.lo & 0x80000000ULL)
2839     cpu->cd.mips.lo |= 0xffffffff00000000ULL;
2840     cpu->cd.mips.hi &= 0xffffffffULL;
2841     if (cpu->cd.mips.hi & 0x80000000ULL)
2842     cpu->cd.mips.hi |= 0xffffffff00000000ULL;
2843     break;
2844     }
2845     if (special6 == SPECIAL_DDIV) {
2846     if (cpu->cd.mips.gpr[rt] == 0) {
2847     cpu->cd.mips.lo = cpu->cd.mips.hi = 0; /* undefined */
2848     } else {
2849     cpu->cd.mips.lo = (int64_t)cpu->cd.mips.gpr[rs] / (int64_t)cpu->cd.mips.gpr[rt];
2850     cpu->cd.mips.hi = (int64_t)cpu->cd.mips.gpr[rs] % (int64_t)cpu->cd.mips.gpr[rt];
2851     }
2852     break;
2853     }
2854     if (special6 == SPECIAL_DDIVU) {
2855     if (cpu->cd.mips.gpr[rt] == 0) {
2856     cpu->cd.mips.lo = cpu->cd.mips.hi = 0; /* undefined */
2857     } else {
2858     cpu->cd.mips.lo = cpu->cd.mips.gpr[rs] / cpu->cd.mips.gpr[rt];
2859     cpu->cd.mips.hi = cpu->cd.mips.gpr[rs] % cpu->cd.mips.gpr[rt];
2860     }
2861     break;
2862     }
2863     if (special6 == SPECIAL_TGE) {
2864     if ((int64_t)cpu->cd.mips.gpr[rs] >= (int64_t)cpu->cd.mips.gpr[rt])
2865     mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
2866     break;
2867     }
2868     if (special6 == SPECIAL_TGEU) {
2869     if (cpu->cd.mips.gpr[rs] >= cpu->cd.mips.gpr[rt])
2870     mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
2871     break;
2872     }
2873     if (special6 == SPECIAL_TLT) {
2874     if ((int64_t)cpu->cd.mips.gpr[rs] < (int64_t)cpu->cd.mips.gpr[rt])
2875     mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
2876     break;
2877     }
2878     if (special6 == SPECIAL_TLTU) {
2879     if (cpu->cd.mips.gpr[rs] < cpu->cd.mips.gpr[rt])
2880     mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
2881     break;
2882     }
2883     if (special6 == SPECIAL_TEQ) {
2884     if (cpu->cd.mips.gpr[rs] == cpu->cd.mips.gpr[rt])
2885     mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
2886     break;
2887     }
2888     if (special6 == SPECIAL_TNE) {
2889     if (cpu->cd.mips.gpr[rs] != cpu->cd.mips.gpr[rt])
2890     mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
2891     break;
2892     }
2893     if (special6 == SPECIAL_DADD) {
2894     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rs] + cpu->cd.mips.gpr[rt];
2895     /* TODO: exception on overflow */
2896     break;
2897     }
2898     if (special6 == SPECIAL_DADDU) {
2899     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rs] + cpu->cd.mips.gpr[rt];
2900     break;
2901     }
2902     if (special6 == SPECIAL_DSUB) {
2903     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rs] - cpu->cd.mips.gpr[rt];
2904     /* TODO: exception on overflow */
2905     break;
2906     }
2907     if (special6 == SPECIAL_DSUBU) {
2908     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rs] - cpu->cd.mips.gpr[rt];
2909     break;
2910     }
2911     if (special6 == SPECIAL_MOVZ) {
2912     if (cpu->cd.mips.gpr[rt] == 0)
2913     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rs];
2914     break;
2915     }
2916     if (special6 == SPECIAL_MOVN) {
2917     if (cpu->cd.mips.gpr[rt] != 0)
2918     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rs];
2919     return 1;
2920     }
2921     return 1;
2922     case SPECIAL_SYNC:
2923     imm = ((instr[1] & 7) << 2) + (instr[0] >> 6);
2924     /* TODO: actually sync */
2925    
2926     /* Clear the LLbit (at least on R10000): */
2927     cpu->cd.mips.rmw = 0;
2928     return 1;
2929     case SPECIAL_SYSCALL:
2930     imm = ((instr[3] << 24) + (instr[2] << 16) +
2931     (instr[1] << 8) + instr[0]) >> 6;
2932     imm &= 0xfffff;
2933    
2934     if (cpu->machine->userland_emul != NULL)
2935     useremul_syscall(cpu, imm);
2936     else
2937     mips_cpu_exception(cpu, EXCEPTION_SYS,
2938     0, 0, 0, 0, 0, 0);
2939     return 1;
2940     case SPECIAL_BREAK:
2941     mips_cpu_exception(cpu, EXCEPTION_BP, 0, 0, 0, 0, 0, 0);
2942     return 1;
2943     case SPECIAL_MFSA:
2944     /* R5900? What on earth does this thing do? */
2945     rd = (instr[1] >> 3) & 31;
2946     /* TODO */
2947     return 1;
2948     case SPECIAL_MTSA:
2949     /* R5900? What on earth does this thing do? */
2950     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
2951     /* TODO */
2952     return 1;
2953     default:
2954     if (!instruction_trace_cached) {
2955     fatal("cpu%i @ %016llx: %02x%02x%02x%02x%s\t",
2956     cpu->cpu_id, cpu->cd.mips.pc_last,
2957     instr[3], instr[2], instr[1], instr[0], cpu_flags(cpu));
2958     }
2959     fatal("unimplemented special6 = 0x%02x\n", special6);
2960     cpu->running = 0;
2961     return 1;
2962     }
2963     return 1;
2964     case HI6_BEQ:
2965     case HI6_BEQL:
2966     case HI6_BNE:
2967     case HI6_BGTZ:
2968     case HI6_BGTZL:
2969     case HI6_BLEZ:
2970     case HI6_BLEZL:
2971     case HI6_BNEL:
2972     case HI6_ADDI:
2973     case HI6_ADDIU:
2974     case HI6_DADDI:
2975     case HI6_DADDIU:
2976     case HI6_SLTI:
2977     case HI6_SLTIU:
2978     case HI6_ANDI:
2979     case HI6_ORI:
2980     case HI6_XORI:
2981     case HI6_LUI:
2982     case HI6_LB:
2983     case HI6_LBU:
2984     case HI6_LH:
2985     case HI6_LHU:
2986     case HI6_LW:
2987     case HI6_LWU:
2988     case HI6_LD:
2989     case HI6_LQ_MDMX:
2990     case HI6_LWC1:
2991     case HI6_LWC2:
2992     case HI6_LWC3:
2993     case HI6_LDC1:
2994     case HI6_LDC2:
2995     case HI6_LL:
2996     case HI6_LLD:
2997     case HI6_SB:
2998     case HI6_SH:
2999     case HI6_SW:
3000     case HI6_SD:
3001     case HI6_SQ:
3002     case HI6_SC:
3003     case HI6_SCD:
3004     case HI6_SWC1:
3005     case HI6_SWC2:
3006     case HI6_SWC3:
3007     case HI6_SDC1:
3008     case HI6_SDC2:
3009     case HI6_LWL: /* Unaligned load/store */
3010     case HI6_LWR:
3011     case HI6_LDL:
3012     case HI6_LDR:
3013     case HI6_SWL:
3014     case HI6_SWR:
3015     case HI6_SDL:
3016     case HI6_SDR:
3017     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
3018     rt = instr[2] & 31;
3019     imm = (instr[1] << 8) + instr[0];
3020     if (imm >= 32768) /* signed 16-bit */
3021     imm -= 65536;
3022    
3023     tmpvalue = imm; /* used later in several cases */
3024    
3025     switch (hi6) {
3026     case HI6_ADDI:
3027     case HI6_ADDIU:
3028     case HI6_DADDI:
3029     case HI6_DADDIU:
3030     tmpvalue = cpu->cd.mips.gpr[rs];
3031     result_value = cpu->cd.mips.gpr[rs] + imm;
3032    
3033     if (hi6 == HI6_ADDI || hi6 == HI6_DADDI) {
3034     /*
3035     * addi and daddi should trap on overflow:
3036     *
3037     * TODO: This is incorrect? The R4000 manual
3038     * says that overflow occurs if the carry bits
3039     * out of bit 62 and 63 differ. The
3040     * destination register should not be modified
3041     * on overflow.
3042     */
3043     if (imm >= 0) {
3044     /* Turn around from 0x7fff.. to 0x800 ? Then overflow. */
3045     if ( ((hi6 == HI6_ADDI && (result_value &
3046     0x80000000ULL) && (tmpvalue &
3047     0x80000000ULL)==0))
3048     || ((hi6 == HI6_DADDI && (result_value &
3049     0x8000000000000000ULL) && (tmpvalue &
3050     0x8000000000000000ULL)==0)) ) {
3051     mips_cpu_exception(cpu, EXCEPTION_OV, 0, 0, 0, 0, 0, 0);
3052     break;
3053     }
3054     } else {
3055     /* Turn around from 0x8000.. to 0x7fff.. ? Then overflow. */
3056     if ( ((hi6 == HI6_ADDI && (result_value &
3057     0x80000000ULL)==0 && (tmpvalue &
3058     0x80000000ULL)))
3059     || ((hi6 == HI6_DADDI && (result_value &
3060     0x8000000000000000ULL)==0 && (tmpvalue &
3061     0x8000000000000000ULL))) ) {
3062     mips_cpu_exception(cpu, EXCEPTION_OV, 0, 0, 0, 0, 0, 0);
3063     break;
3064     }
3065     }
3066     }
3067    
3068     cpu->cd.mips.gpr[rt] = result_value;
3069    
3070     /*
3071     * Super-ugly speed-hack: (only if speed_tricks != 0)
3072     * NOTE: This makes the emulation less correct.
3073     *
3074     * If we encounter a loop such as:
3075     *
3076     * 8012f5f4: 1c40ffff bgtz r0,r2,ffffffff8012f5f4
3077     * 8012f5f8: 2442ffff (d) addiu r2,r2,-1
3078     *
3079     * then it is a small loop which simply waits for r2
3080     * to become zero.
3081     *
3082     * TODO: increaste the count register, and cause
3083     * interrupts!!! For now: return as if we just
3084     * executed 1 instruction.
3085     */
3086     ninstrs_executed = 1;
3087     if (cpu->machine->speed_tricks && cpu->cd.mips.delay_slot &&
3088     cpu->cd.mips.last_was_jumptoself &&
3089     cpu->cd.mips.jump_to_self_reg == rt &&
3090     cpu->cd.mips.jump_to_self_reg == rs) {
3091     if ((int64_t)cpu->cd.mips.gpr[rt] > 1 && (int64_t)cpu->cd.mips.gpr[rt] < 0x70000000
3092     && (imm >= -30000 && imm <= -1)) {
3093     if (instruction_trace_cached)
3094     debug("changing r%i from %016llx to", rt, (long long)cpu->cd.mips.gpr[rt]);
3095    
3096     while ((int64_t)cpu->cd.mips.gpr[rt] > 0 && ninstrs_executed < 1000
3097     && ((int64_t)cpu->cd.mips.gpr[rt] + (int64_t)imm) > 0) {
3098     cpu->cd.mips.gpr[rt] += (int64_t)imm;
3099     ninstrs_executed += 2;
3100     }
3101    
3102     if (instruction_trace_cached)
3103     debug(" %016llx\n", (long long)cpu->cd.mips.gpr[rt]);
3104    
3105     /* TODO: return value, cpu->cd.mips.gpr[rt] * 2; */
3106     }
3107     if ((int64_t)cpu->cd.mips.gpr[rt] > -0x70000000 && (int64_t)cpu->cd.mips.gpr[rt] < -1
3108     && (imm >= 1 && imm <= 30000)) {
3109     if (instruction_trace_cached)
3110     debug("changing r%i from %016llx to", rt, (long long)cpu->cd.mips.gpr[rt]);
3111    
3112     while ((int64_t)cpu->cd.mips.gpr[rt] < 0 && ninstrs_executed < 1000
3113     && ((int64_t)cpu->cd.mips.gpr[rt] + (int64_t)imm) < 0) {
3114     cpu->cd.mips.gpr[rt] += (int64_t)imm;
3115     ninstrs_executed += 2;
3116     }
3117    
3118     if (instruction_trace_cached)
3119     debug(" %016llx\n", (long long)cpu->cd.mips.gpr[rt]);
3120     }
3121     }
3122    
3123     if (hi6 == HI6_ADDI || hi6 == HI6_ADDIU) {
3124     /* Sign-extend: */
3125     cpu->cd.mips.gpr[rt] &= 0xffffffffULL;
3126     if (cpu->cd.mips.gpr[rt] & 0x80000000ULL)
3127     cpu->cd.mips.gpr[rt] |= 0xffffffff00000000ULL;
3128     }
3129     return ninstrs_executed;
3130     case HI6_BEQ:
3131     case HI6_BNE:
3132     case HI6_BGTZ:
3133     case HI6_BGTZL:
3134     case HI6_BLEZ:
3135     case HI6_BLEZL:
3136     case HI6_BEQL:
3137     case HI6_BNEL:
3138     if (cpu->cd.mips.delay_slot) {
3139     fatal("b*: jump inside a jump's delay slot, or similar. TODO\n");
3140     cpu->running = 0;
3141     return 1;
3142     }
3143     likely = cond = 0;
3144     switch (hi6) {
3145     case HI6_BNEL: likely = 1;
3146     case HI6_BNE: cond = (cpu->cd.mips.gpr[rt] != cpu->cd.mips.gpr[rs]);
3147     break;
3148     case HI6_BEQL: likely = 1;
3149     case HI6_BEQ: cond = (cpu->cd.mips.gpr[rt] == cpu->cd.mips.gpr[rs]);
3150     break;
3151     case HI6_BLEZL: likely = 1;
3152     case HI6_BLEZ: cond = ((int64_t)cpu->cd.mips.gpr[rs] <= 0);
3153     break;
3154     case HI6_BGTZL: likely = 1;
3155     case HI6_BGTZ: cond = ((int64_t)cpu->cd.mips.gpr[rs] > 0);
3156     break;
3157     }
3158    
3159     if (cond) {
3160     cpu->cd.mips.delay_slot = TO_BE_DELAYED;
3161     cpu->cd.mips.delay_jmpaddr = cached_pc + (imm << 2);
3162     } else {
3163     if (likely)
3164     cpu->cd.mips.nullify_next = 1; /* nullify delay slot */
3165     }
3166    
3167     if (imm==-1 && (hi6 == HI6_BGTZ || hi6 == HI6_BLEZ ||
3168     (hi6 == HI6_BGTZL && cond) ||
3169     (hi6 == HI6_BLEZL && cond) ||
3170     (hi6 == HI6_BNE && (rt==0 || rs==0)) ||
3171     (hi6 == HI6_BEQ && (rt==0 || rs==0)))) {
3172     cpu->cd.mips.last_was_jumptoself = 2;
3173     if (rs == 0)
3174     cpu->cd.mips.jump_to_self_reg = rt;
3175     else
3176     cpu->cd.mips.jump_to_self_reg = rs;
3177     }
3178     return 1;
3179     case HI6_LUI:
3180     cpu->cd.mips.gpr[rt] = (imm << 16);
3181     /* No sign-extending necessary, as imm already
3182     was sign-extended if it was negative. */
3183     break;
3184     case HI6_SLTI:
3185     cpu->cd.mips.gpr[rt] = (int64_t)cpu->cd.mips.gpr[rs] < (int64_t)tmpvalue;
3186     break;
3187     case HI6_SLTIU:
3188     cpu->cd.mips.gpr[rt] = cpu->cd.mips.gpr[rs] < (uint64_t)imm;
3189     break;
3190     case HI6_ANDI:
3191     cpu->cd.mips.gpr[rt] = cpu->cd.mips.gpr[rs] & (tmpvalue & 0xffff);
3192     break;
3193     case HI6_ORI:
3194     cpu->cd.mips.gpr[rt] = cpu->cd.mips.gpr[rs] | (tmpvalue & 0xffff);
3195     break;
3196     case HI6_XORI:
3197     cpu->cd.mips.gpr[rt] = cpu->cd.mips.gpr[rs] ^ (tmpvalue & 0xffff);
3198     break;
3199     case HI6_LB:
3200     case HI6_LBU:
3201     case HI6_LH:
3202     case HI6_LHU:
3203     case HI6_LW:
3204     case HI6_LWU:
3205     case HI6_LD:
3206     case HI6_LQ_MDMX:
3207     case HI6_LWC1:
3208     case HI6_LWC2:
3209     case HI6_LWC3: /* pref */
3210     case HI6_LDC1:
3211     case HI6_LDC2:
3212     case HI6_LL:
3213     case HI6_LLD:
3214     case HI6_SB:
3215     case HI6_SH:
3216     case HI6_SW:
3217     case HI6_SD:
3218     case HI6_SQ:
3219     case HI6_SC:
3220     case HI6_SCD:
3221     case HI6_SWC1:
3222     case HI6_SWC2:
3223     case HI6_SWC3:
3224     case HI6_SDC1:
3225     case HI6_SDC2:
3226     /* These are the default "assumptions". */
3227     linked = 0;
3228     st = 1;
3229     signd = 1;
3230     wlen = 4;
3231    
3232     switch (hi6) {
3233     /* The most common ones: */
3234     case HI6_LW: { st = 0; } break;
3235     case HI6_SW: { signd = 0; } break;
3236    
3237     case HI6_LB: { wlen = 1; st = 0; } break;
3238     case HI6_LBU: { wlen = 1; st = 0; signd = 0; } break;
3239     case HI6_SB: { wlen = 1; signd = 0; } break;
3240    
3241     case HI6_LD: { wlen = 8; st = 0; signd = 0; } break;
3242     case HI6_SD: { wlen = 8; signd = 0; } break;
3243    
3244     case HI6_LQ_MDMX: { wlen = 16; st = 0; signd = 0; } break; /* R5900, otherwise MDMX (TODO) */
3245     case HI6_SQ: { wlen = 16; signd = 0; } break; /* R5900 ? */
3246    
3247     /* The rest: */
3248     case HI6_LH: { wlen = 2; st = 0; } break;
3249     case HI6_LHU: { wlen = 2; st = 0; signd = 0; } break;
3250     case HI6_LWU: { st = 0; signd = 0; } break;
3251     case HI6_LWC1: { st = 0; } break;
3252     case HI6_LWC2: { st = 0; } break;
3253     case HI6_LWC3: { st = 0; } break;
3254     case HI6_LDC1: { wlen = 8; st = 0; signd = 0; } break;
3255     case HI6_LDC2: { wlen = 8; st = 0; signd = 0; } break;
3256    
3257     case HI6_SH: { wlen = 2; signd = 0; } break;
3258     case HI6_SDC1:
3259     case HI6_SDC2: wlen = 8;
3260     case HI6_SWC1:
3261     case HI6_SWC2:
3262     case HI6_SWC3: { signd = 0; } break;
3263    
3264     case HI6_LL: { st = 0; signd = 1; linked = 1; } break;
3265     case HI6_LLD: { wlen = 8; st = 0; signd = 0; linked = 1; } break;
3266    
3267     case HI6_SC: { signd = 1; linked = 1; } break;
3268     case HI6_SCD: { wlen = 8; signd = 0; linked = 1; } break;
3269    
3270     default:
3271     fatal("cannot be here\n");
3272     wlen = 4; st = 0; signd = 0;
3273     }
3274    
3275     /*
3276     * In the MIPS IV ISA, the 'lwc3' instruction is changed into 'pref'.
3277     * The pref instruction is emulated by not doing anything. :-) TODO
3278     */
3279     if (hi6 == HI6_LWC3 && cpu->cd.mips.cpu_type.isa_level >= 4) {
3280     /* Clear the LLbit (at least on R10000): */
3281     cpu->cd.mips.rmw = 0;
3282     break;
3283     }
3284    
3285     addr = cpu->cd.mips.gpr[rs] + imm;
3286    
3287     /* Check for natural alignment: */
3288     if ((addr & (wlen - 1)) != 0) {
3289     mips_cpu_exception(cpu, st? EXCEPTION_ADES : EXCEPTION_ADEL,
3290     0, addr, 0, 0, 0, 0);
3291     break;
3292     }
3293    
3294     #if 0
3295     if (cpu->cd.mips.cpu_type.isa_level == 4 && (imm & (wlen - 1)) != 0)
3296     debug("WARNING: low bits of imm value not zero! (MIPS IV) "
3297     "pc=%016llx", (long long)cpu->cd.mips.pc_last);
3298     #endif
3299    
3300     /*
3301     * Load Linked: This initiates a Read-Modify-Write
3302     * sequence.
3303     */
3304     if (linked) {
3305     if (st==0) {
3306     /* st == 0: Load */
3307     cpu->cd.mips.rmw = 1;
3308     cpu->cd.mips.rmw_addr = addr;
3309     cpu->cd.mips.rmw_len = wlen;
3310    
3311     /*
3312     * COP0_LLADDR is updated for
3313     * diagnostic purposes, except for
3314     * CPUs in the R10000 family.
3315     */
3316     if (cpu->cd.mips.cpu_type.exc_model != MMU10K)
3317     cp0->reg[COP0_LLADDR] =
3318     (addr >> 4) & 0xffffffffULL;
3319     } else {
3320     /*
3321     * st == 1: Store
3322     * If rmw is 0, then the store failed.
3323     * (This cache-line was written to by
3324     * someone else.)
3325     */
3326 dpavlin 4 if (cpu->cd.mips.rmw == 0 ||
3327     cpu->cd.mips.rmw_addr != addr ||
3328     cpu->cd.mips.rmw_len != wlen) {
3329 dpavlin 2 /* The store failed: */
3330     cpu->cd.mips.gpr[rt] = 0;
3331     if (instruction_trace_cached)
3332     debug(" [COLLISION] ");
3333     break;
3334     }
3335     }
3336     } else {
3337     /*
3338     * If any kind of load or store occurs between
3339     * an ll and an sc, then the ll-sc sequence
3340     * should fail. (This is local to each cpu.)
3341     */
3342     cpu->cd.mips.rmw = 0;
3343     }
3344    
3345     value_hi = 0;
3346    
3347     if (st) {
3348     /* store: */
3349     int cpnr, success;
3350    
3351     if (hi6 == HI6_SWC3 || hi6 == HI6_SWC2 ||
3352     hi6 == HI6_SDC1 || hi6 == HI6_SWC1) {
3353     cpnr = 1;
3354     switch (hi6) {
3355     case HI6_SWC3: cpnr++; /* fallthrough */
3356     case HI6_SWC2: cpnr++;
3357     case HI6_SDC1:
3358     case HI6_SWC1: if (cpu->cd.mips.coproc[cpnr] == NULL ||
3359     (!(cp0->reg[COP0_STATUS] & ((1 << cpnr) << STATUS_CU_SHIFT))) ) {
3360     mips_cpu_exception(cpu, EXCEPTION_CPU, 0, 0, cpnr, 0, 0, 0);
3361     cpnr = -1;
3362     break;
3363     } else {
3364     /* Special handling of 64-bit stores
3365     on 32-bit CPUs, and on newer CPUs
3366     in 32-bit compatiblity mode: */
3367     if ((hi6==HI6_SDC1 || hi6==HI6_SDC2) &&
3368     (cpu->cd.mips.cpu_type.isa_level <= 2 ||
3369     !(cp0->reg[COP0_STATUS] & STATUS_FR))) {
3370     uint64_t a, b;
3371     coproc_register_read(cpu,
3372 dpavlin 10 cpu->cd.mips.coproc[cpnr], rt, &a, 0);
3373 dpavlin 2 coproc_register_read(cpu,
3374 dpavlin 10 cpu->cd.mips.coproc[cpnr], rt^1, &b, 0);
3375 dpavlin 2 if (rt & 1)
3376     fatal("WARNING: SDCx in 32-bit mode from odd register!\n");
3377     value = (a & 0xffffffffULL)
3378     | (b << 32);
3379     } else
3380 dpavlin 10 coproc_register_read(cpu, cpu->cd.mips.coproc[cpnr], rt, &value, 0);
3381 dpavlin 2 }
3382     break;
3383     default:
3384     ;
3385     }
3386     if (cpnr < 0)
3387     break;
3388     } else
3389     value = cpu->cd.mips.gpr[rt];
3390    
3391     if (wlen == 4) {
3392     /* Special case for 32-bit stores... (perhaps not worth it) */
3393     if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
3394     d[0] = value & 0xff; d[1] = (value >> 8) & 0xff;
3395     d[2] = (value >> 16) & 0xff; d[3] = (value >> 24) & 0xff;
3396     } else {
3397     d[3] = value & 0xff; d[2] = (value >> 8) & 0xff;
3398     d[1] = (value >> 16) & 0xff; d[0] = (value >> 24) & 0xff;
3399     }
3400     } else if (wlen == 16) {
3401     value_hi = cpu->cd.mips.gpr_quadhi[rt];
3402     /* Special case for R5900 128-bit stores: */
3403     if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
3404     for (i=0; i<8; i++) {
3405     d[i] = (value >> (i*8)) & 255;
3406     d[i+8] = (value_hi >> (i*8)) & 255;
3407     }
3408     else
3409     for (i=0; i<8; i++) {
3410     d[i] = (value >> ((wlen-1-i)*8)) & 255;
3411     d[i + 8] = (value_hi >> ((wlen-1-i)*8)) & 255;
3412     }
3413     } else if (wlen == 1) {
3414     d[0] = value & 0xff;
3415     } else {
3416     /* General case: */
3417     uint64_t v = value;
3418     if (cpu->byte_order ==
3419     EMUL_LITTLE_ENDIAN)
3420     for (i=0; i<wlen; i++) {
3421     d[i] = v & 255;
3422     v >>= 8;
3423     }
3424     else
3425     for (i=0; i<wlen; i++) {
3426     d[wlen-1-i] = v & 255;
3427     v >>= 8;
3428     }
3429     }
3430    
3431     success = cpu->memory_rw(cpu, cpu->mem, addr,
3432     d, wlen, MEM_WRITE, CACHE_DATA);
3433     if (!success) {
3434     /* The store failed, and might have caused an exception. */
3435     if (instruction_trace_cached)
3436     debug("(failed)]\n");
3437     break;
3438     }
3439     } else {
3440     /* load: */
3441     int cpnr = 1;
3442     int success;
3443    
3444     success = cpu->memory_rw(cpu, cpu->mem, addr,
3445     d, wlen, MEM_READ, CACHE_DATA);
3446     if (!success) {
3447     /* The load failed, and might have caused an exception. */
3448     if (instruction_trace_cached)
3449     debug("(failed)]\n");
3450     break;
3451     }
3452    
3453     if (wlen == 1)
3454     value = d[0] | (signd && (d[0]&128)? (-1 << 8) : 0);
3455     else if (wlen != 16) {
3456     /* General case (except for 128-bit): */
3457     int i;
3458     value = 0;
3459     if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
3460     if (signd && (d[wlen-1] & 128)!=0) /* sign extend */
3461     value = -1;
3462     for (i=wlen-1; i>=0; i--) {
3463     value <<= 8;
3464     value += d[i];
3465     }
3466     } else {
3467     if (signd && (d[0] & 128)!=0) /* sign extend */
3468     value = -1;
3469     for (i=0; i<wlen; i++) {
3470     value <<= 8;
3471     value += d[i];
3472     }
3473     }
3474     } else {
3475     /* R5900 128-bit quadword: */
3476     int i;
3477     value_hi = 0;
3478     value = 0;
3479     if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
3480     for (i=wlen-1; i>=0; i--) {
3481     value_hi <<= 8;
3482     value_hi += (value >> 56) & 255;
3483     value <<= 8;
3484     value += d[i];
3485     }
3486     } else {
3487     for (i=0; i<wlen; i++) {
3488     value_hi <<= 8;
3489     value_hi += (value >> 56) & 255;
3490     value <<= 8;
3491     value += d[i];
3492     }
3493     }
3494     cpu->cd.mips.gpr_quadhi[rt] = value_hi;
3495     }
3496    
3497     switch (hi6) {
3498     case HI6_LWC3: cpnr++; /* fallthrough */
3499     case HI6_LDC2:
3500     case HI6_LWC2: cpnr++;
3501     case HI6_LDC1:
3502     case HI6_LWC1: if (cpu->cd.mips.coproc[cpnr] == NULL ||
3503     (!(cp0->reg[COP0_STATUS] & ((1 << cpnr) << STATUS_CU_SHIFT))) ) {
3504     mips_cpu_exception(cpu, EXCEPTION_CPU, 0, 0, cpnr, 0, 0, 0);
3505     } else {
3506     /* Special handling of 64-bit loads
3507     on 32-bit CPUs, and on newer CPUs
3508     in 32-bit compatiblity mode: */
3509     if ((hi6==HI6_LDC1 || hi6==HI6_LDC2) &&
3510     (cpu->cd.mips.cpu_type.isa_level <= 2 ||
3511     !(cp0->reg[COP0_STATUS] & STATUS_FR))) {
3512     uint64_t a, b;
3513     a = (int64_t)(int32_t) (value & 0xffffffffULL);
3514     b = (int64_t)(int32_t) (value >> 32);
3515     coproc_register_write(cpu,
3516     cpu->cd.mips.coproc[cpnr], rt, &a,
3517 dpavlin 10 hi6==HI6_LDC1 || hi6==HI6_LDC2, 0);
3518 dpavlin 2 coproc_register_write(cpu,
3519     cpu->cd.mips.coproc[cpnr], rt ^ 1, &b,
3520 dpavlin 10 hi6==HI6_LDC1 || hi6==HI6_LDC2, 0);
3521 dpavlin 2 if (rt & 1)
3522     fatal("WARNING: LDCx in 32-bit mode to odd register!\n");
3523     } else {
3524     coproc_register_write(cpu,
3525     cpu->cd.mips.coproc[cpnr], rt, &value,
3526 dpavlin 10 hi6==HI6_LDC1 || hi6==HI6_LDC2, 0);
3527 dpavlin 2 }
3528     }
3529     break;
3530     default: if (rt != 0)
3531     cpu->cd.mips.gpr[rt] = value;
3532     }
3533     }
3534    
3535     if (linked && st==1) {
3536     /*
3537     * The store succeeded. Invalidate any other
3538     * cpu's store to this cache line, and then
3539     * return 1 in gpr rt:
3540     *
3541     * (this is a semi-ugly hack using global
3542     * 'cpus')
3543     *
3544     * TODO: How about invalidating other CPUs
3545     * stores to this cache line, even if this
3546     * was _NOT_ a linked store?
3547     */
3548     for (i=0; i<cpu->machine->ncpus; i++) {
3549     if (cpu->machine->cpus[i]->cd.mips.rmw) {
3550     uint64_t yaddr = addr;
3551     uint64_t xaddr =
3552     cpu->machine->cpus[i]->cd.mips.rmw_addr;
3553     uint64_t mask;
3554     mask = ~(cpu->machine->cpus[i]->
3555     cd.mips.cache_linesize[CACHE_DATA]
3556     - 1);
3557     xaddr &= mask;
3558     yaddr &= mask;
3559     if (xaddr == yaddr) {
3560     cpu->machine->cpus[i]->cd.mips.rmw = 0;
3561     cpu->machine->cpus[i]->cd.mips.rmw_addr = 0;
3562     }
3563     }
3564     }
3565    
3566     if (rt != 0)
3567     cpu->cd.mips.gpr[rt] = 1;
3568    
3569     if (instruction_trace_cached)
3570     debug(" [no collision] ");
3571     cpu->cd.mips.rmw = 0;
3572     }
3573    
3574     if (instruction_trace_cached) {
3575     switch (wlen) {
3576     case 2: debug("0x%04x", (int)value); break;
3577     case 4: debug("0x%08x", (int)value); break;
3578     case 8: debug("0x%016llx", (long long)value);
3579     break;
3580     case 16:debug("0x%016llx", (long long)value_hi);
3581     debug("%016llx", (long long)value);
3582     break;
3583     default:debug("0x%02x", (int)value);
3584     }
3585     debug("]\n");
3586     }
3587     return 1;
3588     case HI6_LWL: /* Unaligned load/store */
3589     case HI6_LWR:
3590     case HI6_LDL:
3591     case HI6_LDR:
3592     case HI6_SWL:
3593     case HI6_SWR:
3594     case HI6_SDL:
3595     case HI6_SDR:
3596     /* For L (Left): address is the most significant byte */
3597     /* For R (Right): address is the least significant byte */
3598     addr = cpu->cd.mips.gpr[rs] + imm;
3599    
3600     is_left = 0;
3601     if (hi6 == HI6_SWL || hi6 == HI6_LWL ||
3602     hi6 == HI6_SDL || hi6 == HI6_LDL)
3603     is_left = 1;
3604    
3605     wlen = 0; st = 0;
3606     signd = 0;
3607     if (hi6 == HI6_LWL || hi6 == HI6_LWR)
3608     signd = 1;
3609    
3610     if (hi6 == HI6_LWL || hi6 == HI6_LWR) { wlen = 4; st = 0; }
3611     if (hi6 == HI6_SWL || hi6 == HI6_SWR) { wlen = 4; st = 1; }
3612     if (hi6 == HI6_LDL || hi6 == HI6_LDR) { wlen = 8; st = 0; }
3613     if (hi6 == HI6_SDL || hi6 == HI6_SDR) { wlen = 8; st = 1; }
3614    
3615     dir = 1; /* big endian, Left */
3616     reg_dir = -1;
3617     reg_ofs = wlen - 1; /* byte offset in the register */
3618     if (!is_left) {
3619     dir = -dir;
3620     reg_ofs = 0;
3621     reg_dir = 1;
3622     }
3623     if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
3624     dir = -dir;
3625    
3626     result_value = cpu->cd.mips.gpr[rt];
3627    
3628     if (st) {
3629     /* Store: */
3630     uint64_t aligned_addr = addr & ~(wlen-1);
3631     unsigned char aligned_word[8];
3632     uint64_t oldpc = cpu->pc;
3633     /*
3634     * NOTE (this is ugly): The memory_rw()
3635     * call generates a TLBL exception, if there
3636     * is a tlb refill exception. However, since
3637     * this is a Store, the exception is converted
3638     * to a TLBS:
3639     */
3640     int ok = cpu->memory_rw(cpu, cpu->mem,
3641     aligned_addr, &aligned_word[0], wlen,
3642     MEM_READ, CACHE_DATA);
3643     if (!ok) {
3644     if (cpu->pc != oldpc) {
3645     cp0->reg[COP0_CAUSE] &= ~CAUSE_EXCCODE_MASK;
3646     cp0->reg[COP0_CAUSE] |= (EXCEPTION_TLBS << CAUSE_EXCCODE_SHIFT);
3647     }
3648     return 1;
3649     }
3650    
3651     for (i=0; i<wlen; i++) {
3652     tmpaddr = addr + i*dir;
3653     /* Have we moved into another word/dword? Then stop: */
3654     if ( (tmpaddr & ~(wlen-1)) != (addr & ~(wlen-1)) )
3655     break;
3656    
3657     /* debug("unaligned byte at %016llx, reg_ofs=%i reg=0x%016llx\n",
3658     tmpaddr, reg_ofs, (long long)result_value); */
3659    
3660     /* Store one byte: */
3661     aligned_word[tmpaddr & (wlen-1)] = (result_value >> (reg_ofs * 8)) & 255;
3662    
3663     reg_ofs += reg_dir;
3664     }
3665    
3666     ok = cpu->memory_rw(cpu, cpu->mem,
3667     aligned_addr, &aligned_word[0], wlen,
3668     MEM_WRITE, CACHE_DATA);
3669     if (!ok)
3670     return 1;
3671     } else {
3672     /* Load: */
3673     uint64_t aligned_addr = addr & ~(wlen-1);
3674     unsigned char aligned_word[8], databyte;
3675     int ok = cpu->memory_rw(cpu, cpu->mem,
3676     aligned_addr, &aligned_word[0], wlen,
3677     MEM_READ, CACHE_DATA);
3678     if (!ok)
3679     return 1;
3680    
3681     for (i=0; i<wlen; i++) {
3682     tmpaddr = addr + i*dir;
3683     /* Have we moved into another word/dword? Then stop: */
3684     if ( (tmpaddr & ~(wlen-1)) != (addr & ~(wlen-1)) )
3685     break;
3686    
3687     /* debug("unaligned byte at %016llx, reg_ofs=%i reg=0x%016llx\n",
3688     tmpaddr, reg_ofs, (long long)result_value); */
3689    
3690     /* Load one byte: */
3691     databyte = aligned_word[tmpaddr & (wlen-1)];
3692     result_value &= ~((uint64_t)0xff << (reg_ofs * 8));
3693     result_value |= (uint64_t)databyte << (reg_ofs * 8);
3694    
3695     reg_ofs += reg_dir;
3696     }
3697    
3698     if (rt != 0)
3699     cpu->cd.mips.gpr[rt] = result_value;
3700     }
3701    
3702     /* Sign extend for 32-bit load lefts: */
3703     if (!st && signd && wlen == 4) {
3704     cpu->cd.mips.gpr[rt] &= 0xffffffffULL;
3705     if (cpu->cd.mips.gpr[rt] & 0x80000000ULL)
3706     cpu->cd.mips.gpr[rt] |= 0xffffffff00000000ULL;
3707     }
3708    
3709     if (instruction_trace_cached) {
3710     char *t;
3711     switch (wlen) {
3712     case 2: t = "0x%04llx"; break;
3713     case 4: t = "0x%08llx"; break;
3714     case 8: t = "0x%016llx"; break;
3715     default: t = "0x%02llx";
3716     }
3717     debug(t, (long long)cpu->cd.mips.gpr[rt]);
3718     debug("]\n");
3719     }
3720    
3721     return 1;
3722     }
3723     return 1;
3724     case HI6_REGIMM:
3725     regimm5 = instr[2] & 0x1f;
3726    
3727     if (show_opcode_statistics)
3728     cpu->cd.mips.stats__regimm[regimm5] ++;
3729    
3730     switch (regimm5) {
3731     case REGIMM_BLTZ:
3732     case REGIMM_BGEZ:
3733     case REGIMM_BLTZL:
3734     case REGIMM_BGEZL:
3735     case REGIMM_BLTZAL:
3736     case REGIMM_BLTZALL:
3737     case REGIMM_BGEZAL:
3738     case REGIMM_BGEZALL:
3739     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
3740     imm = (instr[1] << 8) + instr[0];
3741     if (imm >= 32768) /* signed 16-bit */
3742     imm -= 65536;
3743    
3744     cond = and_link = likely = 0;
3745    
3746     switch (regimm5) {
3747     case REGIMM_BLTZL: likely = 1;
3748     case REGIMM_BLTZ: cond = (cpu->cd.mips.gpr[rs] & ((uint64_t)1 << 63)) != 0;
3749     break;
3750     case REGIMM_BGEZL: likely = 1;
3751     case REGIMM_BGEZ: cond = (cpu->cd.mips.gpr[rs] & ((uint64_t)1 << 63)) == 0;
3752     break;
3753    
3754     case REGIMM_BLTZALL: likely = 1;
3755     case REGIMM_BLTZAL: and_link = 1;
3756     cond = (cpu->cd.mips.gpr[rs] & ((uint64_t)1 << 63)) != 0;
3757     break;
3758     case REGIMM_BGEZALL: likely = 1;
3759     case REGIMM_BGEZAL: and_link = 1;
3760     cond = (cpu->cd.mips.gpr[rs] & ((uint64_t)1 << 63)) == 0;
3761     break;
3762     }
3763    
3764     if (and_link)
3765     cpu->cd.mips.gpr[31] = cached_pc + 4;
3766    
3767     if (cond) {
3768     cpu->cd.mips.delay_slot = TO_BE_DELAYED;
3769     cpu->cd.mips.delay_jmpaddr = cached_pc + (imm << 2);
3770     } else {
3771     if (likely)
3772     cpu->cd.mips.nullify_next = 1; /* nullify delay slot */
3773     }
3774    
3775     return 1;
3776     default:
3777     if (!instruction_trace_cached) {
3778     fatal("cpu%i @ %016llx: %02x%02x%02x%02x%s\t",
3779     cpu->cpu_id, cpu->cd.mips.pc_last,
3780     instr[3], instr[2], instr[1], instr[0], cpu_flags(cpu));
3781     }
3782     fatal("unimplemented regimm5 = 0x%02x\n", regimm5);
3783     cpu->running = 0;
3784     return 1;
3785     }
3786     /* NOT REACHED */
3787     case HI6_J:
3788     case HI6_JAL:
3789     if (cpu->cd.mips.delay_slot) {
3790     fatal("j/jal: jump inside a jump's delay slot, or similar. TODO\n");
3791     cpu->running = 0;
3792     return 1;
3793     }
3794     imm = ((instr[3] & 3) << 24) + (instr[2] << 16) + (instr[1] << 8) + instr[0];
3795     imm <<= 2;
3796    
3797     if (hi6 == HI6_JAL)
3798     cpu->cd.mips.gpr[31] = cached_pc + 4; /* pc already increased by 4 earlier */
3799    
3800     addr = cached_pc & ~((1 << 28) - 1);
3801     addr |= imm;
3802    
3803     cpu->cd.mips.delay_slot = TO_BE_DELAYED;
3804     cpu->cd.mips.delay_jmpaddr = addr;
3805    
3806     if (!quiet_mode_cached && cpu->machine->show_trace_tree &&
3807     hi6 == HI6_JAL) {
3808     cpu->cd.mips.show_trace_delay = 2;
3809     cpu->cd.mips.show_trace_addr = addr;
3810     }
3811    
3812     return 1;
3813     case HI6_COP0:
3814     case HI6_COP1:
3815     case HI6_COP2:
3816     case HI6_COP3:
3817     imm = (instr[3] << 24) + (instr[2] << 16) + (instr[1] << 8) + instr[0];
3818     imm &= ((1 << 26) - 1);
3819    
3820     cpnr = 0;
3821     if (hi6 == HI6_COP0) cpnr = 0;
3822     if (hi6 == HI6_COP1) cpnr = 1;
3823     if (hi6 == HI6_COP2) cpnr = 2;
3824     if (hi6 == HI6_COP3) cpnr = 3;
3825    
3826     /*
3827     * If there is no coprocessor nr cpnr, or we are running in
3828     * userland and the coprocessor is not marked as Useable in
3829     * the status register of CP0, then we get an exception.
3830     *
3831     * An exception (hehe) to this rule is that the kernel should
3832     * always be able to access CP0.
3833     */
3834     /* Set tmp = 1 if we're in user mode. */
3835     tmp = 0;
3836     switch (cpu->cd.mips.cpu_type.exc_model) {
3837     case EXC3K:
3838     /*
3839     * NOTE: If the KU bit is checked, Linux crashes.
3840     * It is the PC that counts. TODO: Check whether
3841     * this is true or not for R4000 as well.
3842     */
3843     if (cached_pc <= 0x7fffffff) /* if (cp0->reg[COP0_STATUS] & MIPS1_SR_KU_CUR) */
3844     tmp = 1;
3845     break;
3846     default:
3847     /* R4000 etc: (TODO: How about supervisor mode?) */
3848     if (((cp0->reg[COP0_STATUS] & STATUS_KSU_MASK) >> STATUS_KSU_SHIFT) != KSU_KERNEL)
3849     tmp = 1;
3850     if (cp0->reg[COP0_STATUS] & STATUS_ERL)
3851     tmp = 0;
3852     if (cp0->reg[COP0_STATUS] & STATUS_EXL)
3853     tmp = 0;
3854     break;
3855     }
3856     if (cpu->cd.mips.coproc[cpnr] == NULL ||
3857     (tmp && !(cp0->reg[COP0_STATUS] & ((1 << cpnr) << STATUS_CU_SHIFT))) ||
3858     (!tmp && cpnr >= 1 && !(cp0->reg[COP0_STATUS] & ((1 << cpnr) << STATUS_CU_SHIFT)))
3859     ) {
3860     if (instruction_trace_cached)
3861     debug("cop%i\t0x%08x => coprocessor unusable\n", cpnr, (int)imm);
3862    
3863     mips_cpu_exception(cpu, EXCEPTION_CPU, 0, 0, cpnr, 0, 0, 0);
3864     } else {
3865     /*
3866     * Execute the coprocessor function. The
3867     * coproc_function code outputs instruction
3868     * trace, if necessary.
3869     */
3870     coproc_function(cpu, cpu->cd.mips.coproc[cpnr],
3871     cpnr, imm, 0, 1);
3872     }
3873     return 1;
3874     case HI6_CACHE:
3875     rt = ((instr[3] & 3) << 3) + (instr[2] >> 5); /* base */
3876     copz = instr[2] & 31;
3877     imm = (instr[1] << 8) + instr[0];
3878    
3879     cache_op = copz >> 2;
3880     which_cache = copz & 3;
3881    
3882     /*
3883     * TODO: The cache instruction is implementation dependant.
3884     * This is really ugly.
3885     */
3886    
3887     #if 0
3888     Remove this...
3889    
3890     /* if (cpu->cd.mips.cpu_type.mmu_model == MMU10K) { */
3891     /* printf("taghi=%08lx taglo=%08lx\n",
3892     (long)cp0->reg[COP0_TAGDATA_HI],
3893     (long)cp0->reg[COP0_TAGDATA_LO]);
3894     */
3895     if (cp0->reg[COP0_TAGDATA_HI] == 0 &&
3896     cp0->reg[COP0_TAGDATA_LO] == 0) {
3897     /* Normal cache operation: */
3898     cpu->r10k_cache_disable_TODO = 0;
3899     } else {
3900     /* Dislocate the cache: */
3901     cpu->r10k_cache_disable_TODO = 1;
3902     }
3903     /* } */
3904     #endif
3905    
3906     /*
3907     * Clear the LLbit (at least on R10000):
3908     * TODO: How about R4000?
3909     */
3910     cpu->cd.mips.rmw = 0;
3911    
3912     return 1;
3913     case HI6_SPECIAL2:
3914     special6 = instr[0] & 0x3f;
3915    
3916     if (show_opcode_statistics)
3917     cpu->cd.mips.stats__special2[special6] ++;
3918    
3919     instrword = (instr[3] << 24) + (instr[2] << 16) + (instr[1] << 8) + instr[0];
3920    
3921     rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
3922     rt = instr[2] & 31;
3923     rd = (instr[1] >> 3) & 31;
3924    
3925     /* printf("special2 %08x rs=0x%02x rt=0x%02x rd=0x%02x\n", instrword, rs,rt,rd); */
3926    
3927     /*
3928     * Many of these can be found in the R5000 docs, or figured out
3929     * by studying binutils source code for MIPS instructions.
3930     */
3931    
3932     if ((instrword & 0xfc0007ffULL) == 0x70000000) {
3933     {
3934     int32_t a, b;
3935     int64_t c;
3936     a = (int32_t)cpu->cd.mips.gpr[rs];
3937     b = (int32_t)cpu->cd.mips.gpr[rt];
3938     c = a * b;
3939     c += (cpu->cd.mips.lo & 0xffffffffULL)
3940     + (cpu->cd.mips.hi << 32);
3941     cpu->cd.mips.lo = (int64_t)((int32_t)c);
3942     cpu->cd.mips.hi = (int64_t)((int32_t)(c >> 32));
3943    
3944     /*
3945     * The R5000 manual says that rd should be all zeros,
3946     * but it isn't on R5900. I'm just guessing here that
3947     * it stores the value in register rd, in addition to hi/lo.
3948     * TODO
3949     */
3950     if (rd != 0)
3951     cpu->cd.mips.gpr[rd] = cpu->cd.mips.lo;
3952     }
3953     } else if ((instrword & 0xffff07ffULL) == 0x70000209
3954     || (instrword & 0xffff07ffULL) == 0x70000249) {
3955     /*
3956     * This is just a guess for R5900, I've not found any docs on this one yet.
3957     *
3958     * pmfhi/pmflo rd
3959     *
3960     * If the lowest 8 bits of the instruction word are 0x09, it's a pmfhi.
3961     * If the lowest bits are 0x49, it's a pmflo.
3962     *
3963     * A wild guess is that this is a 128-bit version of mfhi/mflo.
3964     * For now, this is implemented as 64-bit only. (TODO)
3965     */
3966     if (instr[0] == 0x49) {
3967     cpu->cd.mips.gpr[rd] = cpu->cd.mips.lo;
3968     } else {
3969     cpu->cd.mips.gpr[rd] = cpu->cd.mips.hi;
3970     }
3971     } else if ((instrword & 0xfc1fffff) == 0x70000269 || (instrword & 0xfc1fffff) == 0x70000229) {
3972     /*
3973     * This is just a guess for R5900, I've not found any docs on this one yet.
3974     *
3975     * pmthi/pmtlo rs (pmtlo = 269, pmthi = 229)
3976     *
3977     * A wild guess is that this is a 128-bit version of mthi/mtlo.
3978     * For now, this is implemented as 64-bit only. (TODO)
3979     */
3980     if (instr[0] == 0x69) {
3981     cpu->cd.mips.lo = cpu->cd.mips.gpr[rs];
3982     } else {
3983     cpu->cd.mips.hi = cpu->cd.mips.gpr[rs];
3984     }
3985     } else if ((instrword & 0xfc0007ff) == 0x700004a9) {
3986     /*
3987     * This is just a guess for R5900, I've not found any docs on this one yet.
3988     *
3989     * por dst,src,src2 ==> rs=src rt=src2 rd=dst
3990     *
3991     * A wild guess is that this is a 128-bit "or" between two registers.
3992     * For now, let's just or using 64-bits. (TODO)
3993     */
3994     cpu->cd.mips.gpr[rd] = cpu->cd.mips.gpr[rs] | cpu->cd.mips.gpr[rt];
3995     } else if ((instrword & 0xfc0007ff) == 0x70000488) {
3996     /*
3997     * R5900 "undocumented" pextlw. TODO: find out if this is correct.
3998     * It seems that this instruction is used to combine two 32-bit
3999     * words into a 64-bit dword, typically before a sd (store dword).
4000     */
4001     cpu->cd.mips.gpr[rd] =
4002     ((cpu->cd.mips.gpr[rs] & 0xffffffffULL) << 32) /* TODO: switch rt and rs? */
4003     | (cpu->cd.mips.gpr[rt] & 0xffffffffULL);
4004     } else if (special6 == SPECIAL2_MUL) {
4005     cpu->cd.mips.gpr[rd] = (int64_t)cpu->cd.mips.gpr[rt] *
4006     (int64_t)cpu->cd.mips.gpr[rs];
4007     } else if (special6 == SPECIAL2_CLZ) {
4008     /* clz: count leading zeroes */
4009     int i, n=0;
4010     for (i=31; i>=0; i--) {
4011     if (cpu->cd.mips.gpr[rs] & ((uint32_t)1 << i))
4012     break;
4013     else
4014     n++;
4015     }
4016     cpu->cd.mips.gpr[rd] = n;
4017     } else if (special6 == SPECIAL2_CLO) {
4018     /* clo: count leading ones */
4019     int i, n=0;
4020     for (i=31; i>=0; i--) {
4021     if (cpu->cd.mips.gpr[rs] & ((uint32_t)1 << i))
4022     n++;
4023     else
4024     break;
4025     }
4026     cpu->cd.mips.gpr[rd] = n;
4027     } else if (special6 == SPECIAL2_DCLZ) {
4028     /* dclz: count leading zeroes */
4029     int i, n=0;
4030     for (i=63; i>=0; i--) {
4031     if (cpu->cd.mips.gpr[rs] & ((uint64_t)1 << i))
4032     break;
4033     else
4034     n++;
4035     }
4036     cpu->cd.mips.gpr[rd] = n;
4037     } else if (special6 == SPECIAL2_DCLO) {
4038     /* dclo: count leading ones */
4039     int i, n=0;
4040     for (i=63; i>=0; i--) {
4041     if (cpu->cd.mips.gpr[rs] & ((uint64_t)1 << i))
4042     n++;
4043     else
4044     break;
4045     }
4046     cpu->cd.mips.gpr[rd] = n;
4047     } else {
4048     if (!instruction_trace_cached) {
4049     fatal("cpu%i @ %016llx: %02x%02x%02x%02x%s\t",
4050     cpu->cpu_id, cpu->cd.mips.pc_last,
4051     instr[3], instr[2], instr[1], instr[0], cpu_flags(cpu));
4052     }
4053     fatal("unimplemented special_2 = 0x%02x, rs=0x%02x rt=0x%02x rd=0x%02x\n",
4054     special6, rs, rt, rd);
4055     cpu->running = 0;
4056     return 1;
4057     }
4058     return 1;
4059     default:
4060     if (!instruction_trace_cached) {
4061     fatal("cpu%i @ %016llx: %02x%02x%02x%02x%s\t",
4062     cpu->cpu_id, cpu->cd.mips.pc_last,
4063     instr[3], instr[2], instr[1], instr[0], cpu_flags(cpu));
4064     }
4065     fatal("unimplemented hi6 = 0x%02x\n", hi6);
4066     cpu->running = 0;
4067     return 1;
4068     }
4069    
4070     /* NOTREACHED */
4071     }
4072    
4073    
4074     #define CPU_RUN mips_cpu_run
4075     #define CPU_RUN_MIPS
4076     #define CPU_RINSTR mips_cpu_run_instr
4077     #include "cpu_run.c"
4078     #undef CPU_RINSTR
4079     #undef CPU_RUN_MIPS
4080     #undef CPU_RUN
4081    
4082    
4083     /*
4084     * mips_cpu_dumpinfo():
4085     *
4086     * Debug dump of MIPS-specific CPU data for specific CPU.
4087     */
4088     void mips_cpu_dumpinfo(struct cpu *cpu)
4089     {
4090     struct mips_cpu_type_def *ct = &cpu->cd.mips.cpu_type;
4091    
4092     debug(" (%i-bit ", (ct->isa_level < 3 ||
4093     ct->isa_level == 32)? 32 : 64);
4094    
4095     debug("%s, ", cpu->byte_order == EMUL_BIG_ENDIAN? "BE" : "LE");
4096    
4097     debug("nTLB=%i", ct->nr_of_tlb_entries);
4098    
4099     if (ct->default_picache || ct->default_pdcache)
4100     debug(", I+D = %i+%i KB",
4101     (1 << ct->default_picache) / 1024,
4102     (1 << ct->default_pdcache) / 1024);
4103    
4104     if (ct->default_scache) {
4105     int kb = (1 << ct->default_scache) / 1024;
4106     debug(", L2 = %i %cB",
4107     kb >= 1024? kb / 1024 : kb,
4108     kb >= 1024? 'M' : 'K');
4109     }
4110    
4111     debug(")\n");
4112     }
4113    
4114    
4115     /*
4116     * mips_cpu_list_available_types():
4117     *
4118     * Print a list of available MIPS CPU types.
4119     */
4120     void mips_cpu_list_available_types(void)
4121     {
4122     int i, j;
4123     struct mips_cpu_type_def cpu_type_defs[] = MIPS_CPU_TYPE_DEFS;
4124    
4125     i = 0;
4126     while (cpu_type_defs[i].name != NULL) {
4127     debug("%s", cpu_type_defs[i].name);
4128     for (j=10 - strlen(cpu_type_defs[i].name); j>0; j--)
4129     debug(" ");
4130     i++;
4131     if ((i % 6) == 0 || cpu_type_defs[i].name == NULL)
4132     debug("\n");
4133     }
4134     }
4135    
4136    
4137     /*
4138     * mips_cpu_family_init():
4139     *
4140     * Fill in the cpu_family struct for MIPS.
4141     */
4142     int mips_cpu_family_init(struct cpu_family *fp)
4143     {
4144     fp->name = "MIPS";
4145     fp->cpu_new = mips_cpu_new;
4146     fp->list_available_types = mips_cpu_list_available_types;
4147     fp->register_match = mips_cpu_register_match;
4148     fp->disassemble_instr = mips_cpu_disassemble_instr;
4149     fp->register_dump = mips_cpu_register_dump;
4150     fp->run = mips_cpu_run;
4151     fp->dumpinfo = mips_cpu_dumpinfo;
4152     fp->show_full_statistics = mips_cpu_show_full_statistics;
4153     fp->tlbdump = mips_cpu_tlbdump;
4154     fp->interrupt = mips_cpu_interrupt;
4155     fp->interrupt_ack = mips_cpu_interrupt_ack;
4156     return 1;
4157     }
4158    
4159    
4160     #endif /* ENABLE_MIPS */

  ViewVC Help
Powered by ViewVC 1.1.26