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