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

Contents of /trunk/src/cpu_mips.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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


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

  ViewVC Help
Powered by ViewVC 1.1.26