/[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 18 - (hide annotations)
Mon Oct 8 16:19:11 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 16097 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1004 2005/10/27 14:01:10 debug Exp $
20051011        Passing -A as the default boot arg for CATS (works fine with
                OpenBSD/cats).
20051012	Fixing the VGA cursor offset bug, and speeding up framebuffer
		redraws if character cells contain the same thing as during
		the last redraw.
20051013	Adding a slow strd ARM instruction hack.
20051017	Minor updates: Adding a dummy i80321 Verde controller (for
		XScale emulation), fixing the disassembly of the ARM "ldrd"
		instruction, adding "support" for less-than-4KB pages for ARM
		(by not adding them to translation tables).
20051020	Continuing on some HPCarm stuff. A NetBSD/hpcarm kernel prints
		some boot messages on an emulated Jornada 720.
		Making dev_ram work better with dyntrans (speeds up some things
		quite a bit).
20051021	Automatically generating some of the most common ARM load/store
		multiple instructions.
20051022	Better statistics gathering for the ARM load/store multiple.
		Various other dyntrans and device updates.
20051023	Various minor updates.
20051024	Continuing; minor device and dyntrans fine-tuning. Adding the
		first "reasonable" instruction combination hacks for ARM (the
		cores of NetBSD/cats' memset and memcpy).
20051025	Fixing a dyntrans-related bug in dev_vga. Also changing the
		dyntrans low/high access notification to only be updated on
		writes, not reads. Hopefully it will be enough. (dev_vga in
		charcell mode now seems to work correctly with both reads and
		writes.)
		Experimenting with gathering dyntrans statistics (which parts
		of emulated RAM that are actually executed), and adding
		instruction combination hacks for cache cleaning and a part of
		NetBSD's scanc() function.
20051026	Adding a bitmap for ARM emulation which indicates if a page is
		(specifically) user accessible; loads and stores with the t-
		flag set can now use the translation arrays, which results in
		a measurable speedup.
20051027	Dyntrans updates; adding an extra bitmap array for 32-bit
		emulation modes, speeding up the check whether a physical page
		has any code translations or not (O(n) -> O(1)). Doing a
		similar reduction of O(n) to O(1) by avoiding the scan through
		the translation entries on a translation update (32-bit mode
		only).
		Various other minor hacks.
20051029	Quick release, without any testing at all.

==============  RELEASE 0.3.6.2  ==============


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 18 * $Id: cpu_sh.c,v 1.7 2005/10/22 17:24:21 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_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