/[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 14 - (show annotations)
Mon Oct 8 16:18:51 2007 UTC (16 years, 6 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 /*
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