/[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 4 - (hide annotations)
Mon Oct 8 16:18:00 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 119475 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.707 2005/04/27 16:37:33 debug Exp $
20050408	Some minor updates to the wdc. Linux now doesn't complain
		anymore if a disk is non-present.
20050409	Various minor fixes (a bintrans bug, and some other things).
		The wdc seems to work with Playstation2 emulation, but there
		is a _long_ annoying delay when disks are detected.
		Fixing a really important bintrans bug (when devices and RAM
		are mixed within 4KB pages), which was triggered with
		NetBSD/playstation2 kernels.
20050410	Adding a dummy dev_ps2_ether (just so that NetBSD doesn't
		complain as much during bootup).
		Symbols starting with '$' are now ignored.
		Renaming dev_ps2_ohci.c to dev_ohci.c, etc.
20050411	Moving the bintrans-cache-isolation check from cpu_mips.c to
		cpu_mips_coproc.c. (I thought this would give a speedup, but
		it's not noticable.)
		Better playstation2 sbus interrupt code.
		Skip ahead many ticks if the count register is read manually.
		(This increases the speed of delay-loops that simply read
		the count register.)
20050412	Updates to the playstation2 timer/interrupt code.
		Some other minor updates.
20050413	NetBSD/cobalt runs from a disk image :-) including userland;
		updating the documentation on how to install NetBSD/cobalt
		using NetBSD/pmax (!).
		Some minor bintrans updates (no real speed improvement) and
		other minor updates (playstation2 now uses the -o options).
20050414	Adding a dummy x86 (and AMD64) mode.
20050415	Adding some (32-bit and 16-bit) x86 instructions.
		Adding some initial support for non-SCSI, non-IDE floppy
		images. (The x86 mode can boot from these, more or less.)
		Moving the devices/ and include/ directories to src/devices/
		and src/include/, respectively.
20050416	Continuing on the x86 stuff. (Adding pc_bios.c and some simple
		support for software interrupts in 16-bit mode.)
20050417	Ripping out most of the x86 instruction decoding stuff, trying
		to rewrite it in a cleaner way.
		Disabling some of the least working CPU families in the
		configure script (sparc, x86, alpha, hppa), so that they are
		not enabled by default.
20050418	Trying to fix the bug which caused problems when turning on
		and off bintrans interactively, by flushing the bintrans cache
		whenever bintrans is manually (re)enabled.
20050419	Adding the 'lswi' ppc instruction.
		Minor updates to the x86 instruction decoding.
20050420	Renaming x86 register name indices from R_xx to X86_R_xx (this
		makes building on Tru64 nicer).
20050422	Adding a check for duplicate MIPS TLB entries on tlbwr/tlbwi.
20050427	Adding screenshots to guestoses.html.
		Some minor fixes and testing for the next release.

==============  RELEASE 0.3.2  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26