/[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 6 - (show annotations)
Mon Oct 8 16:18:11 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 119531 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.772 2005/06/04 12:02:16 debug Exp $
20050428	Disabling the "-fmove-all-movables" option in the configure
		script, because it causes the compile to fail on OpenBSD/sgi.
20050502	Minor updates.
20050503	Removing the WRT54G mode (it was bogus anyway), and adding a
		comment about Windows NT for MIPS in doc/experiments.html.
		Minor updates to the x86 instruction decoding.
20050504	Adding some more x86 instructions.
		Adding support for reading files from ISO9660 CDROMs (including
		gzipped files). It's an ugly hack, but it seems to work.
		Various other minor updates (dev_vga.c, pc_bios.c etc).
20050505	Some more x86-related updates.
		Beginning (what I hope will be) a major code cleanup phase.
		"bootris" (an x86 bootsector) runs :-)
20050506	Adding some more x86 instructions.
20050507	tmpnam => mkstemp.
		Working on a hack to allow VGA charcells to be shown even when
		not running with X11.
		Adding more x86 instructions.
20050508	x86 32-bit SIB addressing fix, and more instructions.
20050509	Adding more x86 instructions.
20050510	Minor documentation updates, and other updates (x86 stuff etc.)
20050511	More x86-related updates.
20050513	Various updates, mostly x86-related. (Trying to fix flag 
		calculation, factoring out the ugly shift/rotate code, and
		some other things.)
20050514	Adding support for loading some old i386 a.out executables.
		Finally beginning the cleanup of machine/PROM/bios dependant
		info.
		Some minor documentation updates.
		Trying to clean up ARCBIOS stuff a little.
20050515	Trying to make it possible to actually use more than one disk
		type per machine (floppy, ide, scsi).
		Trying to clean up the kbd vs PROM console stuff. (For PC and
		ARC emulation modes, mostly.)
		Beginning to add an 8259 interrupt controller, and connecting
		it to the x86 emulation.
20050516	The first x86 interrupts seem to work (keyboard stuff).
		Adding a 8253/8254 programmable interval timer skeleton.
		FreeDOS now reaches a command prompt and can be interacted
		with.
20050517	After some bugfixes, MS-DOS also (sometimes) reaches a
		command prompt now.
		Trying to fix the pckbc to work with MS-DOS' keyb.com, but no
		success yet.
20050518	Adding a simple 32-bit x86 MMU skeleton.
20050519	Some more work on the x86 stuff. (Beginning the work on paging,
		and various other fixes).
20050520	More updates. Working on dev_vga (4-bit graphics modes), adding
		40 columns support to the PC bios emulation.
		Trying to add support for resizing windows when switching
		between graphics modes.
20050521	Many more x86-related updates.
20050522	Correcting the initial stack pointer's sign-extension for
		ARCBIOS emulation (thanks to Alec Voropay for noticing the
		error).
		Continuing on the cleanup (ARCBIOS etc).
		dev_vga updates.
20050523	More x86 updates: trying to add some support for protected mode
		interrupts (via gate descriptors) and many other fixes.
		More ARCBIOS cleanup.
		Adding a device flag which indicates that reads cause no
		side-effects. (Useful for the "dump" command in the debugger,
		and other things.)
		Adding support for directly starting up x86 ELFs, skipping the
		bootloader stage. (Most ELFs, however, are not suitable for
		this.)
20050524	Adding simple 32-bit x86 TSS task switching, but no privilege
		level support yet.
		More work on dev_vga. A small "Copper bars" demo works. :-)
		Adding support for Trap Flag (single-step exceptions), at least
		in real mode, and various other x86-related fixes.
20050525	Adding a new disk image prefix (gH;S;) which can be used to
		override the default nr of heads and sectors per track.
20050527	Various bug fixes, more work on the x86 mode (stack change on
		interrupts between different priv.levels), and some minor
		documentation updates.
20050528	Various fixes (x86 stuff).
20050529	More x86 fixes. An OpenBSD/i386 bootfloppy reaches userland
		and can be interacted with (although there are problems with
		key repetition). NetBSD/i386 triggers a serious CISC-related
		problem: instruction fetches across page boundaries, where
		the later part isn't actually part of the instruction.
20050530	Various minor updates. (Documentation updates, etc.)
20050531	Adding some experimental code (experiments/new_test_*) which
		could be useful for dynamic (but not binary) translation in
		the future.
20050602	Adding a dummy ARM skeleton.
		Fixing the pckbc key repetition problem (by adding release
		scancodes for all keypresses).
20050603	Minor updates for the next release.
20050604	Release testing. Minor updates.

==============  RELEASE 0.3.3  ==============

20050604	There'll probably be a 0.3.3.1 release soon, with some very
		very tiny updates.


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

  ViewVC Help
Powered by ViewVC 1.1.26