/[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 22 - (hide annotations)
Mon Oct 8 16:19:37 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 119234 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1121 2006/02/18 21:03:08 debug Exp $
20051126	Cobalt and PReP now work with the 21143 NIC.
		Continuing on Alpha dyntrans things.
		Fixing some more left-shift-by-24 to unsigned.
20051127	Working on OpenFirmware emulation; major cleanup/redesign.
		Progress on MacPPC emulation: NetBSD detects two CPUs (when
		running with -n 2), framebuffer output (for text) works.
		Adding quick-hack Bandit PCI controller and "gc" interrupt
		controller for MacPPC.
20051128	Changing from a Bandit to a Uni-North controller for macppc.
		Continuing on OpenFirmware and MacPPC emulation in general
		(obio controller, and wdc attached to the obio seems to work).
20051129	More work on MacPPC emulation (adding a dummy ADB controller).
		Continuing the PCI bus cleanup (endianness and tag composition)
		and rewriting all PCI controllers' access functions.
20051130	Various minor PPC dyntrans optimizations.
		Manually inlining some parts of the framebuffer redraw routine.
		Slowly beginning the conversion of the old MIPS emulation into
		dyntrans (but this will take quite some time to get right).
		Generalizing quick_pc_to_pointers.
20051201	Documentation update (David Muse has made available a kernel
		which simplifies Debian/DECstation installation).
		Continuing on the ADB bus controller.
20051202	Beginning a rewrite of the Zilog serial controller (dev_zs).
20051203	Continuing on the zs rewrite (now called dev_z8530); conversion
		to devinit style.
		Reworking some of the input-only vs output-only vs input-output
		details of src/console.c, better warning messages, and adding
		a debug dump.
		Removing the concept of "device state"; it wasn't really used.
		Changing some debug output (-vv should now be used to show all
		details about devices and busses; not shown during normal
		startup anymore).
		Beginning on some SPARC instruction disassembly support.
20051204	Minor PPC updates (WALNUT skeleton stuff).
		Continuing on the MIPS dyntrans rewrite.
		More progress on the ADB controller (a keyboard is "detected"
		by NetBSD and OpenBSD).
		Downgrading OpenBSD/arc as a guest OS from "working" to
		"almost working" in the documentation.
		Progress on Algor emulation ("v3" PCI controller).
20051205	Minor updates.
20051207	Sorting devices according to address; this reduces complexity
		of device lookups from O(n) to O(log n) in memory_rw (but no
		real performance increase (yet) in experiments).
20051210	Beginning the work on native dyntrans backends (by making a
		simple skeleton; so far only for Alpha hosts).
20051211	Some very minor SPARC updates.
20051215	Fixing a bug in the MIPS mul (note: not mult) instruction,
		so it also works with non-64-bit emulation. (Thanks to Alec
		Voropay for noticing the problem.)
20051216	More work on the fake/empty/simple/skeleton/whatever backend;
		performance doesn't increase, so this isn't really worth it,
		but it was probably worth it to prepare for a real backend
		later.
20051219	More instr call statistics gathering and analysis stuff.
20051220	Another fix for MIPS 'mul'. Also converting mul and {d,}cl{o,z}
		to dyntrans.
		memory_ppc.c syntax error fix (noticed by Peter Valchev).
		Beginning to move out machines from src/machine.c into
		individual files in src/machines (in a way similar to the
		autodev system for devices).
20051222	Updating the documentation regarding NetBSD/pmax 3.0.
20051223	- " - NetBSD/cats 3.0.
20051225	- " - NetBSD/hpcmips 3.0.
20051226	Continuing on the machine registry redesign.
		Adding support for ARM rrx (33-bit rotate).
		Fixing some signed/unsigned issues (exposed by gcc -W).
20051227	Fixing the bug which prevented a NetBSD/prep 3.0 install kernel
		from starting (triggered when an mtmsr was the last instruction
		on a page). Unfortunately not enough to get the kernel to run
		as well as the 2.1 kernels did.
20051230	Some dyntrans refactoring.
20051231	Continuing on the machine registry redesign.
20060101-10	Continuing... moving more machines. Moving MD interrupt stuff
		from machine.c into a new src/machines/interrupts.c.
20060114	Adding various mvmeppc machine skeletons.
20060115	Continuing on mvme* stuff. NetBSD/mvmeppc prints boot messages
		(for MVME1600) and reaches the root device prompt, but no
		specific hardware devices are emulated yet.
20060116	Minor updates to the mvme1600 emulation mode; the Eagle PCI bus
		seems to work without much modification, and a 21143 can be
		detected, interrupts might work (but untested so far).
		Adding a fake MK48Txx (mkclock) device, for NetBSD/mvmeppc.
20060121	Adding an aux control register for ARM. (A BIG thank you to
		Olivier Houchard for tracking down this bug.)
20060122	Adding more ARM instructions (smulXY), and dev_iq80321_7seg.
20060124	Adding disassembly of more ARM instructions (mia*, mra/mar),
		and some semi-bogus XScale and i80321 registers.
20060201-02	Various minor updates. Moving the last machines out of
		machine.c.
20060204	Adding a -c command line option, for running debugger commands
		before the simulation starts, but after all files have been
		loaded.
		Minor iq80321-related updates.
20060209	Minor hacks (DEVINIT macro, etc).
		Preparing for the generalization of the 64-bit dyntrans address
		translation subsystem.
20060216	Adding ARM ldrd (double-register load).
20060217	Continuing on various ARM-related stuff.
20060218	More progress on the ATA/wdc emulation for NetBSD/iq80321.
		NetBSD/evbarm can now be installed :-)  Updating the docs, etc.
		Continuing on Algor emulation.

==============  RELEASE 0.3.8  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26