/[gxemul]/trunk/src/cpus/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/cpus/cpu_mips.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 20 - (hide annotations)
Mon Oct 8 16:19:23 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 119367 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1055 2005/11/25 22:48:36 debug Exp $
20051031	Adding disassembly support for more ARM instructions (clz,
		smul* etc), and adding a hack to support "new tiny" pages
		for StrongARM.
20051101	Minor documentation updates (NetBSD 2.0.2 -> 2.1, and OpenBSD
		3.7 -> 3.8, and lots of testing).
		Changing from 1-sector PIO mode 0 transfers to 128-sector PIO
		mode 3 (in dev_wdc).
		Various minor ARM dyntrans updates (pc-relative loads from
		within the same page as the instruction are now treated as
		constant "mov").
20051102	Re-enabling instruction combinations (they were accidentally
		disabled).
		Dyntrans TLB entries are now overwritten using a round-robin
		scheme instead of randomly. This increases performance.
		Fixing a typo in file.c (thanks to Chuan-Hua Chang for
		noticing it).
		Experimenting with adding ATAPI support to dev_wdc (to make
		emulated *BSD detect cdroms as cdroms, not harddisks).
20051104	Various minor updates.
20051105	Continuing on the ATAPI emulation. Seems to work well enough
		for a NetBSD/cats installation, but not OpenBSD/cats.
		Various other updates.
20051106	Modifying the -Y command line option to allow scaleup with
		certain graphic controllers (only dev_vga so far), not just
		scaledown.
		Some minor dyntrans cleanups.
20051107	Beginning a cleanup up the PCI subsystem (removing the
		read_register hack, etc).
20051108	Continuing the cleanup; splitting up some pci devices into a
		normal autodev device and some separate pci glue code.
20051109	Continuing on the PCI bus stuff; all old pci_*.c have been
		incorporated into normal devices and/or rewritten as glue code
		only, adding a dummy Intel 82371AB PIIX4 for Malta (not really
		tested yet).
		Minor pckbc fix so that Linux doesn't complain.
		Working on the DEC 21143 NIC (ethernet mac rom stuff mostly).
		Various other minor fixes.
20051110	Some more ARM dyntrans fine-tuning (e.g. some instruction
		combinations (cmps followed by conditional branch within the
		same page) and special cases for DPIs with regform when the
		shifter isn't used).
20051111	ARM dyntrans updates: O(n)->O(1) for just-mark-as-non-
		writable in the generic pc_to_pointers function, and some other
		minor hacks.
		Merging Cobalt and evbmips (Malta) ISA interrupt handling,
		and some minor fixes to allow Linux to accept harddisk irqs.
20051112	Minor device updates (pckbc, dec21143, lpt, ...), most
		importantly fixing the ALI M1543/M5229 so that harddisk irqs
		work with Linux/CATS.
20051113	Some more generalizations of the PCI subsystem.
		Finally took the time to add a hack for SCSI CDROM TOCs; this
		enables OpenBSD to use partition 'a' (as needed by the OpenBSD
		installer), and Windows NT's installer to get a bit further.
		Also fixing dev_wdc to allow Linux to detect ATAPI CDROMs.
		Continuing on the DEC 21143.
20051114	Minor ARM dyntrans tweaks; ARM cmps+branch optimization when
		comparing with 0, and generalizing the xchg instr. comb.
		Adding disassembly of ARM mrrc/mcrr and q{,d}{add,sub}.
20051115	Continuing on various PPC things (BATs, other address trans-
		lation things, various loads/stores, BeBox emulation, etc.).
		Beginning to work on PPC interrupt/exception support.
20051116	Factoring out some code which initializes legacy ISA devices
		from those machines that use them (bus_isa).
		Continuing on PPC interrupt/exception support.
20051117	Minor Malta fixes: RTC year offset = 80, disabling a speed hack
		which caused NetBSD to detect a too fast cpu, and adding a new
		hack to make Linux detect a faster cpu.
		Continuing on the Artesyn PM/PPC emulation mode.
		Adding an Algor emulation skeleton (P4032 and P5064);
		implementing some of the basics.
		Continuing on PPC emulation in general; usage of unimplemented
		SPRs is now easier to track, continuing on memory/exception
		related issues, etc.
20051118	More work on PPC emulation (tgpr0..3, exception handling,
		memory stuff, syscalls, etc.).
20051119	Changing the ARM dyntrans code to mostly use cpu->pc, and not
		necessarily use arm reg 15. Seems to work.
		Various PPC updates; continuing on the PReP emulation mode.
20051120	Adding a workaround/hack to dev_mc146818 to allow NetBSD/prep
		to detect the clock.
20051121	More cleanup of the PCI bus (memory and I/O bases, etc).
		Continuing on various PPC things (decrementer and timebase,
		WDCs on obio (on PReP) use irq 13, not 14/15).
20051122	Continuing on the CPC700 controller (interrupts etc) for PMPPC,
		and on PPC stuff in general.
		Finally! After some bug fixes to the virtual to physical addr
		translation, NetBSD/{prep,pmppc} 2.1 reach userland and are
		stable enough to be interacted with.
		More PCI updates; reverse-endian device access for PowerPC etc.
20051123	Generalizing the IEEE floating point subsystem (moving it out
		from src/cpus/cpu_mips_coproc.c into a new src/float_emul.c).
		Input via slave xterms was sometimes not really working; fixing
		this for ns16550, and a warning message is now displayed if
		multiple non-xterm consoles are active.
		Adding some PPC floating point support, etc.
		Various interrupt related updates (dev_wdc, _ns16550, _8259,
		and the isa32 common code in machine.c).
		NetBSD/prep can now be installed! :-) (Well, with some manual
		commands necessary before running sysinst.) Updating the
		documentation and various other things to reflect this.
20051124	Various minor documentation updates.
		Continuing the work on the DEC 21143 NIC.
20051125	LOTS of work on the 21143. Both OpenBSD and NetBSD work fine
		with it now, except that OpenBSD sometimes gives a time-out
		warning.
		Minor documentation updates.

==============  RELEASE 0.3.7  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26