/[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

Contents of /trunk/src/cpus/cpu_mips.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (show annotations)
Mon Oct 8 16:19:37 2007 UTC (16 years, 6 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 /*
2 * Copyright (C) 2003-2006 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 * $Id: cpu_mips.c,v 1.17 2006/02/17 20:27:21 debug Exp $
29 *
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 #ifdef EXPERIMENTAL_NEWMIPS
102 #define DYNTRANS_DUALMODE_32
103 #define DYNTRANS_DELAYSLOT
104 #include "tmp_mips_head.c"
105 #endif
106
107
108 /*
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 cpu->update_translation_table = mips_OLD_update_translation_table;
168 cpu->invalidate_translation_caches =
169 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 /* Testing: */
346 cpu->cd.mips.host_OLD_load = zeroed_alloc(1048576 *
347 sizeof(unsigned char *));
348 cpu->cd.mips.host_OLD_store = zeroed_alloc(1048576 *
349 sizeof(unsigned char *));
350 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
353 return 1;
354 }
355
356
357 /*
358 * 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 * 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 int i, s1, s2, iadd = DEBUG_INDENTATION;
460
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 /* Raw output: */
524 if (rawflag) {
525 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 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 printf(")\n");
548
549 for (j=0; j<m->cpus[i]->cd.mips.cpu_type.
550 nr_of_tlb_entries; j++) {
551 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 }
571 }
572 return;
573 }
574
575 /* Nicely formatted output: */
576 for (i=0; i<m->ncpus; i++) {
577 int pageshift = 12;
578
579 if (x >= 0 && i != x)
580 continue;
581
582 if (m->cpus[i]->cd.mips.cpu_type.rev == MIPS_R4100)
583 pageshift = 10;
584
585 /* Print index, random, and wired: */
586 printf("cpu%i: (", i);
587 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 printf(" wired=0x%llx", (long long)
603 m->cpus[i]->cd.mips.coproc[0]->
604 reg[COP0_WIRED]);
605 }
606
607 printf(")\n");
608
609 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 }
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 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 }
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 /* Apparently used both on R5900 and MIPS32: */
1295 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 #ifndef EXPERIMENTAL_NEWMIPS
1535
1536 #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 #endif
1545
1546
1547 /*
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 * If irq_nr is >= 8, then it is machine dependent, and md_interrupt() is
1581 * 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 #ifndef EXPERIMENTAL_NEWMIPS
1862 /*
1863 * mips_OLD_cpu_run_instr():
1864 *
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 int mips_OLD_cpu_run_instr(struct emul *emul, struct cpu *cpu)
1874 {
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 case MACHINE_PMAX:
2033 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 * TODO: The cache instruction is implementation dependent.
3963 */
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 /* 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 } 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 #endif /* !EXPERIMENTAL_NEWMIPS */
4134
4135
4136
4137 #ifdef EXPERIMENTAL_NEWMIPS
4138
4139 #include "tmp_mips_tail.c"
4140
4141 #else
4142
4143 #define CPU_RUN mips_OLD_cpu_run
4144 #define CPU_RUN_MIPS
4145 #define CPU_RINSTR mips_OLD_cpu_run_instr
4146 #include "cpu_run.c"
4147 #undef CPU_RINSTR
4148 #undef CPU_RUN_MIPS
4149 #undef CPU_RUN
4150 CPU_OLD_FAMILY_INIT(mips,"MIPS")
4151
4152 #endif
4153
4154
4155 #endif /* ENABLE_MIPS */

  ViewVC Help
Powered by ViewVC 1.1.26