/[gxemul]/upstream/0.3.5/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

Annotation of /upstream/0.3.5/src/cpu_mips.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26