/[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 26 - (hide annotations)
Mon Oct 8 16:20:10 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 15992 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1264 2006/06/25 11:08:04 debug Exp $
20060624	Replacing the error-prone machine type initialization stuff
		with something more reasonable.
		Finally removing the old "cpu_run" kludge; moving around stuff
		in machine.c and emul.c to better suit the dyntrans system.
		Various minor dyntrans cleanups (renaming translate_address to
		translate_v2p, and experimenting with template physpages).
20060625	Removing the speed hack which separated the vph entries into
		two halves (code vs data); things seem a lot more stable now.
		Minor performance hack: R2000/R3000 cache isolation now only
		clears address translations when going into isolation, not
		when going out of it.
		Fixing the MIPS interrupt problems by letting mtc0 immediately
		cause interrupts.

==============  RELEASE 0.4.0.1  ==============


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 26 * $Id: cpu_sh.c,v 1.16 2006/06/24 21:47:23 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 dpavlin 22 uint64_t offset;
130 dpavlin 14 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 dpavlin 24 * sh_cpu_tlbdump():
196     *
197     * Called from the debugger to dump the TLB in a readable format.
198     * x is the cpu number to dump, or -1 to dump all CPUs.
199     *
200     * If rawflag is nonzero, then the TLB contents isn't formated nicely,
201     * just dumped.
202     */
203     void sh_cpu_tlbdump(struct machine *m, int x, int rawflag)
204     {
205     }
206    
207    
208     /*
209     * sh_cpu_gdb_stub():
210     *
211     * Execute a "remote GDB" command. Returns a newly allocated response string
212     * on success, NULL on failure.
213     */
214     char *sh_cpu_gdb_stub(struct cpu *cpu, char *cmd)
215     {
216     fatal("sh_cpu_gdb_stub(): TODO\n");
217     return NULL;
218     }
219    
220    
221     /*
222 dpavlin 14 * sh_cpu_interrupt():
223     */
224     int sh_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)
225     {
226     fatal("sh_cpu_interrupt(): TODO\n");
227     return 0;
228     }
229    
230    
231     /*
232     * sh_cpu_interrupt_ack():
233     */
234     int sh_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)
235     {
236     /* fatal("sh_cpu_interrupt_ack(): TODO\n"); */
237     return 0;
238     }
239    
240    
241     /*
242     * sh_cpu_disassemble_instr_compact():
243     *
244     * SHcompact instruction disassembly. The top 4 bits of each 16-bit
245     * instruction word is used as the main opcode. For most instructions, the
246     * lowest 4 or 8 bits then select sub-opcode.
247     */
248     int sh_cpu_disassemble_instr_compact(struct cpu *cpu, unsigned char *instr,
249 dpavlin 24 int running, uint64_t dumpaddr)
250 dpavlin 14 {
251 dpavlin 22 uint64_t addr;
252 dpavlin 14 uint16_t iword;
253     int hi4, lo4, lo8, r8, r4;
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 dpavlin 24 int running, uint64_t dumpaddr)
573 dpavlin 14 {
574 dpavlin 22 uint64_t offset;
575 dpavlin 14 uint32_t iword;
576 dpavlin 22 char *symbol;
577 dpavlin 14
578     if (running)
579     dumpaddr = cpu->pc;
580    
581     symbol = get_symbol_name(&cpu->machine->symbol_context,
582     dumpaddr, &offset);
583     if (symbol != NULL && offset==0)
584     debug("<%s>\n", symbol);
585    
586     if (cpu->machine->ncpus > 1 && running)
587     debug("cpu%i: ", cpu->cpu_id);
588    
589     if (cpu->cd.sh.bits == 32)
590     debug("%08x", (int)dumpaddr);
591     else
592     debug("%016llx", (long long)dumpaddr);
593    
594     if (cpu->cd.sh.compact)
595     return sh_cpu_disassemble_instr_compact(cpu, instr,
596 dpavlin 24 running, dumpaddr);
597 dpavlin 14
598     if (cpu->byte_order == EMUL_BIG_ENDIAN)
599     iword = (instr[0] << 24) + (instr[1] << 16) + (instr[2] << 8)
600     + instr[3];
601     else
602     iword = (instr[3] << 24) + (instr[2] << 16) + (instr[1] << 8)
603     + instr[0];
604    
605     debug(": %08x\t", iword);
606    
607     /*
608     * Decode the instruction:
609     */
610    
611     debug("TODO\n");
612    
613     return sizeof(iword);
614     }
615    
616    
617     #include "tmp_sh_tail.c"
618    

  ViewVC Help
Powered by ViewVC 1.1.26