/[gxemul]/upstream/0.3.4/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 /upstream/0.3.4/src/cpu_mips.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26