/[gxemul]/trunk/src/cpus/cpu_sh.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 /trunk/src/cpus/cpu_sh.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 38 - (hide annotations)
Mon Oct 8 16:21:53 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 37551 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1515 2007/04/14 05:39:46 debug Exp $
20070324	Adding a "--debug" option to the configure script, to disable
		optimizations in unstable development builds.
		Moving out SCSI-specific stuff from diskimage.c into a new
		diskimage_scsicmd.c.
		Applying Hĺvard Eidnes' patch for SCSICDROM_READ_DISKINFO and
		SCSICDROM_READ_TRACKINFO. (Not really tested yet.)
		Implementing disk image "overlays" (to allow simple roll-back
		to previous disk state). Adding a 'V' disk flag for this, and
		updating the man page and misc.html.
20070325	Stability fix to cpu_dyntrans.c, when multiple physical pages
		share the same initial table entry. (The ppp == NULL check
		should be physpage_ofs == 0.) Bug found by analysing GXemul
		against a version patched for Godson.
		Fixing a second occurance of the same problem (also in
		cpu_dyntrans.c).
		Fixing a MAJOR physical page leak in cpu_dyntrans.c; pages
		weren't _added_ to the set of translated pages, they _replaced_
		all previous pages. It's amazing that this bug has been able
		to live for this long. (Triggered when emulating >128MB RAM.)
20070326	Removing the GDB debugging stub support; it was too hackish
		and ugly.
20070328	Moving around some native code generation skeleton code.
20070329	The -lm check in the configure script now also checks for sin()
		in addition to sqrt(). (Thanks to Nigel Horne for noticing that
		sqrt was not enough on Fedora Core 6.) (Not verified yet.)
20070330	Fixing an indexing bug in dev_sh4.c, found by using gcc version
		4.3.0 20070323.
20070331	Some more experimentation with native code generation.
20070404	Attempting to fix some more SH4 SCIF interrupt bugs; rewriting
		the SH interrupt assertion/deassertion code somewhat.
20070410	Splitting src/file.c into separate files in src/file/.
		Cleanup: Removing the dummy TS7200, Walnut, PB1000, and
		Meshcube emulation modes, and dev_epcom and dev_au1x00.
		Removing the experimental CHIP8/RCA180x code; it wasn't really
		working much lately, anyway. It was fun while it lasted.
		Also removing the experimental Transputer CPU support.
20070412	Moving the section about how the dynamic translation system
		works from intro.html to a separate translation.html file.
		Minor SH fixes; attempting to get OpenBSD/landisk to run
		without randomly bugging out, but no success yet.
20070413	SH SCI (serial bit interface) should now work together with a
		(new) RS5C313 clock device (for Landisk emulation).
20070414	Moving Redhat/MIPS down from supported to experimental, in
		guestoses.html.
		Preparing for a new release; doing some regression testing etc.

==============  RELEASE 0.4.5  ==============


1 dpavlin 14 /*
2 dpavlin 34 * Copyright (C) 2005-2007 Anders Gavare. All rights reserved.
3 dpavlin 14 *
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 38 * $Id: cpu_sh.c,v 1.66 2007/04/13 07:06:31 debug Exp $
29 dpavlin 14 *
30     * Hitachi SuperH ("SH") CPU emulation.
31     *
32 dpavlin 32 * TODO: It would be nice if this could encompass both 64-bit SH5, and
33     * 32-bit SH encodings. Right now, it only really supports 32-bit mode.
34 dpavlin 14 */
35    
36     #include <stdio.h>
37     #include <stdlib.h>
38     #include <string.h>
39     #include <ctype.h>
40 dpavlin 32 #include <unistd.h>
41 dpavlin 14
42     #include "cpu.h"
43 dpavlin 32 #include "device.h"
44     #include "float_emul.h"
45 dpavlin 34 #include "interrupt.h"
46 dpavlin 14 #include "machine.h"
47     #include "memory.h"
48     #include "misc.h"
49 dpavlin 32 #include "settings.h"
50 dpavlin 14 #include "symbol.h"
51    
52 dpavlin 32 #include "sh4_exception.h"
53     #include "sh4_mmu.h"
54 dpavlin 14
55 dpavlin 32
56     #define DYNTRANS_32
57     #define DYNTRANS_DELAYSLOT
58 dpavlin 14 #include "tmp_sh_head.c"
59    
60    
61 dpavlin 32 extern int quiet_mode;
62    
63     void sh_pc_to_pointers(struct cpu *);
64    
65    
66 dpavlin 14 /*
67     * sh_cpu_new():
68     *
69     * Create a new SH cpu object.
70     *
71     * Returns 1 on success, 0 if there was no matching SH processor with
72     * this cpu_type_name.
73     */
74     int sh_cpu_new(struct cpu *cpu, struct memory *mem, struct machine *machine,
75     int cpu_id, char *cpu_type_name)
76     {
77 dpavlin 30 int i = 0;
78     struct sh_cpu_type_def cpu_type_defs[] = SH_CPU_TYPE_DEFS;
79    
80     /* Scan the cpu_type_defs list for this cpu type: */
81     while (cpu_type_defs[i].name != NULL) {
82     if (strcasecmp(cpu_type_defs[i].name, cpu_type_name) == 0) {
83     break;
84     }
85     i++;
86     }
87     if (cpu_type_defs[i].name == NULL)
88 dpavlin 14 return 0;
89    
90     cpu->memory_rw = sh_memory_rw;
91    
92 dpavlin 30 cpu->cd.sh.cpu_type = cpu_type_defs[i];
93 dpavlin 14 cpu->byte_order = EMUL_LITTLE_ENDIAN;
94 dpavlin 30 cpu->is_32bit = cpu->cd.sh.cpu_type.bits == 32;
95     cpu->cd.sh.compact = 1; /* Default to 16-bit opcode mode */
96 dpavlin 14
97 dpavlin 32 if (!cpu->is_32bit) {
98     fatal("SH64 emulation not implemented. Sorry.\n");
99     exit(1);
100     }
101    
102     cpu->instruction_has_delayslot = sh_cpu_instruction_has_delayslot;
103    
104 dpavlin 30 cpu->translate_v2p = sh_translate_v2p;
105    
106 dpavlin 32 cpu->run_instr = sh_run_instr;
107     cpu->update_translation_table = sh_update_translation_table;
108     cpu->invalidate_translation_caches =
109     sh_invalidate_translation_caches;
110     cpu->invalidate_code_translation =
111     sh_invalidate_code_translation;
112 dpavlin 14
113     /* Only show name and caches etc for CPU nr 0 (in SMP machines): */
114     if (cpu_id == 0) {
115     debug("%s", cpu->name);
116     }
117    
118 dpavlin 30 /* Initial value of FPSCR (according to the SH4 manual): */
119     cpu->cd.sh.fpscr = 0x00040001;
120    
121 dpavlin 32 /* (Initial value of the program counter on reboot is 0xA0000000.) */
122    
123 dpavlin 30 /* Start in Privileged Mode: */
124 dpavlin 32 cpu->cd.sh.sr = SH_SR_MD | SH_SR_IMASK;
125 dpavlin 30
126 dpavlin 32 /* Stack pointer at end of physical RAM: */
127     cpu->cd.sh.r[15] = cpu->machine->physical_ram_in_mb * 1048576 - 64;
128    
129     CPU_SETTINGS_ADD_REGISTER64("pc", cpu->pc);
130     CPU_SETTINGS_ADD_REGISTER32("sr", cpu->cd.sh.sr);
131     CPU_SETTINGS_ADD_REGISTER32("pr", cpu->cd.sh.pr);
132     CPU_SETTINGS_ADD_REGISTER32("vbr", cpu->cd.sh.vbr);
133     CPU_SETTINGS_ADD_REGISTER32("gbr", cpu->cd.sh.gbr);
134     CPU_SETTINGS_ADD_REGISTER32("macl", cpu->cd.sh.macl);
135     CPU_SETTINGS_ADD_REGISTER32("mach", cpu->cd.sh.mach);
136 dpavlin 34 CPU_SETTINGS_ADD_REGISTER32("expevt", cpu->cd.sh.expevt);
137     CPU_SETTINGS_ADD_REGISTER32("intevt", cpu->cd.sh.intevt);
138     CPU_SETTINGS_ADD_REGISTER32("tra", cpu->cd.sh.tra);
139 dpavlin 32 CPU_SETTINGS_ADD_REGISTER32("fpscr", cpu->cd.sh.fpscr);
140     CPU_SETTINGS_ADD_REGISTER32("fpul", cpu->cd.sh.fpul);
141     for (i=0; i<SH_N_GPRS; i++) {
142     char tmpstr[5];
143     snprintf(tmpstr, sizeof(tmpstr), "r%i", i);
144     CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.r[i]);
145     }
146     for (i=0; i<SH_N_GPRS_BANKED; i++) {
147     char tmpstr[15];
148     snprintf(tmpstr, sizeof(tmpstr), "r%i_bank", i);
149     CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.r_bank[i]);
150     }
151     for (i=0; i<SH_N_FPRS; i++) {
152     char tmpstr[6];
153     snprintf(tmpstr, sizeof(tmpstr), "fr%i", i);
154     CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.fr[i]);
155     snprintf(tmpstr, sizeof(tmpstr), "xf%i", i);
156     CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.xf[i]);
157     }
158     for (i=0; i<SH_N_ITLB_ENTRIES; i++) {
159     char tmpstr[15];
160     snprintf(tmpstr, sizeof(tmpstr), "itlb_hi_%i", i);
161     CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.itlb_hi[i]);
162     snprintf(tmpstr, sizeof(tmpstr), "itlb_lo_%i", i);
163     CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.itlb_lo[i]);
164     }
165     for (i=0; i<SH_N_UTLB_ENTRIES; i++) {
166     char tmpstr[15];
167     snprintf(tmpstr, sizeof(tmpstr), "utlb_hi_%i", i);
168     CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.utlb_hi[i]);
169     snprintf(tmpstr, sizeof(tmpstr), "utlb_lo_%i", i);
170     CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.sh.utlb_lo[i]);
171     }
172    
173 dpavlin 34 /* Register the CPU's interrupts: */
174     for (i=SH_INTEVT_NMI; i<0x1000; i+=0x20) {
175     struct interrupt template;
176     char name[100];
177     snprintf(name, sizeof(name), "%s.irq[0x%x]", cpu->path, i);
178     memset(&template, 0, sizeof(template));
179     template.line = i;
180     template.name = name;
181     template.extra = cpu;
182     template.interrupt_assert = sh_cpu_interrupt_assert;
183     template.interrupt_deassert = sh_cpu_interrupt_deassert;
184     interrupt_handler_register(&template);
185     }
186    
187 dpavlin 32 /* SH4-specific memory mapped registers, TLBs, caches, etc: */
188 dpavlin 38 if (cpu->cd.sh.cpu_type.arch == 4) {
189 dpavlin 32 device_add(machine, "sh4");
190    
191 dpavlin 38 /*
192     * Interrupt Controller initial values, according to the
193     * SH7760 manual:
194     */
195     cpu->cd.sh.intc_iprd = 0xda74;
196     cpu->cd.sh.intc_intmsk00 = 0xf3ff7fff;
197     cpu->cd.sh.intc_intmsk04 = 0x00ffffff;
198     /* All others are zero. */
199    
200     /* TODO: Initial priorities? */
201     cpu->cd.sh.intc_intpri00 = 0x33333333;
202     cpu->cd.sh.intc_intpri04 = 0x33333333;
203     cpu->cd.sh.intc_intpri08 = 0x33333333;
204     cpu->cd.sh.intc_intpri0c = 0x33333333;
205     }
206    
207     sh_update_interrupt_priorities(cpu);
208    
209 dpavlin 14 return 1;
210     }
211    
212    
213     /*
214 dpavlin 38 * sh_update_interrupt_priorities():
215     *
216     * SH interrupts are a bit complicated; there are several intc registers
217     * controlling priorities for various peripherals:
218     *
219     * Register: Bits 15..12 11..8 7..4 3..0
220     * --------- ----------- ----- ---- ----
221     * ipra TMU0 TMU1 TMU2 Reserved
222     * iprb WDT REF Reserved Reserved
223     * iprc GPIO DMAC Reserved H-UDI
224     * iprd IRL0 IRL1 IRL2 IRL3
225     *
226     * Register: 31..28 27..24 23..20 19..16 15..12 11..8 7..4 3..0
227     * --------- ------ ------ ------ ------ ------ ----- ---- ----
228     * intpri00 IRQ4 IRQ5 IRQ6 IRQ7 Rsrvd. Rsrvd. Rsrvd. Reserved
229     * intpri04 HCAN2,0 HCAN2,1 SSI(0) SSI(1) HAC(0) HAC(1) I2C(0) I2C(1)
230     * intpri08 USB LCDC DMABRG SCIF(0) SCIF(1) SCIF(2) SIM HSPI
231     * intpri0c Reserv. Reserv. MMCIF Reserv. MFI Rsrvd. ADC CMT
232 dpavlin 34 */
233 dpavlin 38 void sh_update_interrupt_priorities(struct cpu *cpu)
234 dpavlin 34 {
235 dpavlin 38 int i;
236 dpavlin 34
237     /*
238 dpavlin 38 * Set priorities of known interrupts, without affecting the
239     * SH_INT_ASSERTED bit:
240 dpavlin 34 */
241    
242 dpavlin 38 for (i=SH4_INTEVT_IRQ0; i<=SH4_INTEVT_IRQ14; i+=0x20) {
243     cpu->cd.sh.int_prio_and_pending[i/0x20] &= ~SH_INT_PRIO_MASK;
244     cpu->cd.sh.int_prio_and_pending[i/0x20] |= (15 - ((i -
245     SH4_INTEVT_IRQ0) / 0x20));
246     }
247 dpavlin 34
248 dpavlin 38 cpu->cd.sh.int_prio_and_pending[SH_INTEVT_TMU0_TUNI0 / 0x20] &=
249     ~SH_INT_PRIO_MASK;
250     cpu->cd.sh.int_prio_and_pending[SH_INTEVT_TMU0_TUNI0 / 0x20] |=
251     (cpu->cd.sh.intc_ipra >> 12) & 0xf;
252 dpavlin 34
253 dpavlin 38 cpu->cd.sh.int_prio_and_pending[SH_INTEVT_TMU1_TUNI1 / 0x20] &=
254     ~SH_INT_PRIO_MASK;
255     cpu->cd.sh.int_prio_and_pending[SH_INTEVT_TMU1_TUNI1 / 0x20] |=
256     (cpu->cd.sh.intc_ipra >> 8) & 0xf;
257 dpavlin 34
258 dpavlin 38 cpu->cd.sh.int_prio_and_pending[SH_INTEVT_TMU2_TUNI2 / 0x20] &=
259     ~SH_INT_PRIO_MASK;
260     cpu->cd.sh.int_prio_and_pending[SH_INTEVT_TMU2_TUNI2 / 0x20] |=
261     (cpu->cd.sh.intc_ipra >> 4) & 0xf;
262    
263     for (i=SH4_INTEVT_SCIF_ERI; i<=SH4_INTEVT_SCIF_TXI; i+=0x20) {
264     cpu->cd.sh.int_prio_and_pending[i/0x20] &= ~SH_INT_PRIO_MASK;
265     cpu->cd.sh.int_prio_and_pending[i/0x20] |=
266     ((cpu->cd.sh.intc_intpri08 >> 16) & 0xf);
267     }
268 dpavlin 34 }
269    
270    
271     /*
272 dpavlin 38 * sh_cpu_interrupt_assert():
273 dpavlin 34 */
274 dpavlin 38 void sh_cpu_interrupt_assert(struct interrupt *interrupt)
275 dpavlin 34 {
276     struct cpu *cpu = interrupt->extra;
277     int irq_nr = interrupt->line;
278 dpavlin 38 int index = irq_nr / 0x20;
279     int prio;
280 dpavlin 34
281 dpavlin 38 /* Assert the interrupt, and check its priority level: */
282     cpu->cd.sh.int_prio_and_pending[index] |= SH_INT_ASSERTED;
283     prio = cpu->cd.sh.int_prio_and_pending[index] & SH_INT_PRIO_MASK;
284 dpavlin 34
285 dpavlin 38 if (prio == 0) {
286     /* Interrupt not implemented? Hm. */
287     fatal("[ SH interrupt 0x%x, prio 0 (?), aborting ]\n", irq_nr);
288     exit(1);
289     }
290 dpavlin 34
291 dpavlin 38 if (cpu->cd.sh.int_to_assert == 0 || prio > cpu->cd.sh.int_level) {
292     cpu->cd.sh.int_to_assert = irq_nr;
293     cpu->cd.sh.int_level = prio;
294     }
295     }
296 dpavlin 34
297    
298 dpavlin 38 /*
299     * sh_cpu_interrupt_deassert():
300     */
301     void sh_cpu_interrupt_deassert(struct interrupt *interrupt)
302     {
303     struct cpu *cpu = interrupt->extra;
304     int irq_nr = interrupt->line;
305     int index = irq_nr / 0x20;
306 dpavlin 34
307 dpavlin 38 /* Deassert the interrupt: */
308     if (cpu->cd.sh.int_prio_and_pending[index] & SH_INT_ASSERTED) {
309     cpu->cd.sh.int_prio_and_pending[index] &= ~SH_INT_ASSERTED;
310 dpavlin 34
311 dpavlin 38 /* Calculate new interrupt assertion: */
312     cpu->cd.sh.int_to_assert = 0;
313     cpu->cd.sh.int_level = 0;
314    
315     /* NOTE/TODO: This is slow, but should hopefully work: */
316     for (index=0; index<0x1000/0x20; index++) {
317     uint8_t x = cpu->cd.sh.int_prio_and_pending[index];
318     uint8_t prio = x & SH_INT_PRIO_MASK;
319     if (x & SH_INT_ASSERTED &&
320     prio > cpu->cd.sh.int_level) {
321     cpu->cd.sh.int_to_assert = index * 0x20;
322     cpu->cd.sh.int_level = prio;
323 dpavlin 34 }
324     }
325     }
326     }
327    
328    
329     /*
330 dpavlin 14 * sh_cpu_list_available_types():
331     *
332     * Print a list of available SH CPU types.
333     */
334     void sh_cpu_list_available_types(void)
335     {
336 dpavlin 30 int i = 0, j;
337     struct sh_cpu_type_def tdefs[] = SH_CPU_TYPE_DEFS;
338    
339     while (tdefs[i].name != NULL) {
340     debug("%s", tdefs[i].name);
341     for (j=10 - strlen(tdefs[i].name); j>0; j--)
342     debug(" ");
343     i ++;
344     if ((i % 6) == 0 || tdefs[i].name == NULL)
345     debug("\n");
346     }
347 dpavlin 14 }
348    
349    
350     /*
351     * sh_cpu_dumpinfo():
352     */
353     void sh_cpu_dumpinfo(struct cpu *cpu)
354     {
355 dpavlin 32 debug(" (%s-endian)\n",
356     cpu->byte_order == EMUL_BIG_ENDIAN? "Big" : "Little");
357 dpavlin 14 }
358    
359    
360     /*
361 dpavlin 32 * sh_cpu_instruction_has_delayslot():
362     *
363     * Return 1 if an opcode is a branch, 0 otherwise.
364     */
365     int sh_cpu_instruction_has_delayslot(struct cpu *cpu, unsigned char *ib)
366     {
367     uint16_t iword = *((uint16_t *)&ib[0]);
368     int hi4, lo4, lo8;
369    
370     if (!cpu->is_32bit)
371     return 0;
372    
373     if (cpu->byte_order == EMUL_BIG_ENDIAN)
374     iword = BE16_TO_HOST(iword);
375     else
376     iword = LE16_TO_HOST(iword);
377    
378     hi4 = iword >> 12; lo4 = iword & 15; lo8 = iword & 255;
379    
380     switch (hi4) {
381     case 0x0:
382     if (iword == 0x000b) /* rts */
383     return 1;
384     if (iword == 0x002b) /* rte */
385     return 1;
386     if (lo8 == 0x03) /* bsrf */
387     return 1;
388     if (lo8 == 0x23) /* braf */
389     return 1;
390     break;
391     case 0x4:
392     switch (lo8) {
393     case 0x0b: /* jsr */
394     case 0x2b: /* jmp */
395     return 1;
396     }
397     break;
398     case 0x8:
399     switch ((iword >> 8) & 0xf) {
400     case 0xd: /* bt/s */
401     case 0xf: /* bf/s */
402     return 1;
403     }
404     break;
405     case 0xa: /* bra */
406     case 0xb: /* bsr */
407     return 1;
408     }
409    
410     return 0;
411     }
412    
413    
414     /*
415 dpavlin 14 * sh_cpu_register_dump():
416     *
417     * Dump cpu registers in a relatively readable format.
418     *
419     * gprs: set to non-zero to dump GPRs and some special-purpose registers.
420     * coprocs: set bit 0..3 to dump registers in coproc 0..3.
421     */
422     void sh_cpu_register_dump(struct cpu *cpu, int gprs, int coprocs)
423     {
424     char *symbol;
425 dpavlin 22 uint64_t offset;
426 dpavlin 14 int i, x = cpu->cpu_id, nregs = cpu->cd.sh.compact? 16 : 64;
427    
428     if (gprs) {
429     /* Special registers (pc, ...) first: */
430     symbol = get_symbol_name(&cpu->machine->symbol_context,
431     cpu->pc, &offset);
432    
433 dpavlin 32 debug("cpu%i: pc = 0x%08"PRIx32, x, (uint32_t)cpu->pc);
434 dpavlin 14 debug(" <%s>\n", symbol != NULL? symbol : " no symbol ");
435    
436 dpavlin 32 debug("cpu%i: sr = 0x%08"PRIx32" (%s, %s, %s, %s, %s, %s,"
437     " imask=0x%x, %s, %s)\n", x, (int32_t)cpu->cd.sh.sr,
438 dpavlin 30 (cpu->cd.sh.sr & SH_SR_MD)? "MD" : "!md",
439     (cpu->cd.sh.sr & SH_SR_RB)? "RB" : "!rb",
440     (cpu->cd.sh.sr & SH_SR_BL)? "BL" : "!bl",
441     (cpu->cd.sh.sr & SH_SR_FD)? "FD" : "!fd",
442     (cpu->cd.sh.sr & SH_SR_M)? "M" : "!m",
443     (cpu->cd.sh.sr & SH_SR_Q)? "Q" : "!q",
444     (cpu->cd.sh.sr & SH_SR_IMASK) >> SH_SR_IMASK_SHIFT,
445     (cpu->cd.sh.sr & SH_SR_S)? "S" : "!s",
446     (cpu->cd.sh.sr & SH_SR_T)? "T" : "!t");
447    
448 dpavlin 32 symbol = get_symbol_name(&cpu->machine->symbol_context,
449     cpu->cd.sh.pr, &offset);
450     debug("cpu%i: pr = 0x%08"PRIx32, x, (uint32_t)cpu->cd.sh.pr);
451     debug(" <%s>\n", symbol != NULL? symbol : " no symbol ");
452    
453     debug("cpu%i: mach = 0x%08"PRIx32" macl = 0x%08"PRIx32
454     " gbr = 0x%08"PRIx32"\n", x, (uint32_t)cpu->cd.sh.mach,
455     (uint32_t)cpu->cd.sh.macl, (uint32_t)cpu->cd.sh.gbr);
456    
457     for (i=0; i<nregs; i++) {
458     if ((i % 4) == 0)
459     debug("cpu%i:", x);
460     debug(" r%-2i = 0x%08x ", i, (int)cpu->cd.sh.r[i]);
461     if ((i % 4) == 3)
462     debug("\n");
463 dpavlin 14 }
464     }
465    
466 dpavlin 32 if (coprocs & 1) {
467     /* Floating point: */
468     debug("cpu%i: fpscr = 0x%08"PRIx32" fpul = 0x%08"PRIx32
469     "\n", x, cpu->cd.sh.fpscr, cpu->cd.sh.fpul);
470 dpavlin 14
471 dpavlin 32 for (i=0; i<SH_N_FPRS; i++) {
472     if ((i % 4) == 0)
473     debug("cpu%i:", x);
474     debug(" fr%-2i=0x%08x ", i, (int)cpu->cd.sh.fr[i]);
475     if ((i % 4) == 3)
476     debug("\n");
477     }
478 dpavlin 14
479 dpavlin 32 for (i=0; i<SH_N_FPRS; i++) {
480     if ((i % 4) == 0)
481     debug("cpu%i:", x);
482     debug(" xf%-2i=0x%08x ", i, (int)cpu->cd.sh.xf[i]);
483     if ((i % 4) == 3)
484     debug("\n");
485     }
486     }
487 dpavlin 14
488 dpavlin 32 if (coprocs & 2) {
489     /* System registers, etc: */
490     debug("cpu%i: vbr = 0x%08"PRIx32" sgr = 0x%08"PRIx32
491     "\n", x, cpu->cd.sh.vbr, cpu->cd.sh.sgr);
492     debug("cpu%i: spc = 0x%08"PRIx32" ssr = 0x%08"PRIx32"\n",
493     x, cpu->cd.sh.spc, cpu->cd.sh.ssr);
494     debug("cpu%i: expevt = 0x%"PRIx32" intevt = 0x%"PRIx32
495     " tra = 0x%"PRIx32"\n", x, cpu->cd.sh.expevt,
496     cpu->cd.sh.intevt, cpu->cd.sh.tra);
497 dpavlin 14
498 dpavlin 32 for (i=0; i<SH_N_GPRS_BANKED; i++) {
499     if ((i % 2) == 0)
500     debug("cpu%i:", x);
501     debug(" r%i_bank = 0x%08x ", i,
502     (int)cpu->cd.sh.r_bank[i]);
503     if ((i % 2) == 1)
504     debug("\n");
505 dpavlin 30 }
506 dpavlin 14 }
507     }
508    
509    
510     /*
511 dpavlin 24 * sh_cpu_tlbdump():
512     *
513     * Called from the debugger to dump the TLB in a readable format.
514     * x is the cpu number to dump, or -1 to dump all CPUs.
515     *
516     * If rawflag is nonzero, then the TLB contents isn't formated nicely,
517     * just dumped.
518     */
519     void sh_cpu_tlbdump(struct machine *m, int x, int rawflag)
520     {
521 dpavlin 32 int i, j;
522    
523     for (j=0; j<m->ncpus; j++) {
524     struct cpu *cpu = m->cpus[j];
525    
526     if (x >= 0 && j != x)
527     continue;
528    
529     for (i=0; i<SH_N_ITLB_ENTRIES; i++)
530     printf("cpu%i: itlb_hi_%-2i = 0x%08"PRIx32" "
531     "itlb_lo_%-2i = 0x%08"PRIx32"\n", j, i,
532     (uint32_t) cpu->cd.sh.itlb_hi[i], i,
533     (uint32_t) cpu->cd.sh.itlb_lo[i]);
534     for (i=0; i<SH_N_UTLB_ENTRIES; i++)
535     printf("cpu%i: utlb_hi_%-2i = 0x%08"PRIx32" "
536     "utlb_lo_%-2i = 0x%08"PRIx32"\n", j, i,
537     (uint32_t) cpu->cd.sh.utlb_hi[i], i,
538     (uint32_t) cpu->cd.sh.utlb_lo[i]);
539     }
540 dpavlin 24 }
541    
542    
543     /*
544 dpavlin 30 * sh_update_sr():
545 dpavlin 32 *
546     * Writes a new value to the status register.
547 dpavlin 30 */
548     void sh_update_sr(struct cpu *cpu, uint32_t new_sr)
549     {
550     uint32_t old_sr = cpu->cd.sh.sr;
551    
552     if ((new_sr & SH_SR_RB) != (old_sr & SH_SR_RB)) {
553 dpavlin 32 int i;
554     for (i=0; i<SH_N_GPRS_BANKED; i++) {
555     uint32_t tmp = cpu->cd.sh.r[i];
556     cpu->cd.sh.r[i] = cpu->cd.sh.r_bank[i];
557     cpu->cd.sh.r_bank[i] = tmp;
558     }
559 dpavlin 30 }
560    
561     cpu->cd.sh.sr = new_sr;
562     }
563    
564    
565     /*
566 dpavlin 32 * sh_update_fpscr():
567     *
568     * Writes a new value to the floating-point status/control register.
569     */
570     void sh_update_fpscr(struct cpu *cpu, uint32_t new_fpscr)
571     {
572     uint32_t old_fpscr = cpu->cd.sh.fpscr;
573    
574     if ((new_fpscr & SH_FPSCR_FR) != (old_fpscr & SH_FPSCR_FR)) {
575     int i;
576     for (i=0; i<SH_N_FPRS; i++) {
577     uint32_t tmp = cpu->cd.sh.fr[i];
578     cpu->cd.sh.fr[i] = cpu->cd.sh.xf[i];
579     cpu->cd.sh.xf[i] = tmp;
580     }
581     }
582    
583     cpu->cd.sh.fpscr = new_fpscr;
584     }
585    
586    
587     /*
588     * sh_exception():
589     *
590     * Causes a transfer of control to an exception or interrupt handler.
591     * If intevt > 0, then it is an interrupt, otherwise an exception.
592 dpavlin 38 *
593     * vaddr contains the faulting address, on TLB exceptions.
594 dpavlin 32 */
595     void sh_exception(struct cpu *cpu, int expevt, int intevt, uint32_t vaddr)
596     {
597     uint32_t vbr = cpu->cd.sh.vbr;
598    
599     if (!quiet_mode) {
600     if (intevt > 0)
601     debug("[ interrupt 0x%03x", intevt);
602     else
603     debug("[ exception 0x%03x", expevt);
604    
605 dpavlin 38 debug(", pc=0x%08"PRIx32" ", (uint32_t)cpu->pc);
606 dpavlin 32 if (intevt == 0)
607     debug("vaddr=0x%08"PRIx32" ", vaddr);
608    
609     debug(" ]\n");
610     }
611    
612     if (cpu->cd.sh.sr & SH_SR_BL) {
613 dpavlin 38 fatal("[ sh_exception(): BL bit already set. ]\n");
614 dpavlin 32
615     /* This is actually OK in two cases: a User Break,
616     or on NMI interrupts if a special flag is set? */
617     /* TODO */
618    
619     expevt = EXPEVT_RESET_POWER;
620     }
621    
622     if (cpu->is_halted) {
623     /*
624     * If the exception occurred on a 'sleep' instruction, then let
625     * the instruction following the sleep instruction be the one
626     * where execution resumes when the interrupt service routine
627     * returns.
628     */
629     cpu->is_halted = 0;
630     cpu->pc += sizeof(uint16_t);
631     }
632    
633     if (cpu->delay_slot) {
634     cpu->delay_slot = EXCEPTION_IN_DELAY_SLOT;
635     cpu->pc -= sizeof(uint16_t);
636     }
637    
638 dpavlin 38
639     /*
640     * Stuff common to all exceptions:
641     */
642    
643 dpavlin 32 cpu->cd.sh.spc = cpu->pc;
644     cpu->cd.sh.ssr = cpu->cd.sh.sr;
645     cpu->cd.sh.sgr = cpu->cd.sh.r[15];
646 dpavlin 38
647 dpavlin 32 if (intevt > 0) {
648     cpu->cd.sh.intevt = intevt;
649     expevt = -1;
650 dpavlin 38 } else {
651 dpavlin 32 cpu->cd.sh.expevt = expevt;
652 dpavlin 38 }
653    
654 dpavlin 32 sh_update_sr(cpu, cpu->cd.sh.sr | SH_SR_MD | SH_SR_RB | SH_SR_BL);
655    
656     /* Most exceptions set PC to VBR + 0x100. */
657     cpu->pc = vbr + 0x100;
658    
659 dpavlin 38
660 dpavlin 32 /* Specific cases: */
661     switch (expevt) {
662    
663     case -1: /* Interrupt */
664     cpu->pc = vbr + 0x600;
665     break;
666    
667     case EXPEVT_RESET_POWER:
668     case EXPEVT_RESET_MANUAL:
669     cpu->pc = 0xa0000000;
670     cpu->cd.sh.vbr = 0x00000000;
671     sh_update_sr(cpu, (cpu->cd.sh.sr | SH_SR_IMASK) & ~SH_SR_FD);
672     break;
673    
674     case EXPEVT_TLB_MISS_LD:
675     case EXPEVT_TLB_MISS_ST:
676     cpu->pc = vbr + 0x400;
677     case EXPEVT_TLB_PROT_LD:
678     case EXPEVT_TLB_PROT_ST:
679     case EXPEVT_TLB_MOD:
680     cpu->cd.sh.tea = vaddr;
681     cpu->cd.sh.pteh &= ~SH4_PTEH_VPN_MASK;
682     cpu->cd.sh.pteh |= (vaddr & SH4_PTEH_VPN_MASK);
683     break;
684    
685     case EXPEVT_TRAPA:
686 dpavlin 38 /*
687     * Note: The TRA register is already set by the implementation
688     * of the trapa instruction. See cpu_sh_instr.c for details.
689     * Here, spc is incremented, so that a return from the trap
690     * handler transfers control to the instruction _following_
691     * the trapa.
692     */
693 dpavlin 32 cpu->cd.sh.spc += sizeof(uint16_t);
694     break;
695    
696 dpavlin 34 case EXPEVT_RES_INST:
697 dpavlin 36 /*
698     * Note: Having this code here makes it possible to catch
699     * reserved instructions; during normal instruction execution,
700     * these are not very common.
701     */
702     #if 1
703     printf("\nRESERVED SuperH instruction at spc=%08"PRIx32"\n",
704     cpu->cd.sh.spc);
705     exit(1);
706     #else
707 dpavlin 34 break;
708     #endif
709    
710     case EXPEVT_FPU_DISABLE:
711     break;
712    
713 dpavlin 32 default:fatal("sh_exception(): exception 0x%x is not yet "
714     "implemented.\n", expevt);
715     exit(1);
716     }
717    
718     sh_pc_to_pointers(cpu);
719     }
720    
721    
722     /*
723 dpavlin 14 * sh_cpu_disassemble_instr_compact():
724     *
725     * SHcompact instruction disassembly. The top 4 bits of each 16-bit
726     * instruction word is used as the main opcode. For most instructions, the
727     * lowest 4 or 8 bits then select sub-opcode.
728     */
729     int sh_cpu_disassemble_instr_compact(struct cpu *cpu, unsigned char *instr,
730 dpavlin 24 int running, uint64_t dumpaddr)
731 dpavlin 14 {
732 dpavlin 22 uint64_t addr;
733 dpavlin 14 uint16_t iword;
734     int hi4, lo4, lo8, r8, r4;
735    
736     if (cpu->byte_order == EMUL_BIG_ENDIAN)
737     iword = (instr[0] << 8) + instr[1];
738     else
739     iword = (instr[1] << 8) + instr[0];
740    
741 dpavlin 32 debug(": %04x %s\t", iword, cpu->delay_slot? "(d)" : "");
742 dpavlin 14 hi4 = iword >> 12; lo4 = iword & 15; lo8 = iword & 255;
743     r8 = (iword >> 8) & 15; r4 = (iword >> 4) & 15;
744    
745     /*
746     * Decode the instruction:
747     */
748    
749     switch (hi4) {
750     case 0x0:
751     if (lo8 == 0x02)
752     debug("stc\tsr,r%i\n", r8);
753     else if (lo8 == 0x03)
754     debug("bsrf\tr%i\n", r8);
755 dpavlin 34 else if (lo4 >= 4 && lo4 <= 6) {
756     if (lo4 == 0x4)
757     debug("mov.b\tr%i,@(r0,r%i)", r4, r8);
758     else if (lo4 == 0x5)
759     debug("mov.w\tr%i,@(r0,r%i)", r4, r8);
760     else if (lo4 == 0x6)
761     debug("mov.l\tr%i,@(r0,r%i)", r4, r8);
762     if (running) {
763     debug("\t; r0+r%i = 0x%08"PRIx32, r8,
764     cpu->cd.sh.r[0] + cpu->cd.sh.r[r8]);
765     }
766     debug("\n");
767     } else if (lo4 == 0x7)
768 dpavlin 14 debug("mul.l\tr%i,r%i\n", r4, r8);
769     else if (iword == 0x0008)
770     debug("clrt\n");
771     else if (iword == 0x0009)
772     debug("nop\n");
773     else if (lo8 == 0x0a)
774     debug("sts\tmach,r%i\n", r8);
775     else if (iword == 0x000b)
776     debug("rts\n");
777 dpavlin 34 else if (lo4 >= 0xc && lo4 <= 0xe) {
778     if (lo4 == 0xc)
779     debug("mov.b\t@(r0,r%i),r%i", r4, r8);
780     else if (lo4 == 0xd)
781     debug("mov.w\t@(r0,r%i),r%i", r4, r8);
782     else if (lo4 == 0xe)
783     debug("mov.l\t@(r0,r%i),r%i", r4, r8);
784     if (running) {
785     debug("\t; r0+r%i = 0x%08"PRIx32, r4,
786     cpu->cd.sh.r[0] + cpu->cd.sh.r[r4]);
787     }
788     debug("\n");
789     } else if (lo8 == 0x12)
790 dpavlin 14 debug("stc\tgbr,r%i\n", r8);
791     else if (iword == 0x0018)
792     debug("sett\n");
793     else if (iword == 0x0019)
794     debug("div0u\n");
795     else if (lo8 == 0x1a)
796     debug("sts\tmacl,r%i\n", r8);
797 dpavlin 32 else if (iword == 0x001b)
798     debug("sleep\n");
799     else if (lo8 == 0x22)
800     debug("stc\tvbr,r%i\n", r8);
801 dpavlin 14 else if (lo8 == 0x23)
802     debug("braf\tr%i\n", r8);
803     else if (iword == 0x0028)
804     debug("clrmac\n");
805     else if (lo8 == 0x29)
806     debug("movt\tr%i\n", r8);
807 dpavlin 32 else if (lo8 == 0x2a)
808     debug("sts\tpr,r%i\n", r8);
809     else if (iword == 0x002b)
810     debug("rte\n");
811     else if (lo8 == 0x32)
812     debug("stc\tssr,r%i\n", r8);
813     else if (iword == 0x0038)
814     debug("ldtlb\n");
815 dpavlin 14 else if (iword == 0x003b)
816     debug("brk\n");
817 dpavlin 32 else if (lo8 == 0x42)
818     debug("stc\tspc,r%i\n", r8);
819 dpavlin 14 else if (iword == 0x0048)
820     debug("clrs\n");
821     else if (iword == 0x0058)
822     debug("sets\n");
823 dpavlin 32 else if (lo8 == 0x5a)
824     debug("sts\tfpul,r%i\n", r8);
825     else if (lo8 == 0x6a)
826     debug("sts\tfpscr,r%i\n", r8);
827     else if ((lo8 & 0x8f) == 0x82)
828     debug("stc\tr%i_bank,r%i\n", (lo8 >> 4) & 7, r8);
829 dpavlin 14 else if (lo8 == 0x83)
830     debug("pref\t@r%i\n", r8);
831 dpavlin 32 else if (lo8 == 0x93)
832     debug("ocbi\t@r%i\n", r8);
833     else if (lo8 == 0xa3)
834     debug("ocbp\t@r%i\n", r8);
835     else if (lo8 == 0xb3)
836     debug("ocbwb\t@r%i\n", r8);
837     else if (lo8 == 0xc3)
838     debug("movca.l\tr0,@r%i\n", r8);
839     else if (lo8 == 0xfa)
840     debug("stc\tdbr,r%i\n", r8);
841 dpavlin 34 else if (iword == SH_INVALID_INSTR)
842 dpavlin 32 debug("gxemul_dreamcast_prom_emul\n");
843 dpavlin 14 else
844     debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
845     break;
846     case 0x1:
847 dpavlin 34 debug("mov.l\tr%i,@(%i,r%i)", r4, lo4 * 4, r8);
848     if (running) {
849     debug("\t; r%i+%i = 0x%08"PRIx32, r8, lo4 * 4,
850     cpu->cd.sh.r[r8] + lo4 * 4);
851     }
852     debug("\n");
853 dpavlin 14 break;
854     case 0x2:
855     if (lo4 == 0x0)
856     debug("mov.b\tr%i,@r%i\n", r4, r8);
857     else if (lo4 == 0x1)
858     debug("mov.w\tr%i,@r%i\n", r4, r8);
859     else if (lo4 == 0x2)
860     debug("mov.l\tr%i,@r%i\n", r4, r8);
861     else if (lo4 == 0x4)
862     debug("mov.b\tr%i,@-r%i\n", r4, r8);
863     else if (lo4 == 0x5)
864     debug("mov.w\tr%i,@-r%i\n", r4, r8);
865     else if (lo4 == 0x6)
866     debug("mov.l\tr%i,@-r%i\n", r4, r8);
867     else if (lo4 == 0x7)
868     debug("div0s\tr%i,r%i\n", r4, r8);
869     else if (lo4 == 0x8)
870     debug("tst\tr%i,r%i\n", r4, r8);
871     else if (lo4 == 0x9)
872     debug("and\tr%i,r%i\n", r4, r8);
873     else if (lo4 == 0xa)
874     debug("xor\tr%i,r%i\n", r4, r8);
875     else if (lo4 == 0xb)
876     debug("or\tr%i,r%i\n", r4, r8);
877     else if (lo4 == 0xc)
878     debug("cmp/str\tr%i,r%i\n", r4, r8);
879     else if (lo4 == 0xd)
880     debug("xtrct\tr%i,r%i\n", r4, r8);
881     else if (lo4 == 0xe)
882     debug("mulu.w\tr%i,r%i\n", r4, r8);
883     else if (lo4 == 0xf)
884     debug("muls.w\tr%i,r%i\n", r4, r8);
885     else
886     debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
887     break;
888     case 0x3:
889     if (lo4 == 0x0)
890     debug("cmp/eq\tr%i,r%i\n", r4, r8);
891     else if (lo4 == 0x2)
892     debug("cmp/hs\tr%i,r%i\n", r4, r8);
893     else if (lo4 == 0x3)
894     debug("cmp/ge\tr%i,r%i\n", r4, r8);
895     else if (lo4 == 0x4)
896     debug("div1\tr%i,r%i\n", r4, r8);
897     else if (lo4 == 0x5)
898     debug("dmulu.l\tr%i,r%i\n", r4, r8);
899     else if (lo4 == 0x6)
900     debug("cmp/hi\tr%i,r%i\n", r4, r8);
901     else if (lo4 == 0x7)
902     debug("cmp/gt\tr%i,r%i\n", r4, r8);
903     else if (lo4 == 0x8)
904     debug("sub\tr%i,r%i\n", r4, r8);
905     else if (lo4 == 0xa)
906     debug("subc\tr%i,r%i\n", r4, r8);
907     else if (lo4 == 0xb)
908     debug("subv\tr%i,r%i\n", r4, r8);
909     else if (lo4 == 0xc)
910     debug("add\tr%i,r%i\n", r4, r8);
911     else if (lo4 == 0xd)
912     debug("dmuls.l\tr%i,r%i\n", r4, r8);
913     else if (lo4 == 0xe)
914     debug("addc\tr%i,r%i\n", r4, r8);
915     else if (lo4 == 0xf)
916     debug("addv\tr%i,r%i\n", r4, r8);
917     else
918     debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
919     break;
920     case 0x4:
921     if (lo8 == 0x00)
922     debug("shll\tr%i\n", r8);
923     else if (lo8 == 0x01)
924     debug("shlr\tr%i\n", r8);
925 dpavlin 32 else if (lo8 == 0x02)
926     debug("sts.l\tmach,@-r%i\n", r8);
927     else if (lo8 == 0x03)
928     debug("stc.l\tsr,@-r%i\n", r8);
929 dpavlin 14 else if (lo8 == 0x04)
930     debug("rotl\tr%i\n", r8);
931     else if (lo8 == 0x05)
932     debug("rotr\tr%i\n", r8);
933     else if (lo8 == 0x06)
934     debug("lds.l\t@r%i+,mach\n", r8);
935 dpavlin 32 else if (lo8 == 0x07)
936     debug("ldc.l\t@r%i+,sr\n", r8);
937 dpavlin 14 else if (lo8 == 0x08)
938     debug("shll2\tr%i\n", r8);
939     else if (lo8 == 0x09)
940     debug("shlr2\tr%i\n", r8);
941     else if (lo8 == 0x0a)
942     debug("lds\tr%i,mach\n", r8);
943     else if (lo8 == 0x0b)
944     debug("jsr\t@r%i\n", r8);
945     else if (lo4 == 0xc)
946     debug("shad\tr%i,r%i\n", r4, r8);
947     else if (lo4 == 0xd)
948     debug("shld\tr%i,r%i\n", r4, r8);
949     else if (lo8 == 0x0e)
950     debug("ldc\tr%i,sr\n", r8);
951     else if (lo8 == 0x10)
952     debug("dt\tr%i\n", r8);
953     else if (lo8 == 0x11)
954     debug("cmp/pz\tr%i\n", r8);
955 dpavlin 32 else if (lo8 == 0x12)
956     debug("sts.l\tmacl,@-r%i\n", r8);
957     else if (lo8 == 0x13)
958     debug("stc.l\tgbr,@-r%i\n", r8);
959 dpavlin 14 else if (lo8 == 0x15)
960     debug("cmp/pl\tr%i\n", r8);
961     else if (lo8 == 0x16)
962     debug("lds.l\t@r%i+,macl\n", r8);
963 dpavlin 32 else if (lo8 == 0x17)
964     debug("ldc.l\t@r%i+,gbr\n", r8);
965 dpavlin 14 else if (lo8 == 0x18)
966     debug("shll8\tr%i\n", r8);
967     else if (lo8 == 0x19)
968     debug("shlr8\tr%i\n", r8);
969     else if (lo8 == 0x1a)
970     debug("lds\tr%i,macl\n", r8);
971     else if (lo8 == 0x1b)
972     debug("tas.b\t@r%i\n", r8);
973     else if (lo8 == 0x1e)
974     debug("ldc\tr%i,gbr\n", r8);
975     else if (lo8 == 0x20)
976     debug("shal\tr%i\n", r8);
977     else if (lo8 == 0x21)
978     debug("shar\tr%i\n", r8);
979     else if (lo8 == 0x22)
980     debug("sts.l\tpr,@-r%i\n", r8);
981 dpavlin 32 else if (lo8 == 0x23)
982     debug("stc.l\tvbr,@-r%i\n", r8);
983 dpavlin 14 else if (lo8 == 0x24)
984     debug("rotcl\tr%i\n", r8);
985     else if (lo8 == 0x25)
986     debug("rotcr\tr%i\n", r8);
987     else if (lo8 == 0x26)
988     debug("lds.l\t@r%i+,pr\n", r8);
989 dpavlin 32 else if (lo8 == 0x27)
990     debug("ldc.l\t@r%i+,vbr\n", r8);
991 dpavlin 14 else if (lo8 == 0x28)
992     debug("shll16\tr%i\n", r8);
993     else if (lo8 == 0x29)
994     debug("shlr16\tr%i\n", r8);
995     else if (lo8 == 0x2a)
996     debug("lds\tr%i,pr\n", r8);
997     else if (lo8 == 0x2b)
998     debug("jmp\t@r%i\n", r8);
999 dpavlin 32 else if (lo8 == 0x2e)
1000     debug("ldc\tr%i,vbr\n", r8);
1001     else if (lo8 == 0x33)
1002     debug("stc.l\tssr,@-r%i\n", r8);
1003     else if (lo8 == 0x37)
1004     debug("ldc.l\t@r%i+,ssr\n", r8);
1005     else if (lo8 == 0x3e)
1006     debug("ldc\tr%i,ssr\n", r8);
1007     else if (lo8 == 0x43)
1008     debug("stc.l\tspc,@-r%i\n", r8);
1009     else if (lo8 == 0x47)
1010     debug("ldc.l\t@r%i+,spc\n", r8);
1011     else if (lo8 == 0x4e)
1012     debug("ldc\tr%i,spc\n", r8);
1013     else if (lo8 == 0x52)
1014     debug("sts.l\tfpul,@-r%i\n", r8);
1015 dpavlin 14 else if (lo8 == 0x56)
1016     debug("lds.l\t@r%i+,fpul\n", r8);
1017     else if (lo8 == 0x5a)
1018     debug("lds\tr%i,fpul\n", r8);
1019 dpavlin 32 else if (lo8 == 0x62)
1020     debug("sts.l\tfpscr,@-r%i\n", r8);
1021     else if (lo8 == 0x66)
1022     debug("lds.l\t@r%i+,fpscr\n", r8);
1023 dpavlin 14 else if (lo8 == 0x6a)
1024     debug("lds\tr%i,fpscr\n", r8);
1025 dpavlin 32 else if ((lo8 & 0x8f) == 0x83)
1026     debug("stc.l\tr%i_bank,@-r%i\n", (lo8 >> 4) & 7, r8);
1027     else if ((lo8 & 0x8f) == 0x87)
1028     debug("ldc.l\t@r%i,r%i_bank\n", r8, (lo8 >> 4) & 7, r8);
1029     else if ((lo8 & 0x8f) == 0x8e)
1030     debug("ldc\tr%i,r%i_bank\n", r8, (lo8 >> 4) & 7);
1031     else if (lo8 == 0xfa)
1032     debug("ldc\tr%i,dbr\n", r8);
1033 dpavlin 14 else
1034     debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
1035     break;
1036     case 0x5:
1037 dpavlin 34 debug("mov.l\t@(%i,r%i),r%i", lo4 * 4, r4, r8);
1038     if (running) {
1039     debug("\t; r%i+%i = 0x%08"PRIx32, r4, lo4 * 4,
1040     cpu->cd.sh.r[r4] + lo4 * 4);
1041     }
1042     debug("\n");
1043 dpavlin 14 break;
1044     case 0x6:
1045     if (lo4 == 0x0)
1046     debug("mov.b\t@r%i,r%i\n", r4, r8);
1047     else if (lo4 == 0x1)
1048     debug("mov.w\t@r%i,r%i\n", r4, r8);
1049     else if (lo4 == 0x2)
1050     debug("mov.l\t@r%i,r%i\n", r4, r8);
1051     else if (lo4 == 0x3)
1052     debug("mov\tr%i,r%i\n", r4, r8);
1053     else if (lo4 == 0x4)
1054     debug("mov.b\t@r%i+,r%i\n", r4, r8);
1055 dpavlin 32 else if (lo4 == 0x5)
1056     debug("mov.w\t@r%i+,r%i\n", r4, r8);
1057 dpavlin 14 else if (lo4 == 0x6)
1058     debug("mov.l\t@r%i+,r%i\n", r4, r8);
1059     else if (lo4 == 0x7)
1060     debug("not\tr%i,r%i\n", r4, r8);
1061     else if (lo4 == 0x8)
1062     debug("swap.b\tr%i,r%i\n", r4, r8);
1063     else if (lo4 == 0x9)
1064     debug("swap.w\tr%i,r%i\n", r4, r8);
1065     else if (lo4 == 0xa)
1066     debug("negc\tr%i,r%i\n", r4, r8);
1067     else if (lo4 == 0xb)
1068     debug("neg\tr%i,r%i\n", r4, r8);
1069     else if (lo4 == 0xc)
1070     debug("extu.b\tr%i,r%i\n", r4, r8);
1071     else if (lo4 == 0xd)
1072     debug("extu.w\tr%i,r%i\n", r4, r8);
1073     else if (lo4 == 0xe)
1074     debug("exts.b\tr%i,r%i\n", r4, r8);
1075     else if (lo4 == 0xf)
1076     debug("exts.w\tr%i,r%i\n", r4, r8);
1077     else
1078     debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
1079     break;
1080     case 0x7:
1081     debug("add\t#%i,r%i\n", (int8_t)lo8, r8);
1082     break;
1083     case 0x8:
1084 dpavlin 34 if (r8 == 0 || r8 == 4) {
1085     if (r8 == 0x0)
1086     debug("mov.b\tr0,@(%i,r%i)", lo4, r4);
1087     else if (r8 == 0x4)
1088     debug("mov.b\t@(%i,r%i),r0", lo4, r4);
1089     if (running) {
1090     debug("\t; r%i+%i = 0x%08"PRIx32, r4, lo4,
1091     cpu->cd.sh.r[r4] + lo4);
1092     }
1093     debug("\n");
1094     } else if (r8 == 1 || r8 == 5) {
1095     if (r8 == 0x1)
1096     debug("mov.w\tr0,@(%i,r%i)", lo4 * 2, r4);
1097     else if (r8 == 0x5)
1098     debug("mov.w\t@(%i,r%i),r0", lo4 * 2, r4);
1099     if (running) {
1100     debug("\t; r%i+%i = 0x%08"PRIx32, r4, lo4 * 2,
1101     cpu->cd.sh.r[r4] + lo4 * 2);
1102     }
1103     debug("\n");
1104 dpavlin 32 } else if (r8 == 0x8) {
1105 dpavlin 14 debug("cmp/eq\t#%i,r0\n", (int8_t)lo8);
1106 dpavlin 32 } else if (r8 == 0x9 || r8 == 0xb || r8 == 0xd || r8 == 0xf) {
1107 dpavlin 14 addr = (int8_t)lo8;
1108     addr = dumpaddr + 4 + (addr << 1);
1109     debug("b%s%s\t0x%x\n",
1110     (r8 == 0x9 || r8 == 0xd)? "t" : "f",
1111     (r8 == 0x9 || r8 == 0xb)? "" : "/s", (int)addr);
1112     } else
1113     debug("UNIMPLEMENTED hi4=0x%x,0x%x\n", hi4, r8);
1114     break;
1115     case 0x9:
1116     case 0xd:
1117 dpavlin 30 addr = lo8 * (hi4==9? 2 : 4);
1118 dpavlin 14 addr += (dumpaddr & ~(hi4==9? 1 : 3)) + 4;
1119     debug("mov.%s\t0x%x,r%i\n", hi4==9? "w":"l", (int)addr, r8);
1120     break;
1121     case 0xa:
1122     case 0xb:
1123     addr = (int32_t)(int16_t)((iword & 0xfff) << 4);
1124     addr = ((int32_t)addr >> 3);
1125     addr += dumpaddr + 4;
1126     debug("%s\t0x%x\n", hi4==0xa? "bra":"bsr", (int)addr);
1127     break;
1128     case 0xc:
1129 dpavlin 32 if (r8 == 0x0)
1130     debug("mov.b\tr0,@(%i,gbr)\n", lo8);
1131     else if (r8 == 0x1)
1132     debug("mov.w\tr0,@(%i,gbr)\n", lo8 * 2);
1133     else if (r8 == 0x2)
1134     debug("mov.l\tr0,@(%i,gbr)\n", lo8 * 4);
1135     else if (r8 == 0x3)
1136 dpavlin 14 debug("trapa\t#%i\n", (uint8_t)lo8);
1137 dpavlin 32 else if (r8 == 0x4)
1138     debug("mov.b\t(%i,gbr),r0\n", lo8);
1139     else if (r8 == 0x5)
1140     debug("mov.w\t(%i,gbr),r0\n", lo8 * 2);
1141     else if (r8 == 0x6)
1142     debug("mov.l\t(%i,gbr),r0\n", lo8 * 4);
1143     else if (r8 == 0x7) {
1144     addr = lo8 * 4 + (dumpaddr & ~3) + 4;
1145     debug("mova\t0x%x,r0\n", (int)addr);
1146     } else if (r8 == 0x8)
1147 dpavlin 14 debug("tst\t#%i,r0\n", (uint8_t)lo8);
1148     else if (r8 == 0x9)
1149     debug("and\t#%i,r0\n", (uint8_t)lo8);
1150     else if (r8 == 0xa)
1151     debug("xor\t#%i,r0\n", (uint8_t)lo8);
1152     else if (r8 == 0xb)
1153     debug("or\t#%i,r0\n", (uint8_t)lo8);
1154     else if (r8 == 0xc)
1155     debug("tst.b\t#%i,@(r0,gbr)\n", (uint8_t)lo8);
1156     else if (r8 == 0xd)
1157     debug("and.b\t#%i,@(r0,gbr)\n", (uint8_t)lo8);
1158     else if (r8 == 0xe)
1159     debug("xor.b\t#%i,@(r0,gbr)\n", (uint8_t)lo8);
1160     else if (r8 == 0xf)
1161     debug("or.b\t#%i,@(r0,gbr)\n", (uint8_t)lo8);
1162     else
1163     debug("UNIMPLEMENTED hi4=0x%x,0x%x\n", hi4, r8);
1164     break;
1165     case 0xe:
1166     debug("mov\t#%i,r%i\n", (int8_t)lo8, r8);
1167     break;
1168 dpavlin 32 case 0xf:
1169     if (lo4 == 0x0)
1170     debug("fadd\t%sr%i,%sr%i\n",
1171     cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1172     cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1173     else if (lo4 == 0x1)
1174     debug("fsub\t%sr%i,%sr%i\n",
1175     cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1176     cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1177     else if (lo4 == 0x2)
1178     debug("fmul\t%sr%i,%sr%i\n",
1179     cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1180     cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1181     else if (lo4 == 0x3)
1182     debug("fdiv\t%sr%i,%sr%i\n",
1183     cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1184     cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1185     else if (lo4 == 0x4)
1186     debug("fcmp/eq\t%sr%i,%sr%i\n",
1187     cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1188     cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1189     else if (lo4 == 0x5)
1190     debug("fcmp/gt\t%sr%i,%sr%i\n",
1191     cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r4,
1192     cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1193     else if (lo4 == 0x6) {
1194     char *n = "fr";
1195     if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1196     n = (r8 & 1)? "xd" : "dr";
1197     r8 &= ~1;
1198     }
1199     debug("fmov\t@(r0,r%i),%s%i\n", r4, n, r8);
1200     } else if (lo4 == 0x7) {
1201     char *n = "fr";
1202     if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1203     n = (r4 & 1)? "xd" : "dr";
1204     r4 &= ~1;
1205     }
1206     debug("fmov\t%s%i,@(r0,r%i)\n", n, r4, r8);
1207     } else if (lo4 == 0x8) {
1208     char *n = "fr";
1209     if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1210     n = (r8 & 1)? "xd" : "dr";
1211     r8 &= ~1;
1212     }
1213     debug("fmov\t@r%i,%s%i\n", r4, n, r8);
1214     } else if (lo4 == 0x9) {
1215     char *n = "fr";
1216     if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1217     n = (r8 & 1)? "xd" : "dr";
1218     r8 &= ~1;
1219     }
1220     debug("fmov\t@r%i+,%s%i\n", r4, n, r8);
1221     } else if (lo4 == 0xa) {
1222     char *n = "fr";
1223     if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1224     n = (r4 & 1)? "xd" : "dr";
1225     r4 &= ~1;
1226     }
1227     debug("fmov\t%s%i,@r%i\n", n, r4, r8);
1228     } else if (lo4 == 0xb) {
1229     char *n = "fr";
1230     if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1231     n = (r4 & 1)? "xd" : "dr";
1232     r4 &= ~1;
1233     }
1234     debug("fmov\t%s%i,@-r%i\n", n, r4, r8);
1235     } else if (lo4 == 0xc) {
1236     char *n1 = "fr", *n2 = "fr";
1237     if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1238     n1 = (r4 & 1)? "xd" : "dr";
1239     n2 = (r8 & 1)? "xd" : "dr";
1240     r4 &= ~1; r8 &= ~1;
1241     }
1242     debug("fmov\t%s%i,%s%i\n", n1, r4, n2, r8);
1243     } else if (lo8 == 0x0d)
1244     debug("fsts\tfpul,fr%i\n", r8);
1245     else if (lo8 == 0x1d)
1246     debug("flds\tfr%i,fpul\n", r8);
1247     else if (lo8 == 0x2d)
1248     debug("float\tfpul,%sr%i\n",
1249     cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1250     else if (lo8 == 0x3d)
1251     debug("ftrc\t%sr%i,fpul\n",
1252     cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1253     else if (lo8 == 0x4d)
1254     debug("fneg\t%sr%i\n",
1255     cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1256     else if (lo8 == 0x5d)
1257     debug("fabs\t%sr%i\n",
1258     cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1259     else if (lo8 == 0x6d)
1260     debug("fsqrt\t%sr%i\n",
1261     cpu->cd.sh.fpscr & SH_FPSCR_PR? "d" : "f", r8);
1262     else if (lo8 == 0x8d)
1263     debug("fldi0\tfr%i\n", r8);
1264     else if (lo8 == 0x9d)
1265     debug("fldi1\tfr%i\n", r8);
1266     else if ((iword & 0x01ff) == 0x00fd)
1267     debug("fsca\tfpul,dr%i\n", r8);
1268     else if (iword == 0xf3fd)
1269     debug("fschg\n");
1270     else if (iword == 0xfbfd)
1271     debug("frchg\n");
1272     else if ((iword & 0xf3ff) == 0xf1fd)
1273     debug("ftrv\txmtrx,fv%i\n", r8 & 0xc);
1274     else if (lo4 == 0xe)
1275     debug("fmac\tfr0,fr%i,fr%i\n", r4, r8);
1276     else
1277     debug("UNIMPLEMENTED hi4=0x%x,0x%x\n", hi4, lo8);
1278     break;
1279 dpavlin 14 default:debug("UNIMPLEMENTED hi4=0x%x\n", hi4);
1280     }
1281    
1282     return sizeof(iword);
1283     }
1284    
1285    
1286     /*
1287     * sh_cpu_disassemble_instr():
1288     *
1289     * Convert an instruction word into human readable format, for instruction
1290     * tracing.
1291     *
1292     * If running is 1, cpu->pc should be the address of the instruction.
1293     *
1294     * If running is 0, things that depend on the runtime environment (eg.
1295     * register contents) will not be shown, and addr will be used instead of
1296     * cpu->pc for relative addresses.
1297     */
1298     int sh_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,
1299 dpavlin 24 int running, uint64_t dumpaddr)
1300 dpavlin 14 {
1301 dpavlin 22 uint64_t offset;
1302 dpavlin 14 uint32_t iword;
1303 dpavlin 22 char *symbol;
1304 dpavlin 14
1305     if (running)
1306     dumpaddr = cpu->pc;
1307    
1308     symbol = get_symbol_name(&cpu->machine->symbol_context,
1309     dumpaddr, &offset);
1310     if (symbol != NULL && offset==0)
1311     debug("<%s>\n", symbol);
1312    
1313     if (cpu->machine->ncpus > 1 && running)
1314     debug("cpu%i: ", cpu->cpu_id);
1315    
1316 dpavlin 30 if (cpu->cd.sh.cpu_type.bits == 32)
1317 dpavlin 14 debug("%08x", (int)dumpaddr);
1318     else
1319     debug("%016llx", (long long)dumpaddr);
1320    
1321     if (cpu->cd.sh.compact)
1322     return sh_cpu_disassemble_instr_compact(cpu, instr,
1323 dpavlin 24 running, dumpaddr);
1324 dpavlin 14
1325     if (cpu->byte_order == EMUL_BIG_ENDIAN)
1326     iword = (instr[0] << 24) + (instr[1] << 16) + (instr[2] << 8)
1327     + instr[3];
1328     else
1329     iword = (instr[3] << 24) + (instr[2] << 16) + (instr[1] << 8)
1330     + instr[0];
1331    
1332     debug(": %08x\t", iword);
1333    
1334     /*
1335     * Decode the instruction:
1336     */
1337    
1338     debug("TODO\n");
1339    
1340     return sizeof(iword);
1341     }
1342    
1343    
1344     #include "tmp_sh_tail.c"
1345    

  ViewVC Help
Powered by ViewVC 1.1.26