/[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

Contents of /trunk/src/cpus/cpu_sh.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 18 - (show annotations)
Mon Oct 8 16:19:11 2007 UTC (16 years, 5 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 /*
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.7 2005/10/22 17:24:21 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 =
76 sh32_invalidate_translation_caches;
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 =
82 sh_invalidate_translation_caches;
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