/[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 10 - (show annotations)
Mon Oct 8 16:18:27 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 119881 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.815 2005/06/27 23:04:35 debug Exp $
20050617	Experimenting some more with netbooting OpenBSD/sgi. Adding
		a hack which allows emulated ethernet networks to be
		distributed across multiple emulator processes.
20050618	Minor updates (documentation, dummy YAMON emulation, etc).
20050620	strcpy/strcat -> strlcpy/strlcat updates.
		Some more progress on evbmips (Malta).
20050621	Adding a section to doc/configfiles.html about ethernet
		emulation across multiple hosts.
		Beginning the work on the ARM translation engine (using the
		dynamic-but-not-binary translation method).
		Fixing a bintrans bug: 0x9fc00000 should always be treated as
		PROM area, just as 0xbfc00000 is.
		Minor progress on Malta emulation (the PCI-ISA bus).
20050622	NetBSD/evbmips can now be installed (using another emulated
		machine) and run (including userland and so on). :-)
		Spliting up the bintrans haddr_entry field into two (one for
		read, one for write). Probably not much of a speed increase,
		though.
		Updating some NetBSD 2.0 -> 2.0.2 in the documentation.
20050623	Minor updates (documentation, the TODO file, etc).
		gzipped kernels are now always automagically gunzipped when
		loaded.
20050624	Adding a dummy Playstation Portable (PSP) mode, just barely
		enough to run Hello World (in weird colors :-).
		Removing the -b command line option; old bintrans is enabled
		by default instead. It makes more sense.
		Trying to finally fix the non-working performance measurement
		thing (instr/second etc).
20050625	Continuing on the essential basics for ARM emulation. Two
		instructions seem to work, a branch and a simple "mov". (The
		mov arguments are not correct yet.) Performance is definitely
		reasonable.
		Various other minor updates.
		Adding the ARM "bl" instruction.
		Adding support for combining multiple ARM instructions into one
		function call. ("mov" + "mov" is the only one implemented so
		far, but it seems to work.)
		Cleaning up some IP32 interrupt things (crime/mace); disabling
		the PS/2 keyboard controller on IP32, so that NetBSD/sgimips
		boots into userland again.
20050626	Finally! NetBSD/sgimips netboots. Adding instructions to
		doc/guestoses.html on how to set up an nfs server etc.
		Various other minor fixes.
		Playstation Portable ".pbp" files can now be used directly.
		(The ELF part of the .pbp is extracted transparently.)
		Converting some sprintf -> snprintf.
		Adding some more instructions to the ARM disassembler.
20050627	More ARM updates. Adding some simple ldr(b), str(b),
		cmps, and conditional branch instructions, enough to run
		a simple Hello World program.
		All ARM instructions are now inlined/generated for all possible
		condition codes.
		Adding add and sub, and more load/store instructions.
		Removing dummy files: cpu_alpha.c, cpu_hppa.c, and cpu_sparc.c.
		Some minor documentation updates; preparing for a 0.3.4
		release. Updating some URLs.

==============  RELEASE 0.3.4  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26