/[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

Contents of /trunk/src/cpus/cpu_sh.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 30 - (show annotations)
Mon Oct 8 16:20:40 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 17883 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1325 2006/08/15 15:38:37 debug Exp $
20060723	More Transputer instructions (pfix, nfix, opr, mint, ldl, ldlp,
		eqc, rev, ajw, stl, stlf, sthf, sub, ldnl, ldnlp, ldpi, move,
		wcnt, add, bcnt).
		Adding more SPARC instructions (andcc, addcc, bl, rdpr).
		Progress on the igsfb framebuffer used by NetBSD/netwinder.
		Enabling 8-bit fills in dev_fb.
		NetBSD/netwinder 3.0.1 can now run from a disk image :-)
20060724	Cleanup/performance fix for 64-bit virtual translation table
		updates (by removing the "timestamp" stuff). A full NetBSD/pmax
		3.0.1 install for R4400 has dropped from 667 seconds to 584 :)
		Fixing the igsfb "almost vga" color (it is 24-bit, not 18-bit).
		Adding some MIPS instruction combinations (3*lw, and 3*addu).
		The 8048 keyboard now turns off interrupt enable between the
		KBR_ACK and the KBR_RSTDONE, to work better with Linux 2.6.
		Not causing PPC DEC interrupts if PPC_NO_DEC is set for a
		specific CPU; NetBSD/bebox gets slightly further than before.
		Adding some more SPARC instructions: branches, udiv.
20060725	Refreshing dev_pckbc.c a little.
		Cleanups for the SH emulation mode, and adding the first
		"compact" (16-bit) instructions: various simple movs, nop,
		shll, stc, or, ldc.
20060726	Adding dummy "pcn" (AMD PCnet NIC) PCI glue.
20060727	Various cleanups; removing stuff from cpu.h, such as
		running_translated (not really meaningful anymore), and
		page flags (breaking into the debugger clears all translations
		anyway).
		Minor MIPS instruction combination updates.
20060807	Expanding the 3*sw and 3*lw MIPS instruction combinations to
		work with 2* and 4* too, resulting in a minor performance gain.
		Implementing a usleep hack for the RM52xx/MIPS32/MIPS64 "wait"
		instruction (when emulating 1 cpu).
20060808	Experimenting with some more MIPS instruction combinations.
		Implementing support for showing a (hardcoded 12x22) text
		cursor in igsfb.
20060809	Simplifying the NetBSD/evbmips (Malta) install instructions
		somewhat (by using a NetBSD/pmax ramdisk install kernel).
20060812	Experimenting more with the MIPS 'wait' instruction.
		PCI configuration register writes can now be handled, which
		allow PCI IDE controllers to work with NetBSD/Malta 3.0.1 and
		NetBSD/cobalt 3.0.1. (Previously only NetBSD 2.1 worked.)
20060813	Updating dev_gt.c based on numbers from Alec Voropay, to enable
		Linux 2.6 to use PCI on Malta.
		Continuing on Algor interrupt stuff.
20060814	Adding support for routing ISA interrupts to two different
		interrupts, making it possible to run NetBSD/algor :-)
20060814-15	Testing for the release.

==============  RELEASE 0.4.2  ==============


1 /*
2 * Copyright (C) 2005-2006 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 * $Id: cpu_sh.c,v 1.21 2006/07/25 21:49:14 debug Exp $
29 *
30 * Hitachi SuperH ("SH") CPU emulation.
31 *
32 * TODO
33 */
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <ctype.h>
39
40 #include "cpu.h"
41 #include "machine.h"
42 #include "memory.h"
43 #include "misc.h"
44 #include "symbol.h"
45
46
47 #define DYNTRANS_DUALMODE_32
48 #include "tmp_sh_head.c"
49
50
51 /*
52 * sh_cpu_new():
53 *
54 * Create a new SH cpu object.
55 *
56 * Returns 1 on success, 0 if there was no matching SH processor with
57 * this cpu_type_name.
58 */
59 int sh_cpu_new(struct cpu *cpu, struct memory *mem, struct machine *machine,
60 int cpu_id, char *cpu_type_name)
61 {
62 int i = 0;
63 struct sh_cpu_type_def cpu_type_defs[] = SH_CPU_TYPE_DEFS;
64
65 /* Scan the cpu_type_defs list for this cpu type: */
66 while (cpu_type_defs[i].name != NULL) {
67 if (strcasecmp(cpu_type_defs[i].name, cpu_type_name) == 0) {
68 break;
69 }
70 i++;
71 }
72 if (cpu_type_defs[i].name == NULL)
73 return 0;
74
75 cpu->memory_rw = sh_memory_rw;
76
77 cpu->cd.sh.cpu_type = cpu_type_defs[i];
78 cpu->byte_order = EMUL_LITTLE_ENDIAN;
79 cpu->is_32bit = cpu->cd.sh.cpu_type.bits == 32;
80 cpu->cd.sh.compact = 1; /* Default to 16-bit opcode mode */
81
82 cpu->translate_v2p = sh_translate_v2p;
83
84 if (cpu->is_32bit) {
85 cpu->run_instr = sh32_run_instr;
86 cpu->update_translation_table = sh32_update_translation_table;
87 cpu->invalidate_translation_caches =
88 sh32_invalidate_translation_caches;
89 cpu->invalidate_code_translation =
90 sh32_invalidate_code_translation;
91 } else {
92 cpu->run_instr = sh_run_instr;
93 cpu->update_translation_table = sh_update_translation_table;
94 cpu->invalidate_translation_caches =
95 sh_invalidate_translation_caches;
96 cpu->invalidate_code_translation =
97 sh_invalidate_code_translation;
98 }
99
100 /* Only show name and caches etc for CPU nr 0 (in SMP machines): */
101 if (cpu_id == 0) {
102 debug("%s", cpu->name);
103 }
104
105 /* Initial value of FPSCR (according to the SH4 manual): */
106 cpu->cd.sh.fpscr = 0x00040001;
107
108 /* Start in Privileged Mode: */
109 cpu->cd.sh.sr = SH_SR_MD;
110
111 return 1;
112 }
113
114
115 /*
116 * sh_cpu_list_available_types():
117 *
118 * Print a list of available SH CPU types.
119 */
120 void sh_cpu_list_available_types(void)
121 {
122 int i = 0, j;
123 struct sh_cpu_type_def tdefs[] = SH_CPU_TYPE_DEFS;
124
125 while (tdefs[i].name != NULL) {
126 debug("%s", tdefs[i].name);
127 for (j=10 - strlen(tdefs[i].name); j>0; j--)
128 debug(" ");
129 i ++;
130 if ((i % 6) == 0 || tdefs[i].name == NULL)
131 debug("\n");
132 }
133 }
134
135
136 /*
137 * sh_cpu_dumpinfo():
138 */
139 void sh_cpu_dumpinfo(struct cpu *cpu)
140 {
141 debug("\n");
142 /* TODO */
143 }
144
145
146 /*
147 * sh_cpu_register_dump():
148 *
149 * Dump cpu registers in a relatively readable format.
150 *
151 * gprs: set to non-zero to dump GPRs and some special-purpose registers.
152 * coprocs: set bit 0..3 to dump registers in coproc 0..3.
153 */
154 void sh_cpu_register_dump(struct cpu *cpu, int gprs, int coprocs)
155 {
156 char *symbol;
157 uint64_t offset;
158 int i, x = cpu->cpu_id, nregs = cpu->cd.sh.compact? 16 : 64;
159 int bits32 = cpu->cd.sh.cpu_type.bits == 32;
160
161 if (gprs) {
162 /* Special registers (pc, ...) first: */
163 symbol = get_symbol_name(&cpu->machine->symbol_context,
164 cpu->pc, &offset);
165
166 debug("cpu%i: pc = 0x", x);
167 if (bits32)
168 debug("%08x", (int)cpu->pc);
169 else
170 debug("%016llx", (long long)cpu->pc);
171 debug(" <%s>\n", symbol != NULL? symbol : " no symbol ");
172
173 debug("cpu%i: sr = %s, %s, %s, %s, %s, %s, imask=0x%x, "
174 "%s, %s\n", x,
175 (cpu->cd.sh.sr & SH_SR_MD)? "MD" : "!md",
176 (cpu->cd.sh.sr & SH_SR_RB)? "RB" : "!rb",
177 (cpu->cd.sh.sr & SH_SR_BL)? "BL" : "!bl",
178 (cpu->cd.sh.sr & SH_SR_FD)? "FD" : "!fd",
179 (cpu->cd.sh.sr & SH_SR_M)? "M" : "!m",
180 (cpu->cd.sh.sr & SH_SR_Q)? "Q" : "!q",
181 (cpu->cd.sh.sr & SH_SR_IMASK) >> SH_SR_IMASK_SHIFT,
182 (cpu->cd.sh.sr & SH_SR_S)? "S" : "!s",
183 (cpu->cd.sh.sr & SH_SR_T)? "T" : "!t");
184
185 if (bits32) {
186 /* 32-bit: */
187 for (i=0; i<nregs; i++) {
188 if ((i % 4) == 0)
189 debug("cpu%i:", x);
190 debug(" r%02i = 0x%08x ", i,
191 (int)cpu->cd.sh.r[i]);
192 if ((i % 4) == 3)
193 debug("\n");
194 }
195 } else {
196 /* 64-bit: */
197 for (i=0; i<nregs; i++) {
198 int r = (i >> 1) + ((i & 1) << 4);
199 if ((i % 2) == 0)
200 debug("cpu%i:", x);
201 debug(" r%02i = 0x%016llx ", r,
202 (long long)cpu->cd.sh.r[r]);
203 if ((i % 2) == 1)
204 debug("\n");
205 }
206 }
207 }
208 }
209
210
211 /*
212 * sh_cpu_register_match():
213 */
214 void sh_cpu_register_match(struct machine *m, char *name,
215 int writeflag, uint64_t *valuep, int *match_register)
216 {
217 int cpunr = 0;
218
219 /* CPU number: */
220
221 /* TODO */
222
223 /* Register name: */
224 if (strcasecmp(name, "pc") == 0) {
225 if (writeflag) {
226 m->cpus[cpunr]->pc = *valuep;
227 } else
228 *valuep = m->cpus[cpunr]->pc;
229 *match_register = 1;
230 } else if (name[0] == 'r' && isdigit((int)name[1])) {
231 int nr = atoi(name + 1);
232 if (nr >= 0 && nr < SH_N_GPRS) {
233 if (writeflag)
234 m->cpus[cpunr]->cd.sh.r[nr] = *valuep;
235 else
236 *valuep = m->cpus[cpunr]->cd.sh.r[nr];
237 *match_register = 1;
238 }
239 }
240 }
241
242
243 /*
244 * sh_cpu_tlbdump():
245 *
246 * Called from the debugger to dump the TLB in a readable format.
247 * x is the cpu number to dump, or -1 to dump all CPUs.
248 *
249 * If rawflag is nonzero, then the TLB contents isn't formated nicely,
250 * just dumped.
251 */
252 void sh_cpu_tlbdump(struct machine *m, int x, int rawflag)
253 {
254 }
255
256
257 /*
258 * sh_cpu_gdb_stub():
259 *
260 * Execute a "remote GDB" command. Returns a newly allocated response string
261 * on success, NULL on failure.
262 */
263 char *sh_cpu_gdb_stub(struct cpu *cpu, char *cmd)
264 {
265 fatal("sh_cpu_gdb_stub(): TODO\n");
266 return NULL;
267 }
268
269
270 /*
271 * sh_cpu_interrupt():
272 */
273 int sh_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)
274 {
275 fatal("sh_cpu_interrupt(): TODO\n");
276 return 0;
277 }
278
279
280 /*
281 * sh_cpu_interrupt_ack():
282 */
283 int sh_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)
284 {
285 /* fatal("sh_cpu_interrupt_ack(): TODO\n"); */
286 return 0;
287 }
288
289
290 /*
291 * sh_update_sr():
292 */
293 void sh_update_sr(struct cpu *cpu, uint32_t new_sr)
294 {
295 uint32_t old_sr = cpu->cd.sh.sr;
296
297 if ((new_sr & SH_SR_RB) != (old_sr & SH_SR_RB)) {
298 fatal("sh_update_sr(): Register bank switching is not"
299 " implemented yet! TODO\n");
300 exit(1);
301 }
302
303 cpu->cd.sh.sr = new_sr;
304 }
305
306
307 /*
308 * sh_cpu_disassemble_instr_compact():
309 *
310 * SHcompact instruction disassembly. The top 4 bits of each 16-bit
311 * instruction word is used as the main opcode. For most instructions, the
312 * lowest 4 or 8 bits then select sub-opcode.
313 */
314 int sh_cpu_disassemble_instr_compact(struct cpu *cpu, unsigned char *instr,
315 int running, uint64_t dumpaddr)
316 {
317 uint64_t addr;
318 uint16_t iword;
319 int hi4, lo4, lo8, r8, r4;
320
321 if (cpu->byte_order == EMUL_BIG_ENDIAN)
322 iword = (instr[0] << 8) + instr[1];
323 else
324 iword = (instr[1] << 8) + instr[0];
325
326 debug(": %04x \t", iword);
327 hi4 = iword >> 12; lo4 = iword & 15; lo8 = iword & 255;
328 r8 = (iword >> 8) & 15; r4 = (iword >> 4) & 15;
329
330 /*
331 * Decode the instruction:
332 */
333
334 switch (hi4) {
335 case 0x0:
336 if (lo8 == 0x02)
337 debug("stc\tsr,r%i\n", r8);
338 else if (lo8 == 0x03)
339 debug("bsrf\tr%i\n", r8);
340 else if (lo4 == 0x4)
341 debug("mov.b\tr%i,@(r0,r%i)\n", r4, r8);
342 else if (lo4 == 0x5)
343 debug("mov.w\tr%i,@(r0,r%i)\n", r4, r8);
344 else if (lo4 == 0x6)
345 debug("mov.l\tr%i,@(r0,r%i)\n", r4, r8);
346 else if (lo4 == 0x7)
347 debug("mul.l\tr%i,r%i\n", r4, r8);
348 else if (iword == 0x0008)
349 debug("clrt\n");
350 else if (iword == 0x0009)
351 debug("nop\n");
352 else if (lo8 == 0x0a)
353 debug("sts\tmach,r%i\n", r8);
354 else if (iword == 0x000b)
355 debug("rts\n");
356 else if (lo4 == 0xc)
357 debug("mov.b\t@(r0,r%i),r%i\n", r4, r8);
358 else if (lo4 == 0xd)
359 debug("mov.w\t@(r0,r%i),r%i\n", r4, r8);
360 else if (lo4 == 0xe)
361 debug("mov.l\t@(r0,r%i),r%i\n", r4, r8);
362 else if (lo8 == 0x12)
363 debug("stc\tgbr,r%i\n", r8);
364 else if (iword == 0x0018)
365 debug("sett\n");
366 else if (iword == 0x0019)
367 debug("div0u\n");
368 else if (lo8 == 0x1a)
369 debug("sts\tmacl,r%i\n", r8);
370 else if (lo8 == 0x23)
371 debug("braf\tr%i\n", r8);
372 else if (iword == 0x0028)
373 debug("clrmac\n");
374 else if (lo8 == 0x29)
375 debug("movt\tr%i\n", r8);
376 else if (iword == 0x003b)
377 debug("brk\n");
378 else if (iword == 0x0048)
379 debug("clrs\n");
380 else if (iword == 0x0058)
381 debug("sets\n");
382 else if (lo8 == 0x83)
383 debug("pref\t@r%i\n", r8);
384 else
385 debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
386 break;
387 case 0x1:
388 debug("mov.l\tr%i,@(%i,r%i)\n", r4, lo4 * 4, r8);
389 break;
390 case 0x2:
391 if (lo4 == 0x0)
392 debug("mov.b\tr%i,@r%i\n", r4, r8);
393 else if (lo4 == 0x1)
394 debug("mov.w\tr%i,@r%i\n", r4, r8);
395 else if (lo4 == 0x2)
396 debug("mov.l\tr%i,@r%i\n", r4, r8);
397 else if (lo4 == 0x4)
398 debug("mov.b\tr%i,@-r%i\n", r4, r8);
399 else if (lo4 == 0x5)
400 debug("mov.w\tr%i,@-r%i\n", r4, r8);
401 else if (lo4 == 0x6)
402 debug("mov.l\tr%i,@-r%i\n", r4, r8);
403 else if (lo4 == 0x7)
404 debug("div0s\tr%i,r%i\n", r4, r8);
405 else if (lo4 == 0x8)
406 debug("tst\tr%i,r%i\n", r4, r8);
407 else if (lo4 == 0x9)
408 debug("and\tr%i,r%i\n", r4, r8);
409 else if (lo4 == 0xa)
410 debug("xor\tr%i,r%i\n", r4, r8);
411 else if (lo4 == 0xb)
412 debug("or\tr%i,r%i\n", r4, r8);
413 else if (lo4 == 0xc)
414 debug("cmp/str\tr%i,r%i\n", r4, r8);
415 else if (lo4 == 0xd)
416 debug("xtrct\tr%i,r%i\n", r4, r8);
417 else if (lo4 == 0xe)
418 debug("mulu.w\tr%i,r%i\n", r4, r8);
419 else if (lo4 == 0xf)
420 debug("muls.w\tr%i,r%i\n", r4, r8);
421 else
422 debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
423 break;
424 case 0x3:
425 if (lo4 == 0x0)
426 debug("cmp/eq\tr%i,r%i\n", r4, r8);
427 else if (lo4 == 0x2)
428 debug("cmp/hs\tr%i,r%i\n", r4, r8);
429 else if (lo4 == 0x3)
430 debug("cmp/ge\tr%i,r%i\n", r4, r8);
431 else if (lo4 == 0x4)
432 debug("div1\tr%i,r%i\n", r4, r8);
433 else if (lo4 == 0x5)
434 debug("dmulu.l\tr%i,r%i\n", r4, r8);
435 else if (lo4 == 0x6)
436 debug("cmp/hi\tr%i,r%i\n", r4, r8);
437 else if (lo4 == 0x7)
438 debug("cmp/gt\tr%i,r%i\n", r4, r8);
439 else if (lo4 == 0x8)
440 debug("sub\tr%i,r%i\n", r4, r8);
441 else if (lo4 == 0xa)
442 debug("subc\tr%i,r%i\n", r4, r8);
443 else if (lo4 == 0xb)
444 debug("subv\tr%i,r%i\n", r4, r8);
445 else if (lo4 == 0xc)
446 debug("add\tr%i,r%i\n", r4, r8);
447 else if (lo4 == 0xd)
448 debug("dmuls.l\tr%i,r%i\n", r4, r8);
449 else if (lo4 == 0xe)
450 debug("addc\tr%i,r%i\n", r4, r8);
451 else if (lo4 == 0xf)
452 debug("addv\tr%i,r%i\n", r4, r8);
453 else
454 debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
455 break;
456 case 0x4:
457 if (lo8 == 0x00)
458 debug("shll\tr%i\n", r8);
459 else if (lo8 == 0x01)
460 debug("shlr\tr%i\n", r8);
461 else if (lo8 == 0x04)
462 debug("rotl\tr%i\n", r8);
463 else if (lo8 == 0x05)
464 debug("rotr\tr%i\n", r8);
465 else if (lo8 == 0x06)
466 debug("lds.l\t@r%i+,mach\n", r8);
467 else if (lo8 == 0x08)
468 debug("shll2\tr%i\n", r8);
469 else if (lo8 == 0x09)
470 debug("shlr2\tr%i\n", r8);
471 else if (lo8 == 0x0a)
472 debug("lds\tr%i,mach\n", r8);
473 else if (lo8 == 0x0b)
474 debug("jsr\t@r%i\n", r8);
475 else if (lo4 == 0xc)
476 debug("shad\tr%i,r%i\n", r4, r8);
477 else if (lo4 == 0xd)
478 debug("shld\tr%i,r%i\n", r4, r8);
479 else if (lo8 == 0x0e)
480 debug("ldc\tr%i,sr\n", r8);
481 else if (lo8 == 0x10)
482 debug("dt\tr%i\n", r8);
483 else if (lo8 == 0x11)
484 debug("cmp/pz\tr%i\n", r8);
485 else if (lo8 == 0x15)
486 debug("cmp/pl\tr%i\n", r8);
487 else if (lo8 == 0x16)
488 debug("lds.l\t@r%i+,macl\n", r8);
489 else if (lo8 == 0x18)
490 debug("shll8\tr%i\n", r8);
491 else if (lo8 == 0x19)
492 debug("shlr8\tr%i\n", r8);
493 else if (lo8 == 0x1a)
494 debug("lds\tr%i,macl\n", r8);
495 else if (lo8 == 0x1b)
496 debug("tas.b\t@r%i\n", r8);
497 else if (lo8 == 0x1e)
498 debug("ldc\tr%i,gbr\n", r8);
499 else if (lo8 == 0x20)
500 debug("shal\tr%i\n", r8);
501 else if (lo8 == 0x21)
502 debug("shar\tr%i\n", r8);
503 else if (lo8 == 0x22)
504 debug("sts.l\tpr,@-r%i\n", r8);
505 else if (lo8 == 0x24)
506 debug("rotcl\tr%i\n", r8);
507 else if (lo8 == 0x25)
508 debug("rotcr\tr%i\n", r8);
509 else if (lo8 == 0x26)
510 debug("lds.l\t@r%i+,pr\n", r8);
511 else if (lo8 == 0x28)
512 debug("shll16\tr%i\n", r8);
513 else if (lo8 == 0x29)
514 debug("shlr16\tr%i\n", r8);
515 else if (lo8 == 0x2a)
516 debug("lds\tr%i,pr\n", r8);
517 else if (lo8 == 0x2b)
518 debug("jmp\t@r%i\n", r8);
519 else if (lo8 == 0x56)
520 debug("lds.l\t@r%i+,fpul\n", r8);
521 else if (lo8 == 0x5a)
522 debug("lds\tr%i,fpul\n", r8);
523 else if (lo8 == 0x6a)
524 debug("lds\tr%i,fpscr\n", r8);
525 else
526 debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
527 break;
528 case 0x5:
529 debug("mov.l\t@(%i,r%i),r%i\n", lo4 * 4, r4, r8);
530 break;
531 case 0x6:
532 if (lo4 == 0x0)
533 debug("mov.b\t@r%i,r%i\n", r4, r8);
534 else if (lo4 == 0x1)
535 debug("mov.w\t@r%i,r%i\n", r4, r8);
536 else if (lo4 == 0x2)
537 debug("mov.l\t@r%i,r%i\n", r4, r8);
538 else if (lo4 == 0x3)
539 debug("mov\tr%i,r%i\n", r4, r8);
540 else if (lo4 == 0x4)
541 debug("mov.b\t@r%i+,r%i\n", r4, r8);
542 else if (lo4 == 0x6)
543 debug("mov.l\t@r%i+,r%i\n", r4, r8);
544 else if (lo4 == 0x7)
545 debug("not\tr%i,r%i\n", r4, r8);
546 else if (lo4 == 0x8)
547 debug("swap.b\tr%i,r%i\n", r4, r8);
548 else if (lo4 == 0x9)
549 debug("swap.w\tr%i,r%i\n", r4, r8);
550 else if (lo4 == 0xa)
551 debug("negc\tr%i,r%i\n", r4, r8);
552 else if (lo4 == 0xb)
553 debug("neg\tr%i,r%i\n", r4, r8);
554 else if (lo4 == 0xc)
555 debug("extu.b\tr%i,r%i\n", r4, r8);
556 else if (lo4 == 0xd)
557 debug("extu.w\tr%i,r%i\n", r4, r8);
558 else if (lo4 == 0xe)
559 debug("exts.b\tr%i,r%i\n", r4, r8);
560 else if (lo4 == 0xf)
561 debug("exts.w\tr%i,r%i\n", r4, r8);
562 else
563 debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
564 break;
565 case 0x7:
566 debug("add\t#%i,r%i\n", (int8_t)lo8, r8);
567 break;
568 case 0x8:
569 if (r8 == 0x8)
570 debug("cmp/eq\t#%i,r0\n", (int8_t)lo8);
571 else if (r8 == 0x9 || r8 == 0xb || r8 == 0xd || r8 == 0xf) {
572 addr = (int8_t)lo8;
573 addr = dumpaddr + 4 + (addr << 1);
574 debug("b%s%s\t0x%x\n",
575 (r8 == 0x9 || r8 == 0xd)? "t" : "f",
576 (r8 == 0x9 || r8 == 0xb)? "" : "/s", (int)addr);
577 } else
578 debug("UNIMPLEMENTED hi4=0x%x,0x%x\n", hi4, r8);
579 break;
580 case 0x9:
581 case 0xd:
582 addr = lo8 * (hi4==9? 2 : 4);
583 addr += (dumpaddr & ~(hi4==9? 1 : 3)) + 4;
584 debug("mov.%s\t0x%x,r%i\n", hi4==9? "w":"l", (int)addr, r8);
585 break;
586 case 0xa:
587 case 0xb:
588 addr = (int32_t)(int16_t)((iword & 0xfff) << 4);
589 addr = ((int32_t)addr >> 3);
590 addr += dumpaddr + 4;
591 debug("%s\t0x%x\n", hi4==0xa? "bra":"bsr", (int)addr);
592 break;
593 case 0xc:
594 if (r8 == 0x3)
595 debug("trapa\t#%i\n", (uint8_t)lo8);
596 else if (r8 == 0x8)
597 debug("tst\t#%i,r0\n", (uint8_t)lo8);
598 else if (r8 == 0x9)
599 debug("and\t#%i,r0\n", (uint8_t)lo8);
600 else if (r8 == 0xa)
601 debug("xor\t#%i,r0\n", (uint8_t)lo8);
602 else if (r8 == 0xb)
603 debug("or\t#%i,r0\n", (uint8_t)lo8);
604 else if (r8 == 0xc)
605 debug("tst.b\t#%i,@(r0,gbr)\n", (uint8_t)lo8);
606 else if (r8 == 0xd)
607 debug("and.b\t#%i,@(r0,gbr)\n", (uint8_t)lo8);
608 else if (r8 == 0xe)
609 debug("xor.b\t#%i,@(r0,gbr)\n", (uint8_t)lo8);
610 else if (r8 == 0xf)
611 debug("or.b\t#%i,@(r0,gbr)\n", (uint8_t)lo8);
612 else
613 debug("UNIMPLEMENTED hi4=0x%x,0x%x\n", hi4, r8);
614 break;
615 case 0xe:
616 debug("mov\t#%i,r%i\n", (int8_t)lo8, r8);
617 break;
618 default:debug("UNIMPLEMENTED hi4=0x%x\n", hi4);
619 }
620
621 return sizeof(iword);
622 }
623
624
625 /*
626 * sh_cpu_disassemble_instr():
627 *
628 * Convert an instruction word into human readable format, for instruction
629 * tracing.
630 *
631 * If running is 1, cpu->pc should be the address of the instruction.
632 *
633 * If running is 0, things that depend on the runtime environment (eg.
634 * register contents) will not be shown, and addr will be used instead of
635 * cpu->pc for relative addresses.
636 */
637 int sh_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,
638 int running, uint64_t dumpaddr)
639 {
640 uint64_t offset;
641 uint32_t iword;
642 char *symbol;
643
644 if (running)
645 dumpaddr = cpu->pc;
646
647 symbol = get_symbol_name(&cpu->machine->symbol_context,
648 dumpaddr, &offset);
649 if (symbol != NULL && offset==0)
650 debug("<%s>\n", symbol);
651
652 if (cpu->machine->ncpus > 1 && running)
653 debug("cpu%i: ", cpu->cpu_id);
654
655 if (cpu->cd.sh.cpu_type.bits == 32)
656 debug("%08x", (int)dumpaddr);
657 else
658 debug("%016llx", (long long)dumpaddr);
659
660 if (cpu->cd.sh.compact)
661 return sh_cpu_disassemble_instr_compact(cpu, instr,
662 running, dumpaddr);
663
664 if (cpu->byte_order == EMUL_BIG_ENDIAN)
665 iword = (instr[0] << 24) + (instr[1] << 16) + (instr[2] << 8)
666 + instr[3];
667 else
668 iword = (instr[3] << 24) + (instr[2] << 16) + (instr[1] << 8)
669 + instr[0];
670
671 debug(": %08x\t", iword);
672
673 /*
674 * Decode the instruction:
675 */
676
677 debug("TODO\n");
678
679 return sizeof(iword);
680 }
681
682
683 #include "tmp_sh_tail.c"
684

  ViewVC Help
Powered by ViewVC 1.1.26