/[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 20 - (show annotations)
Mon Oct 8 16:19:23 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 15538 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1055 2005/11/25 22:48:36 debug Exp $
20051031	Adding disassembly support for more ARM instructions (clz,
		smul* etc), and adding a hack to support "new tiny" pages
		for StrongARM.
20051101	Minor documentation updates (NetBSD 2.0.2 -> 2.1, and OpenBSD
		3.7 -> 3.8, and lots of testing).
		Changing from 1-sector PIO mode 0 transfers to 128-sector PIO
		mode 3 (in dev_wdc).
		Various minor ARM dyntrans updates (pc-relative loads from
		within the same page as the instruction are now treated as
		constant "mov").
20051102	Re-enabling instruction combinations (they were accidentally
		disabled).
		Dyntrans TLB entries are now overwritten using a round-robin
		scheme instead of randomly. This increases performance.
		Fixing a typo in file.c (thanks to Chuan-Hua Chang for
		noticing it).
		Experimenting with adding ATAPI support to dev_wdc (to make
		emulated *BSD detect cdroms as cdroms, not harddisks).
20051104	Various minor updates.
20051105	Continuing on the ATAPI emulation. Seems to work well enough
		for a NetBSD/cats installation, but not OpenBSD/cats.
		Various other updates.
20051106	Modifying the -Y command line option to allow scaleup with
		certain graphic controllers (only dev_vga so far), not just
		scaledown.
		Some minor dyntrans cleanups.
20051107	Beginning a cleanup up the PCI subsystem (removing the
		read_register hack, etc).
20051108	Continuing the cleanup; splitting up some pci devices into a
		normal autodev device and some separate pci glue code.
20051109	Continuing on the PCI bus stuff; all old pci_*.c have been
		incorporated into normal devices and/or rewritten as glue code
		only, adding a dummy Intel 82371AB PIIX4 for Malta (not really
		tested yet).
		Minor pckbc fix so that Linux doesn't complain.
		Working on the DEC 21143 NIC (ethernet mac rom stuff mostly).
		Various other minor fixes.
20051110	Some more ARM dyntrans fine-tuning (e.g. some instruction
		combinations (cmps followed by conditional branch within the
		same page) and special cases for DPIs with regform when the
		shifter isn't used).
20051111	ARM dyntrans updates: O(n)->O(1) for just-mark-as-non-
		writable in the generic pc_to_pointers function, and some other
		minor hacks.
		Merging Cobalt and evbmips (Malta) ISA interrupt handling,
		and some minor fixes to allow Linux to accept harddisk irqs.
20051112	Minor device updates (pckbc, dec21143, lpt, ...), most
		importantly fixing the ALI M1543/M5229 so that harddisk irqs
		work with Linux/CATS.
20051113	Some more generalizations of the PCI subsystem.
		Finally took the time to add a hack for SCSI CDROM TOCs; this
		enables OpenBSD to use partition 'a' (as needed by the OpenBSD
		installer), and Windows NT's installer to get a bit further.
		Also fixing dev_wdc to allow Linux to detect ATAPI CDROMs.
		Continuing on the DEC 21143.
20051114	Minor ARM dyntrans tweaks; ARM cmps+branch optimization when
		comparing with 0, and generalizing the xchg instr. comb.
		Adding disassembly of ARM mrrc/mcrr and q{,d}{add,sub}.
20051115	Continuing on various PPC things (BATs, other address trans-
		lation things, various loads/stores, BeBox emulation, etc.).
		Beginning to work on PPC interrupt/exception support.
20051116	Factoring out some code which initializes legacy ISA devices
		from those machines that use them (bus_isa).
		Continuing on PPC interrupt/exception support.
20051117	Minor Malta fixes: RTC year offset = 80, disabling a speed hack
		which caused NetBSD to detect a too fast cpu, and adding a new
		hack to make Linux detect a faster cpu.
		Continuing on the Artesyn PM/PPC emulation mode.
		Adding an Algor emulation skeleton (P4032 and P5064);
		implementing some of the basics.
		Continuing on PPC emulation in general; usage of unimplemented
		SPRs is now easier to track, continuing on memory/exception
		related issues, etc.
20051118	More work on PPC emulation (tgpr0..3, exception handling,
		memory stuff, syscalls, etc.).
20051119	Changing the ARM dyntrans code to mostly use cpu->pc, and not
		necessarily use arm reg 15. Seems to work.
		Various PPC updates; continuing on the PReP emulation mode.
20051120	Adding a workaround/hack to dev_mc146818 to allow NetBSD/prep
		to detect the clock.
20051121	More cleanup of the PCI bus (memory and I/O bases, etc).
		Continuing on various PPC things (decrementer and timebase,
		WDCs on obio (on PReP) use irq 13, not 14/15).
20051122	Continuing on the CPC700 controller (interrupts etc) for PMPPC,
		and on PPC stuff in general.
		Finally! After some bug fixes to the virtual to physical addr
		translation, NetBSD/{prep,pmppc} 2.1 reach userland and are
		stable enough to be interacted with.
		More PCI updates; reverse-endian device access for PowerPC etc.
20051123	Generalizing the IEEE floating point subsystem (moving it out
		from src/cpus/cpu_mips_coproc.c into a new src/float_emul.c).
		Input via slave xterms was sometimes not really working; fixing
		this for ns16550, and a warning message is now displayed if
		multiple non-xterm consoles are active.
		Adding some PPC floating point support, etc.
		Various interrupt related updates (dev_wdc, _ns16550, _8259,
		and the isa32 common code in machine.c).
		NetBSD/prep can now be installed! :-) (Well, with some manual
		commands necessary before running sysinst.) Updating the
		documentation and various other things to reflect this.
20051124	Various minor documentation updates.
		Continuing the work on the DEC 21143 NIC.
20051125	LOTS of work on the 21143. Both OpenBSD and NetBSD work fine
		with it now, except that OpenBSD sometimes gives a time-out
		warning.
		Minor documentation updates.

==============  RELEASE 0.3.7  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26