/[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 14 - (hide annotations)
Mon Oct 8 16:18:51 2007 UTC (13 years, 3 months ago) by dpavlin
File MIME type: text/plain
File size: 16121 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.982 2005/10/07 22:45:32 debug Exp $
20050816	Some success in decoding the way the SGI O2 PROM draws graphics
		during bootup; lines/rectangles and bitmaps work, enough to
		show the bootlogo etc. :-)
		Adding more PPC instructions, and (dummy) BAT registers.
20050817	Updating the pckbc to support scancode type 3 keyboards
		(required in order to interact with the SGI O2 PROM).
		Adding more PPC instructions.
20050818	Adding more ARM instructions; general register forms.
		Importing armreg.h from NetBSD (ARM cpu ids). Adding a (dummy)
		CATS machine mode (using SA110 as the default CPU).
		Continuing on general dyntrans related stuff.
20050819	Register forms for ARM load/stores. Gaah! The Compaq C Compiler
		bug is triggered for ARM loads as well, not just PPC :-(
		Adding full support for ARM PC-relative load/stores, and load/
		stores where the PC register is the destination register.
		Adding support for ARM a.out binaries.
20050820	Continuing to add more ARM instructions, and correcting some
		bugs. Continuing on CATS emulation.
		More work on the PPC stuff.
20050821	Minor PPC and ARM updates. Adding more machine types.
20050822	All ARM "data processing instructions" are now generated
		automatically.
20050824	Beginning the work on the ARM system control coprocessor.
		Adding support for ARM halfword load/stores, and signed loads.
20050825	Fixing an important bug related to the ARM condition codes.
		OpenBSD/zaurus and NetBSD/netwinder now print some boot
		messages. :)
		Adding a dummy SH (Hitachi SuperH) cpu family.
		Beginning to add some ARM virtual address translation.
		MIPS bugfixes: unaligned PC now cause an ADEL exception (at
		least for non-bintrans execution), and ADEL/ADES (not
		TLBL/TLBS) are used if userland tries to access kernel space.
		(Thanks to Joshua Wise for making me aware of these bugs.)
20050827	More work on the ARM emulation, and various other updates.
20050828	More ARM updates.
		Finally taking the time to work on translation invalidation
		(i.e. invalidating translated code mappings when memory is
		written to). Hopefully this doesn't break anything.
20050829	Moving CPU related files from src/ to a new subdir, src/cpus/.
		Moving PROM emulation stuff from src/ to src/promemul/.
		Better debug instruction trace for ARM loads and stores.
20050830	Various ARM updates (correcting CMP flag calculation, etc).
20050831	PPC instruction updates. (Flag fixes, etc.)
20050901	Various minor PPC and ARM instruction emulation updates.
		Minor OpenFirmware emulation updates.
20050903	Adding support for adding arbitrary ARM coprocessors (with
		the i80321 I/O coprocessor as a first test).
		Various other ARM and PPC updates.
20050904	Adding some SHcompact disassembly routines.
20050907	(Re)adding a dummy HPPA CPU module, and a dummy i960 module.
20050908	Began hacking on some Apple Partition Table support.
20050909	Adding support for loading Mach-O (Darwin PPC) binaries.
20050910	Fixing an ARM bug (Carry flag was incorrectly updated for some
		data processing instructions); OpenBSD/cats and NetBSD/
		netwinder get quite a bit further now.
		Applying a patch to dev_wdc, and a one-liner to dev_pcic, to
		make them work better when emulating new versions of OpenBSD.
		(Thanks to Alexander Yurchenko for the patches.)
		Also doing some other minor updates to dev_wdc. (Some cleanup,
		and finally converting to devinit, etc.)
20050912	IRIX doesn't have u_int64_t by default (noticed by Andreas
		<avr@gnulinux.nl>); configure updated to reflect this.
		Working on ARM register bank switching, CPSR vs SPSR issues,
		and beginning the work on interrupt/exception support.
20050913	Various minor ARM updates (speeding up load/store multiple,
		and fixing a ROR bug in R(); NetBSD/cats now boots as far as
		OpenBSD/cats).
20050917	Adding a dummy Atmel AVR (8-bit) cpu family skeleton.
20050918	Various minor updates.
20050919	Symbols are now loaded from Mach-O executables.
		Continuing the work on adding ARM exception support.
20050920	More work on ARM stuff: OpenBSD/cats and NetBSD/cats reach
		userland! :-)
20050921	Some more progress on ARM interrupt specifics.
20050923	Fixing linesize for VR4121 (patch by Yurchenko). Also fixing
		linesizes/cachesizes for some other VR4xxx.
		Adding a dummy Acer Labs M1543 PCI-ISA bridge (for CATS) and a
		dummy Symphony Labs 83C553 bridge (for Netwinder), usable by 
		dev_footbridge.
20050924	Some PPC progress.
20050925	More PPC progress.
20050926	PPC progress (fixing some bugs etc); Darwin's kernel gets
		slightly further than before.
20050928	Various updates: footbridge/ISA/pciide stuff, and finally
		fixing the VGA text scroll-by-changing-the-base-offset bug.
20050930	Adding a dummy S3 ViRGE pci card for CATS emulation, which
		both NetBSD and OpenBSD detects as VGA.
		Continuing on Footbridge (timers, ISA interrupt stuff).
20051001	Continuing... there are still bugs, probably interrupt-
		related.
20051002	More work on the Footbridge (interrupt stuff).
20051003	Various minor updates. (Trying to find the bug(s).)
20051004	Continuing on the ARM stuff.
20051005	More ARM-related fixes.
20051007	FINALLY! Found and fixed 2 ARM bugs: 1 memory related, and the
		other was because of an error in the ARM manual (load multiple
		with the S-bit set should _NOT_ load usermode registers, as the
		manual says, but it should load saved registers, which may or
		may not happen to be usermode registers).
		NetBSD/cats and OpenBSD/cats seem to install fine now :-)
		except for a minor bug at the end of the OpenBSD/cats install.
		Updating the documentation, preparing for the next release.
20051008	Continuing with release testing and cleanup.

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     * $Id: cpu_sh.c,v 1.6 2005/09/04 14:38:17 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     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     cpu->invalidate_translation_caches_paddr =
76     sh32_invalidate_translation_caches_paddr;
77     cpu->invalidate_code_translation =
78     sh32_invalidate_code_translation;
79     } else {
80     cpu->update_translation_table = sh_update_translation_table;
81     cpu->invalidate_translation_caches_paddr =
82     sh_invalidate_translation_caches_paddr;
83     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_show_full_statistics():
196     *
197     * Show detailed statistics on opcode usage on each cpu.
198     */
199     void sh_cpu_show_full_statistics(struct machine *m)
200     {
201     fatal("sh_cpu_show_full_statistics(): TODO\n");
202     }
203    
204    
205     /*
206     * sh_cpu_tlbdump():
207     *
208     * Called from the debugger to dump the TLB in a readable format.
209     * x is the cpu number to dump, or -1 to dump all CPUs.
210     *
211     * If rawflag is nonzero, then the TLB contents isn't formated nicely,
212     * just dumped.
213     */
214     void sh_cpu_tlbdump(struct machine *m, int x, int rawflag)
215     {
216     fatal("sh_cpu_tlbdump(): TODO\n");
217     }
218    
219    
220     /*
221     * sh_cpu_interrupt():
222     */
223     int sh_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)
224     {
225     fatal("sh_cpu_interrupt(): TODO\n");
226     return 0;
227     }
228    
229    
230     /*
231     * sh_cpu_interrupt_ack():
232     */
233     int sh_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)
234     {
235     /* fatal("sh_cpu_interrupt_ack(): TODO\n"); */
236     return 0;
237     }
238    
239    
240     /*
241     * sh_cpu_disassemble_instr_compact():
242     *
243     * SHcompact instruction disassembly. The top 4 bits of each 16-bit
244     * instruction word is used as the main opcode. For most instructions, the
245     * lowest 4 or 8 bits then select sub-opcode.
246     */
247     int sh_cpu_disassemble_instr_compact(struct cpu *cpu, unsigned char *instr,
248     int running, uint64_t dumpaddr, int bintrans)
249     {
250     uint64_t offset, addr;
251     uint16_t iword;
252     int hi4, lo4, lo8, r8, r4;
253     char *symbol, *mnem = "ERROR";
254    
255     if (cpu->byte_order == EMUL_BIG_ENDIAN)
256     iword = (instr[0] << 8) + instr[1];
257     else
258     iword = (instr[1] << 8) + instr[0];
259    
260     debug(": %04x \t", iword);
261     hi4 = iword >> 12; lo4 = iword & 15; lo8 = iword & 255;
262     r8 = (iword >> 8) & 15; r4 = (iword >> 4) & 15;
263    
264     /*
265     * Decode the instruction:
266     */
267    
268     switch (hi4) {
269     case 0x0:
270     if (lo8 == 0x02)
271     debug("stc\tsr,r%i\n", r8);
272     else if (lo8 == 0x03)
273     debug("bsrf\tr%i\n", r8);
274     else if (lo4 == 0x4)
275     debug("mov.b\tr%i,@(r0,r%i)\n", r4, r8);
276     else if (lo4 == 0x5)
277     debug("mov.w\tr%i,@(r0,r%i)\n", r4, r8);
278     else if (lo4 == 0x6)
279     debug("mov.l\tr%i,@(r0,r%i)\n", r4, r8);
280     else if (lo4 == 0x7)
281     debug("mul.l\tr%i,r%i\n", r4, r8);
282     else if (iword == 0x0008)
283     debug("clrt\n");
284     else if (iword == 0x0009)
285     debug("nop\n");
286     else if (lo8 == 0x0a)
287     debug("sts\tmach,r%i\n", r8);
288     else if (iword == 0x000b)
289     debug("rts\n");
290     else if (lo4 == 0xc)
291     debug("mov.b\t@(r0,r%i),r%i\n", r4, r8);
292     else if (lo4 == 0xd)
293     debug("mov.w\t@(r0,r%i),r%i\n", r4, r8);
294     else if (lo4 == 0xe)
295     debug("mov.l\t@(r0,r%i),r%i\n", r4, r8);
296     else if (lo8 == 0x12)
297     debug("stc\tgbr,r%i\n", r8);
298     else if (iword == 0x0018)
299     debug("sett\n");
300     else if (iword == 0x0019)
301     debug("div0u\n");
302     else if (lo8 == 0x1a)
303     debug("sts\tmacl,r%i\n", r8);
304     else if (lo8 == 0x23)
305     debug("braf\tr%i\n", r8);
306     else if (iword == 0x0028)
307     debug("clrmac\n");
308     else if (lo8 == 0x29)
309     debug("movt\tr%i\n", r8);
310     else if (iword == 0x003b)
311     debug("brk\n");
312     else if (iword == 0x0048)
313     debug("clrs\n");
314     else if (iword == 0x0058)
315     debug("sets\n");
316     else if (lo8 == 0x83)
317     debug("pref\t@r%i\n", r8);
318     else
319     debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
320     break;
321     case 0x1:
322     debug("mov.l\tr%i,@(%i,r%i)\n", r4, lo4 * 4, r8);
323     break;
324     case 0x2:
325     if (lo4 == 0x0)
326     debug("mov.b\tr%i,@r%i\n", r4, r8);
327     else if (lo4 == 0x1)
328     debug("mov.w\tr%i,@r%i\n", r4, r8);
329     else if (lo4 == 0x2)
330     debug("mov.l\tr%i,@r%i\n", r4, r8);
331     else if (lo4 == 0x4)
332     debug("mov.b\tr%i,@-r%i\n", r4, r8);
333     else if (lo4 == 0x5)
334     debug("mov.w\tr%i,@-r%i\n", r4, r8);
335     else if (lo4 == 0x6)
336     debug("mov.l\tr%i,@-r%i\n", r4, r8);
337     else if (lo4 == 0x7)
338     debug("div0s\tr%i,r%i\n", r4, r8);
339     else if (lo4 == 0x8)
340     debug("tst\tr%i,r%i\n", r4, r8);
341     else if (lo4 == 0x9)
342     debug("and\tr%i,r%i\n", r4, r8);
343     else if (lo4 == 0xa)
344     debug("xor\tr%i,r%i\n", r4, r8);
345     else if (lo4 == 0xb)
346     debug("or\tr%i,r%i\n", r4, r8);
347     else if (lo4 == 0xc)
348     debug("cmp/str\tr%i,r%i\n", r4, r8);
349     else if (lo4 == 0xd)
350     debug("xtrct\tr%i,r%i\n", r4, r8);
351     else if (lo4 == 0xe)
352     debug("mulu.w\tr%i,r%i\n", r4, r8);
353     else if (lo4 == 0xf)
354     debug("muls.w\tr%i,r%i\n", r4, r8);
355     else
356     debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
357     break;
358     case 0x3:
359     if (lo4 == 0x0)
360     debug("cmp/eq\tr%i,r%i\n", r4, r8);
361     else if (lo4 == 0x2)
362     debug("cmp/hs\tr%i,r%i\n", r4, r8);
363     else if (lo4 == 0x3)
364     debug("cmp/ge\tr%i,r%i\n", r4, r8);
365     else if (lo4 == 0x4)
366     debug("div1\tr%i,r%i\n", r4, r8);
367     else if (lo4 == 0x5)
368     debug("dmulu.l\tr%i,r%i\n", r4, r8);
369     else if (lo4 == 0x6)
370     debug("cmp/hi\tr%i,r%i\n", r4, r8);
371     else if (lo4 == 0x7)
372     debug("cmp/gt\tr%i,r%i\n", r4, r8);
373     else if (lo4 == 0x8)
374     debug("sub\tr%i,r%i\n", r4, r8);
375     else if (lo4 == 0xa)
376     debug("subc\tr%i,r%i\n", r4, r8);
377     else if (lo4 == 0xb)
378     debug("subv\tr%i,r%i\n", r4, r8);
379     else if (lo4 == 0xc)
380     debug("add\tr%i,r%i\n", r4, r8);
381     else if (lo4 == 0xd)
382     debug("dmuls.l\tr%i,r%i\n", r4, r8);
383     else if (lo4 == 0xe)
384     debug("addc\tr%i,r%i\n", r4, r8);
385     else if (lo4 == 0xf)
386     debug("addv\tr%i,r%i\n", r4, r8);
387     else
388     debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
389     break;
390     case 0x4:
391     if (lo8 == 0x00)
392     debug("shll\tr%i\n", r8);
393     else if (lo8 == 0x01)
394     debug("shlr\tr%i\n", r8);
395     else if (lo8 == 0x04)
396     debug("rotl\tr%i\n", r8);
397     else if (lo8 == 0x05)
398     debug("rotr\tr%i\n", r8);
399     else if (lo8 == 0x06)
400     debug("lds.l\t@r%i+,mach\n", r8);
401     else if (lo8 == 0x08)
402     debug("shll2\tr%i\n", r8);
403     else if (lo8 == 0x09)
404     debug("shlr2\tr%i\n", r8);
405     else if (lo8 == 0x0a)
406     debug("lds\tr%i,mach\n", r8);
407     else if (lo8 == 0x0b)
408     debug("jsr\t@r%i\n", r8);
409     else if (lo4 == 0xc)
410     debug("shad\tr%i,r%i\n", r4, r8);
411     else if (lo4 == 0xd)
412     debug("shld\tr%i,r%i\n", r4, r8);
413     else if (lo8 == 0x0e)
414     debug("ldc\tr%i,sr\n", r8);
415     else if (lo8 == 0x10)
416     debug("dt\tr%i\n", r8);
417     else if (lo8 == 0x11)
418     debug("cmp/pz\tr%i\n", r8);
419     else if (lo8 == 0x15)
420     debug("cmp/pl\tr%i\n", r8);
421     else if (lo8 == 0x16)
422     debug("lds.l\t@r%i+,macl\n", r8);
423     else if (lo8 == 0x18)
424     debug("shll8\tr%i\n", r8);
425     else if (lo8 == 0x19)
426     debug("shlr8\tr%i\n", r8);
427     else if (lo8 == 0x1a)
428     debug("lds\tr%i,macl\n", r8);
429     else if (lo8 == 0x1b)
430     debug("tas.b\t@r%i\n", r8);
431     else if (lo8 == 0x1e)
432     debug("ldc\tr%i,gbr\n", r8);
433     else if (lo8 == 0x20)
434     debug("shal\tr%i\n", r8);
435     else if (lo8 == 0x21)
436     debug("shar\tr%i\n", r8);
437     else if (lo8 == 0x22)
438     debug("sts.l\tpr,@-r%i\n", r8);
439     else if (lo8 == 0x24)
440     debug("rotcl\tr%i\n", r8);
441     else if (lo8 == 0x25)
442     debug("rotcr\tr%i\n", r8);
443     else if (lo8 == 0x26)
444     debug("lds.l\t@r%i+,pr\n", r8);
445     else if (lo8 == 0x28)
446     debug("shll16\tr%i\n", r8);
447     else if (lo8 == 0x29)
448     debug("shlr16\tr%i\n", r8);
449     else if (lo8 == 0x2a)
450     debug("lds\tr%i,pr\n", r8);
451     else if (lo8 == 0x2b)
452     debug("jmp\t@r%i\n", r8);
453     else if (lo8 == 0x56)
454     debug("lds.l\t@r%i+,fpul\n", r8);
455     else if (lo8 == 0x5a)
456     debug("lds\tr%i,fpul\n", r8);
457     else if (lo8 == 0x6a)
458     debug("lds\tr%i,fpscr\n", r8);
459     else
460     debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
461     break;
462     case 0x5:
463     debug("mov.l\t@(%i,r%i),r%i\n", lo4 * 4, r4, r8);
464     break;
465     case 0x6:
466     if (lo4 == 0x0)
467     debug("mov.b\t@r%i,r%i\n", r4, r8);
468     else if (lo4 == 0x1)
469     debug("mov.w\t@r%i,r%i\n", r4, r8);
470     else if (lo4 == 0x2)
471     debug("mov.l\t@r%i,r%i\n", r4, r8);
472     else if (lo4 == 0x3)
473     debug("mov\tr%i,r%i\n", r4, r8);
474     else if (lo4 == 0x4)
475     debug("mov.b\t@r%i+,r%i\n", r4, r8);
476     else if (lo4 == 0x6)
477     debug("mov.l\t@r%i+,r%i\n", r4, r8);
478     else if (lo4 == 0x7)
479     debug("not\tr%i,r%i\n", r4, r8);
480     else if (lo4 == 0x8)
481     debug("swap.b\tr%i,r%i\n", r4, r8);
482     else if (lo4 == 0x9)
483     debug("swap.w\tr%i,r%i\n", r4, r8);
484     else if (lo4 == 0xa)
485     debug("negc\tr%i,r%i\n", r4, r8);
486     else if (lo4 == 0xb)
487     debug("neg\tr%i,r%i\n", r4, r8);
488     else if (lo4 == 0xc)
489     debug("extu.b\tr%i,r%i\n", r4, r8);
490     else if (lo4 == 0xd)
491     debug("extu.w\tr%i,r%i\n", r4, r8);
492     else if (lo4 == 0xe)
493     debug("exts.b\tr%i,r%i\n", r4, r8);
494     else if (lo4 == 0xf)
495     debug("exts.w\tr%i,r%i\n", r4, r8);
496     else
497     debug("UNIMPLEMENTED hi4=0x%x, lo8=0x%02x\n", hi4, lo8);
498     break;
499     case 0x7:
500     debug("add\t#%i,r%i\n", (int8_t)lo8, r8);
501     break;
502     case 0x8:
503     if (r8 == 0x8)
504     debug("cmp/eq\t#%i,r0\n", (int8_t)lo8);
505     else if (r8 == 0x9 || r8 == 0xb || r8 == 0xd || r8 == 0xf) {
506     addr = (int8_t)lo8;
507     addr = dumpaddr + 4 + (addr << 1);
508     debug("b%s%s\t0x%x\n",
509     (r8 == 0x9 || r8 == 0xd)? "t" : "f",
510     (r8 == 0x9 || r8 == 0xb)? "" : "/s", (int)addr);
511     } else
512     debug("UNIMPLEMENTED hi4=0x%x,0x%x\n", hi4, r8);
513     break;
514     case 0x9:
515     case 0xd:
516     addr = ((int8_t)lo8) * (hi4==9? 2 : 4);
517     addr += (dumpaddr & ~(hi4==9? 1 : 3)) + 4;
518     debug("mov.%s\t0x%x,r%i\n", hi4==9? "w":"l", (int)addr, r8);
519     break;
520     case 0xa:
521     case 0xb:
522     addr = (int32_t)(int16_t)((iword & 0xfff) << 4);
523     addr = ((int32_t)addr >> 3);
524     addr += dumpaddr + 4;
525     debug("%s\t0x%x\n", hi4==0xa? "bra":"bsr", (int)addr);
526     break;
527     case 0xc:
528     if (r8 == 0x3)
529     debug("trapa\t#%i\n", (uint8_t)lo8);
530     else if (r8 == 0x8)
531     debug("tst\t#%i,r0\n", (uint8_t)lo8);
532     else if (r8 == 0x9)
533     debug("and\t#%i,r0\n", (uint8_t)lo8);
534     else if (r8 == 0xa)
535     debug("xor\t#%i,r0\n", (uint8_t)lo8);
536     else if (r8 == 0xb)
537     debug("or\t#%i,r0\n", (uint8_t)lo8);
538     else if (r8 == 0xc)
539     debug("tst.b\t#%i,@(r0,gbr)\n", (uint8_t)lo8);
540     else if (r8 == 0xd)
541     debug("and.b\t#%i,@(r0,gbr)\n", (uint8_t)lo8);
542     else if (r8 == 0xe)
543     debug("xor.b\t#%i,@(r0,gbr)\n", (uint8_t)lo8);
544     else if (r8 == 0xf)
545     debug("or.b\t#%i,@(r0,gbr)\n", (uint8_t)lo8);
546     else
547     debug("UNIMPLEMENTED hi4=0x%x,0x%x\n", hi4, r8);
548     break;
549     case 0xe:
550     debug("mov\t#%i,r%i\n", (int8_t)lo8, r8);
551     break;
552     default:debug("UNIMPLEMENTED hi4=0x%x\n", hi4);
553     }
554    
555     return sizeof(iword);
556     }
557    
558    
559     /*
560     * sh_cpu_disassemble_instr():
561     *
562     * Convert an instruction word into human readable format, for instruction
563     * tracing.
564     *
565     * If running is 1, cpu->pc should be the address of the instruction.
566     *
567     * If running is 0, things that depend on the runtime environment (eg.
568     * register contents) will not be shown, and addr will be used instead of
569     * cpu->pc for relative addresses.
570     */
571     int sh_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,
572     int running, uint64_t dumpaddr, int bintrans)
573     {
574     uint64_t offset, addr;
575     uint32_t iword;
576     int hi6;
577     char *symbol, *mnem = "ERROR";
578    
579     if (running)
580     dumpaddr = cpu->pc;
581    
582     symbol = get_symbol_name(&cpu->machine->symbol_context,
583     dumpaddr, &offset);
584     if (symbol != NULL && offset==0)
585     debug("<%s>\n", symbol);
586    
587     if (cpu->machine->ncpus > 1 && running)
588     debug("cpu%i: ", cpu->cpu_id);
589    
590     if (cpu->cd.sh.bits == 32)
591     debug("%08x", (int)dumpaddr);
592     else
593     debug("%016llx", (long long)dumpaddr);
594    
595     if (cpu->cd.sh.compact)
596     return sh_cpu_disassemble_instr_compact(cpu, instr,
597     running, dumpaddr, bintrans);
598    
599     if (cpu->byte_order == EMUL_BIG_ENDIAN)
600     iword = (instr[0] << 24) + (instr[1] << 16) + (instr[2] << 8)
601     + instr[3];
602     else
603     iword = (instr[3] << 24) + (instr[2] << 16) + (instr[1] << 8)
604     + instr[0];
605    
606     debug(": %08x\t", iword);
607    
608     /*
609     * Decode the instruction:
610     */
611    
612     debug("TODO\n");
613    
614     return sizeof(iword);
615     }
616    
617    
618     #include "tmp_sh_tail.c"
619    

  ViewVC Help
Powered by ViewVC 1.1.26