/[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 20 - (hide annotations)
Mon Oct 8 16:19:23 2007 UTC (13 years, 3 months ago) by dpavlin
File MIME type: text/plain
File size: 15538 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1055 2005/11/25 22:48:36 debug Exp $
20051031	Adding disassembly support for more ARM instructions (clz,
		smul* etc), and adding a hack to support "new tiny" pages
		for StrongARM.
20051101	Minor documentation updates (NetBSD 2.0.2 -> 2.1, and OpenBSD
		3.7 -> 3.8, and lots of testing).
		Changing from 1-sector PIO mode 0 transfers to 128-sector PIO
		mode 3 (in dev_wdc).
		Various minor ARM dyntrans updates (pc-relative loads from
		within the same page as the instruction are now treated as
		constant "mov").
20051102	Re-enabling instruction combinations (they were accidentally
		disabled).
		Dyntrans TLB entries are now overwritten using a round-robin
		scheme instead of randomly. This increases performance.
		Fixing a typo in file.c (thanks to Chuan-Hua Chang for
		noticing it).
		Experimenting with adding ATAPI support to dev_wdc (to make
		emulated *BSD detect cdroms as cdroms, not harddisks).
20051104	Various minor updates.
20051105	Continuing on the ATAPI emulation. Seems to work well enough
		for a NetBSD/cats installation, but not OpenBSD/cats.
		Various other updates.
20051106	Modifying the -Y command line option to allow scaleup with
		certain graphic controllers (only dev_vga so far), not just
		scaledown.
		Some minor dyntrans cleanups.
20051107	Beginning a cleanup up the PCI subsystem (removing the
		read_register hack, etc).
20051108	Continuing the cleanup; splitting up some pci devices into a
		normal autodev device and some separate pci glue code.
20051109	Continuing on the PCI bus stuff; all old pci_*.c have been
		incorporated into normal devices and/or rewritten as glue code
		only, adding a dummy Intel 82371AB PIIX4 for Malta (not really
		tested yet).
		Minor pckbc fix so that Linux doesn't complain.
		Working on the DEC 21143 NIC (ethernet mac rom stuff mostly).
		Various other minor fixes.
20051110	Some more ARM dyntrans fine-tuning (e.g. some instruction
		combinations (cmps followed by conditional branch within the
		same page) and special cases for DPIs with regform when the
		shifter isn't used).
20051111	ARM dyntrans updates: O(n)->O(1) for just-mark-as-non-
		writable in the generic pc_to_pointers function, and some other
		minor hacks.
		Merging Cobalt and evbmips (Malta) ISA interrupt handling,
		and some minor fixes to allow Linux to accept harddisk irqs.
20051112	Minor device updates (pckbc, dec21143, lpt, ...), most
		importantly fixing the ALI M1543/M5229 so that harddisk irqs
		work with Linux/CATS.
20051113	Some more generalizations of the PCI subsystem.
		Finally took the time to add a hack for SCSI CDROM TOCs; this
		enables OpenBSD to use partition 'a' (as needed by the OpenBSD
		installer), and Windows NT's installer to get a bit further.
		Also fixing dev_wdc to allow Linux to detect ATAPI CDROMs.
		Continuing on the DEC 21143.
20051114	Minor ARM dyntrans tweaks; ARM cmps+branch optimization when
		comparing with 0, and generalizing the xchg instr. comb.
		Adding disassembly of ARM mrrc/mcrr and q{,d}{add,sub}.
20051115	Continuing on various PPC things (BATs, other address trans-
		lation things, various loads/stores, BeBox emulation, etc.).
		Beginning to work on PPC interrupt/exception support.
20051116	Factoring out some code which initializes legacy ISA devices
		from those machines that use them (bus_isa).
		Continuing on PPC interrupt/exception support.
20051117	Minor Malta fixes: RTC year offset = 80, disabling a speed hack
		which caused NetBSD to detect a too fast cpu, and adding a new
		hack to make Linux detect a faster cpu.
		Continuing on the Artesyn PM/PPC emulation mode.
		Adding an Algor emulation skeleton (P4032 and P5064);
		implementing some of the basics.
		Continuing on PPC emulation in general; usage of unimplemented
		SPRs is now easier to track, continuing on memory/exception
		related issues, etc.
20051118	More work on PPC emulation (tgpr0..3, exception handling,
		memory stuff, syscalls, etc.).
20051119	Changing the ARM dyntrans code to mostly use cpu->pc, and not
		necessarily use arm reg 15. Seems to work.
		Various PPC updates; continuing on the PReP emulation mode.
20051120	Adding a workaround/hack to dev_mc146818 to allow NetBSD/prep
		to detect the clock.
20051121	More cleanup of the PCI bus (memory and I/O bases, etc).
		Continuing on various PPC things (decrementer and timebase,
		WDCs on obio (on PReP) use irq 13, not 14/15).
20051122	Continuing on the CPC700 controller (interrupts etc) for PMPPC,
		and on PPC stuff in general.
		Finally! After some bug fixes to the virtual to physical addr
		translation, NetBSD/{prep,pmppc} 2.1 reach userland and are
		stable enough to be interacted with.
		More PCI updates; reverse-endian device access for PowerPC etc.
20051123	Generalizing the IEEE floating point subsystem (moving it out
		from src/cpus/cpu_mips_coproc.c into a new src/float_emul.c).
		Input via slave xterms was sometimes not really working; fixing
		this for ns16550, and a warning message is now displayed if
		multiple non-xterm consoles are active.
		Adding some PPC floating point support, etc.
		Various interrupt related updates (dev_wdc, _ns16550, _8259,
		and the isa32 common code in machine.c).
		NetBSD/prep can now be installed! :-) (Well, with some manual
		commands necessary before running sysinst.) Updating the
		documentation and various other things to reflect this.
20051124	Various minor documentation updates.
		Continuing the work on the DEC 21143 NIC.
20051125	LOTS of work on the 21143. Both OpenBSD and NetBSD work fine
		with it now, except that OpenBSD sometimes gives a time-out
		warning.
		Minor documentation updates.

==============  RELEASE 0.3.7  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26