/[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 30 - (hide 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 dpavlin 14 /*
2 dpavlin 24 * Copyright (C) 2005-2006 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 30 * $Id: cpu_sh.c,v 1.21 2006/07/25 21:49:14 debug Exp $
29 dpavlin 14 *
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 dpavlin 30 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 dpavlin 14 return 0;
74    
75     cpu->memory_rw = sh_memory_rw;
76    
77 dpavlin 30 cpu->cd.sh.cpu_type = cpu_type_defs[i];
78 dpavlin 14 cpu->byte_order = EMUL_LITTLE_ENDIAN;
79 dpavlin 30 cpu->is_32bit = cpu->cd.sh.cpu_type.bits == 32;
80     cpu->cd.sh.compact = 1; /* Default to 16-bit opcode mode */
81 dpavlin 14
82 dpavlin 30 cpu->translate_v2p = sh_translate_v2p;
83    
84 dpavlin 14 if (cpu->is_32bit) {
85 dpavlin 28 cpu->run_instr = sh32_run_instr;
86 dpavlin 14 cpu->update_translation_table = sh32_update_translation_table;
87 dpavlin 18 cpu->invalidate_translation_caches =
88     sh32_invalidate_translation_caches;
89 dpavlin 14 cpu->invalidate_code_translation =
90     sh32_invalidate_code_translation;
91     } else {
92 dpavlin 28 cpu->run_instr = sh_run_instr;
93 dpavlin 14 cpu->update_translation_table = sh_update_translation_table;
94 dpavlin 18 cpu->invalidate_translation_caches =
95     sh_invalidate_translation_caches;
96 dpavlin 14 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 dpavlin 30 /* 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 dpavlin 14 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 dpavlin 30 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 dpavlin 14 }
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 dpavlin 22 uint64_t offset;
158 dpavlin 14 int i, x = cpu->cpu_id, nregs = cpu->cd.sh.compact? 16 : 64;
159 dpavlin 30 int bits32 = cpu->cd.sh.cpu_type.bits == 32;
160 dpavlin 14
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 dpavlin 30 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 dpavlin 14 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 dpavlin 30 } 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 dpavlin 14 }
240     }
241    
242    
243     /*
244 dpavlin 24 * 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 dpavlin 14 * 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 dpavlin 30 * 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 dpavlin 14 * 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 dpavlin 24 int running, uint64_t dumpaddr)
316 dpavlin 14 {
317 dpavlin 22 uint64_t addr;
318 dpavlin 14 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 dpavlin 30 addr = lo8 * (hi4==9? 2 : 4);
583 dpavlin 14 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 dpavlin 24 int running, uint64_t dumpaddr)
639 dpavlin 14 {
640 dpavlin 22 uint64_t offset;
641 dpavlin 14 uint32_t iword;
642 dpavlin 22 char *symbol;
643 dpavlin 14
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 dpavlin 30 if (cpu->cd.sh.cpu_type.bits == 32)
656 dpavlin 14 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 dpavlin 24 running, dumpaddr);
663 dpavlin 14
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