/[gxemul]/trunk/src/cpus/cpu_alpha.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_alpha.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 38 - (show annotations)
Mon Oct 8 16:21:53 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 17777 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1515 2007/04/14 05:39:46 debug Exp $
20070324	Adding a "--debug" option to the configure script, to disable
		optimizations in unstable development builds.
		Moving out SCSI-specific stuff from diskimage.c into a new
		diskimage_scsicmd.c.
		Applying Hĺvard Eidnes' patch for SCSICDROM_READ_DISKINFO and
		SCSICDROM_READ_TRACKINFO. (Not really tested yet.)
		Implementing disk image "overlays" (to allow simple roll-back
		to previous disk state). Adding a 'V' disk flag for this, and
		updating the man page and misc.html.
20070325	Stability fix to cpu_dyntrans.c, when multiple physical pages
		share the same initial table entry. (The ppp == NULL check
		should be physpage_ofs == 0.) Bug found by analysing GXemul
		against a version patched for Godson.
		Fixing a second occurance of the same problem (also in
		cpu_dyntrans.c).
		Fixing a MAJOR physical page leak in cpu_dyntrans.c; pages
		weren't _added_ to the set of translated pages, they _replaced_
		all previous pages. It's amazing that this bug has been able
		to live for this long. (Triggered when emulating >128MB RAM.)
20070326	Removing the GDB debugging stub support; it was too hackish
		and ugly.
20070328	Moving around some native code generation skeleton code.
20070329	The -lm check in the configure script now also checks for sin()
		in addition to sqrt(). (Thanks to Nigel Horne for noticing that
		sqrt was not enough on Fedora Core 6.) (Not verified yet.)
20070330	Fixing an indexing bug in dev_sh4.c, found by using gcc version
		4.3.0 20070323.
20070331	Some more experimentation with native code generation.
20070404	Attempting to fix some more SH4 SCIF interrupt bugs; rewriting
		the SH interrupt assertion/deassertion code somewhat.
20070410	Splitting src/file.c into separate files in src/file/.
		Cleanup: Removing the dummy TS7200, Walnut, PB1000, and
		Meshcube emulation modes, and dev_epcom and dev_au1x00.
		Removing the experimental CHIP8/RCA180x code; it wasn't really
		working much lately, anyway. It was fun while it lasted.
		Also removing the experimental Transputer CPU support.
20070412	Moving the section about how the dynamic translation system
		works from intro.html to a separate translation.html file.
		Minor SH fixes; attempting to get OpenBSD/landisk to run
		without randomly bugging out, but no success yet.
20070413	SH SCI (serial bit interface) should now work together with a
		(new) RS5C313 clock device (for Landisk emulation).
20070414	Moving Redhat/MIPS down from supported to experimental, in
		guestoses.html.
		Preparing for a new release; doing some regression testing etc.

==============  RELEASE 0.4.5  ==============


1 /*
2 * Copyright (C) 2005-2007 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_alpha.c,v 1.25 2007/03/26 02:01:35 debug Exp $
29 *
30 * Alpha CPU emulation.
31 *
32 * TODO: Many things.
33 *
34 * See http://www.eecs.harvard.edu/~nr/toolkit/specs/alpha.html for info
35 * on instruction formats etc.
36 */
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <ctype.h>
42
43 #include "cpu.h"
44 #include "machine.h"
45 #include "memory.h"
46 #include "misc.h"
47 #include "settings.h"
48 #include "symbol.h"
49
50 #define DYNTRANS_8K
51 #define DYNTRANS_PAGESIZE 8192
52 #include "tmp_alpha_head.c"
53
54
55 /* Alpha symbolic register names: */
56 static char *alpha_regname[N_ALPHA_REGS] = ALPHA_REG_NAMES;
57
58
59 /*
60 * alpha_cpu_new():
61 *
62 * Create a new Alpha CPU object by filling the CPU struct.
63 * Return 1 on success, 0 if cpu_type_name isn't a valid Alpha processor.
64 */
65 int alpha_cpu_new(struct cpu *cpu, struct memory *mem,
66 struct machine *machine, int cpu_id, char *cpu_type_name)
67 {
68 int i = 0;
69 struct alpha_cpu_type_def cpu_type_defs[] = ALPHA_CPU_TYPE_DEFS;
70
71 /* Scan the cpu_type_defs list for this cpu type: */
72 while (cpu_type_defs[i].name != NULL) {
73 if (strcasecmp(cpu_type_defs[i].name, cpu_type_name) == 0) {
74 break;
75 }
76 i++;
77 }
78 if (cpu_type_defs[i].name == NULL)
79 return 0;
80
81 cpu->is_32bit = 0;
82 cpu->byte_order = EMUL_LITTLE_ENDIAN;
83
84 cpu->memory_rw = alpha_memory_rw;
85 cpu->run_instr = alpha_run_instr;
86 cpu->translate_v2p = alpha_translate_v2p;
87 cpu->update_translation_table = alpha_update_translation_table;
88 cpu->invalidate_translation_caches =
89 alpha_invalidate_translation_caches;
90 cpu->invalidate_code_translation = alpha_invalidate_code_translation;
91
92 cpu->cd.alpha.cpu_type = cpu_type_defs[i];
93
94 /* Only show name and caches etc for CPU nr 0: */
95 if (cpu_id == 0) {
96 debug("%s", cpu->name);
97 }
98
99 cpu->cd.alpha.r[ALPHA_SP] = 0xfffffc000000ff00ULL;
100
101 /* Set up dummy kentry pointers to something which crashes
102 the machine: */
103 store_32bit_word(cpu, 0x10010, 0x3fffffc);
104 for (i=0; i<N_ALPHA_KENTRY; i++)
105 cpu->cd.alpha.kentry[i] = 0x10010;
106
107 /* Bogus initial context (will be overwritten on first
108 context switch): */
109 cpu->cd.alpha.ctx = 0x10100;
110
111 CPU_SETTINGS_ADD_REGISTER64("pc", cpu->pc);
112 for (i=0; i<N_ALPHA_REGS; i++)
113 CPU_SETTINGS_ADD_REGISTER64(alpha_regname[i],
114 cpu->cd.alpha.r[i]);
115
116 return 1;
117 }
118
119
120 /*
121 * alpha_cpu_dumpinfo():
122 */
123 void alpha_cpu_dumpinfo(struct cpu *cpu)
124 {
125 /* TODO */
126 debug("\n");
127 }
128
129
130 /*
131 * alpha_cpu_list_available_types():
132 *
133 * Print a list of available Alpha CPU types.
134 */
135 void alpha_cpu_list_available_types(void)
136 {
137 int i, j;
138 struct alpha_cpu_type_def tdefs[] = ALPHA_CPU_TYPE_DEFS;
139
140 i = 0;
141 while (tdefs[i].name != NULL) {
142 debug("%s", tdefs[i].name);
143 for (j=13 - strlen(tdefs[i].name); j>0; j--)
144 debug(" ");
145 i++;
146 if ((i % 4) == 0 || tdefs[i].name == NULL)
147 debug("\n");
148 }
149 }
150
151
152 /*
153 * alpha_cpu_register_dump():
154 *
155 * Dump cpu registers in a relatively readable format.
156 *
157 * gprs: set to non-zero to dump GPRs and some special-purpose registers.
158 * coprocs: set bit 0..3 to dump registers in coproc 0..3.
159 */
160 void alpha_cpu_register_dump(struct cpu *cpu, int gprs, int coprocs)
161 {
162 char *symbol;
163 uint64_t offset;
164 int i, x = cpu->cpu_id;
165
166 if (gprs) {
167 symbol = get_symbol_name(&cpu->machine->symbol_context,
168 cpu->pc, &offset);
169 debug("cpu%i:\t pc = 0x%016"PRIx64, x, (uint64_t) cpu->pc);
170 debug(" <%s>\n", symbol != NULL? symbol : " no symbol ");
171 for (i=0; i<N_ALPHA_REGS; i++) {
172 int r = (i >> 1) + ((i & 1) << 4);
173 if ((i % 2) == 0)
174 debug("cpu%i:\t", x);
175 if (r != ALPHA_ZERO)
176 debug("%3s = 0x%016"PRIx64, alpha_regname[r],
177 (uint64_t) cpu->cd.alpha.r[r]);
178 debug((i % 2) == 1? "\n" : " ");
179 }
180 }
181 }
182
183
184 /*
185 * alpha_cpu_tlbdump():
186 *
187 * Called from the debugger to dump the TLB in a readable format.
188 * x is the cpu number to dump, or -1 to dump all CPUs.
189 *
190 * If rawflag is nonzero, then the TLB contents isn't formated nicely,
191 * just dumped.
192 */
193 void alpha_cpu_tlbdump(struct machine *m, int x, int rawflag)
194 {
195 }
196
197
198 /*
199 * alpha_print_imm16_disp():
200 *
201 * Used internally by alpha_cpu_disassemble_instr().
202 */
203 static void alpha_print_imm16_disp(int imm, int rb)
204 {
205 imm = (int16_t)imm;
206
207 if (imm < 0) {
208 debug("-");
209 imm = -imm;
210 }
211 if (imm <= 256)
212 debug("%i", imm);
213 else
214 debug("0x%x", imm);
215 if (rb != ALPHA_ZERO)
216 debug("(%s)", alpha_regname[rb]);
217 }
218
219
220 /*
221 * alpha_cpu_disassemble_instr():
222 *
223 * Convert an instruction word into human readable format, for instruction
224 * tracing.
225 *
226 * If running is 1, cpu->pc should be the address of the instruction.
227 *
228 * If running is 0, things that depend on the runtime environment (eg.
229 * register contents) will not be shown, and addr will be used instead of
230 * cpu->pc for relative addresses.
231 */
232 int alpha_cpu_disassemble_instr(struct cpu *cpu, unsigned char *ib,
233 int running, uint64_t dumpaddr)
234 {
235 uint32_t iw;
236 uint64_t offset, tmp;
237 int opcode, ra, rb, func, rc, imm, floating, rbrc = 0, indir = 0;
238 char *symbol, *mnem = NULL;
239 char palcode_name[30];
240
241 if (running)
242 dumpaddr = cpu->pc;
243
244 symbol = get_symbol_name(&cpu->machine->symbol_context,
245 dumpaddr, &offset);
246 if (symbol != NULL && offset == 0)
247 debug("<%s>\n", symbol);
248
249 if (cpu->machine->ncpus > 1 && running)
250 debug("cpu%i:\t", cpu->cpu_id);
251
252 debug("%016"PRIx64": ", (uint64_t) dumpaddr);
253
254 iw = ib[0] + (ib[1]<<8) + (ib[2]<<16) + (ib[3]<<24);
255 debug("%08x\t", (int)iw);
256
257 opcode = iw >> 26;
258 ra = (iw >> 21) & 31;
259 rb = (iw >> 16) & 31;
260 func = (iw >> 5) & 0x7ff;
261 rc = iw & 31;
262 imm = iw & 0xffff;
263
264 switch (opcode) {
265 case 0x00:
266 alpha_palcode_name(iw & 0x3ffffff, palcode_name,
267 sizeof(palcode_name));
268 debug("call_pal %s\n", palcode_name);
269 break;
270 case 0x08:
271 case 0x09:
272 debug("lda%s\t%s,", opcode == 9? "h" : "", alpha_regname[ra]);
273 alpha_print_imm16_disp(imm, rb);
274 debug("\n");
275 break;
276 case 0x0a:
277 case 0x0b:
278 case 0x0c:
279 case 0x0d:
280 case 0x0e:
281 case 0x0f:
282 case 0x20:
283 case 0x21:
284 case 0x22:
285 case 0x23:
286 case 0x24:
287 case 0x25:
288 case 0x26:
289 case 0x27:
290 case 0x28:
291 case 0x29:
292 case 0x2a:
293 case 0x2b:
294 case 0x2c:
295 case 0x2d:
296 case 0x2e:
297 case 0x2f:
298 floating = 0;
299 switch (opcode) {
300 case 0x0a: mnem = "ldbu"; break;
301 case 0x0b: mnem = "ldq_u"; break;
302 case 0x0c: mnem = "ldwu"; break;
303 case 0x0d: mnem = "stw"; break;
304 case 0x0e: mnem = "stb"; break;
305 case 0x0f: mnem = "stq_u"; break;
306 case 0x20: mnem = "ldf"; floating = 1; break;
307 case 0x21: mnem = "ldg"; floating = 1; break;
308 case 0x22: mnem = "lds"; floating = 1; break;
309 case 0x23: mnem = "ldt"; floating = 1; break;
310 case 0x24: mnem = "stf"; floating = 1; break;
311 case 0x25: mnem = "stg"; floating = 1; break;
312 case 0x26: mnem = "sts"; floating = 1; break;
313 case 0x27: mnem = "stt"; floating = 1; break;
314 case 0x28: mnem = "ldl"; break;
315 case 0x29: mnem = "ldq"; break;
316 case 0x2a: mnem = "ldl_l"; break;
317 case 0x2b: mnem = "ldq_l"; break;
318 case 0x2c: mnem = "stl"; break;
319 case 0x2d: mnem = "stq"; break;
320 case 0x2e: mnem = "stl_c"; break;
321 case 0x2f: mnem = "stq_c"; break;
322 }
323 if (opcode == 0x0b && ra == ALPHA_ZERO) {
324 debug("unop");
325 } else {
326 debug("%s\t", mnem);
327 if (floating)
328 debug("f%i,", ra);
329 else
330 debug("%s,", alpha_regname[ra]);
331 alpha_print_imm16_disp(imm, rb);
332 }
333 debug("\n");
334 break;
335 case 0x10:
336 switch (func & 0x7f) {
337 case 0x00: mnem = "addl"; break;
338 case 0x02: mnem = "s4addl"; break;
339 case 0x09: mnem = "subl"; break;
340 case 0x0b: mnem = "s4subl"; break;
341 case 0x0f: mnem = "cmpbge"; break;
342 case 0x12: mnem = "s8addl"; break;
343 case 0x1b: mnem = "s8subl"; break;
344 case 0x1d: mnem = "cmpult"; break;
345 case 0x20: mnem = "addq"; break;
346 case 0x22: mnem = "s4addq"; break;
347 case 0x29: mnem = "subq"; break;
348 case 0x2b: mnem = "s4subq"; break;
349 case 0x2d: mnem = "cmpeq"; break;
350 case 0x32: mnem = "s8addq"; break;
351 case 0x3b: mnem = "s8subq"; break;
352 case 0x3d: mnem = "cmpule"; break;
353 case 0x40: mnem = "addl/v"; break;
354 case 0x49: mnem = "subl/v"; break;
355 case 0x4d: mnem = "cmplt"; break;
356 case 0x60: mnem = "addq/v"; break;
357 case 0x69: mnem = "subq/v"; break;
358 case 0x6d: mnem = "cmple"; break;
359 default:debug("UNIMPLEMENTED opcode 0x%x func 0x%x\n",
360 opcode, func);
361 }
362 if (mnem == NULL)
363 break;
364 if (func & 0x80)
365 debug("%s\t%s,0x%x,%s\n", mnem,
366 alpha_regname[ra], (rb << 3) + (func >> 8),
367 alpha_regname[rc]);
368 else
369 debug("%s\t%s,%s,%s\n", mnem, alpha_regname[ra],
370 alpha_regname[rb], alpha_regname[rc]);
371 break;
372 case 0x11:
373 switch (func & 0x7f) {
374 case 0x000: mnem = "and"; break;
375 case 0x008: mnem = "andnot"; break;
376 case 0x014: mnem = "cmovlbs"; break;
377 case 0x016: mnem = "cmovlbc"; break;
378 case 0x020: mnem = "or"; break;
379 case 0x024: mnem = "cmoveq"; break;
380 case 0x026: mnem = "cmovne"; break;
381 case 0x028: mnem = "ornot"; break;
382 case 0x040: mnem = "xor"; break;
383 case 0x044: mnem = "cmovlt"; break;
384 case 0x046: mnem = "cmovge"; break;
385 case 0x048: mnem = "eqv"; break;
386 case 0x061: mnem = "amask"; break;
387 case 0x064: mnem = "cmovle"; break;
388 case 0x066: mnem = "cmovgt"; break;
389 case 0x06c: mnem = "implver"; break;
390 default:debug("UNIMPLEMENTED opcode 0x%x func 0x%x\n",
391 opcode, func);
392 }
393 if (mnem == NULL)
394 break;
395 /* Special cases: "nop" etc: */
396 if (func == 0x020 && rc == ALPHA_ZERO)
397 debug("nop\n");
398 else if (func == 0x020 && (ra == ALPHA_ZERO
399 || rb == ALPHA_ZERO)) {
400 if (ra == ALPHA_ZERO && rb == ALPHA_ZERO)
401 debug("clr\t%s\n", alpha_regname[rc]);
402 else if (ra == ALPHA_ZERO)
403 debug("mov\t%s,%s\n", alpha_regname[rb],
404 alpha_regname[rc]);
405 else
406 debug("mov\t%s,%s\n", alpha_regname[ra],
407 alpha_regname[rc]);
408 } else if (func == 0x1ec) {
409 /* implver */
410 debug("%s\t%s\n", mnem, alpha_regname[rc]);
411 } else if (func & 0x80)
412 debug("%s\t%s,0x%x,%s\n", mnem,
413 alpha_regname[ra], (rb << 3) + (func >> 8),
414 alpha_regname[rc]);
415 else
416 debug("%s\t%s,%s,%s\n", mnem, alpha_regname[ra],
417 alpha_regname[rb], alpha_regname[rc]);
418 break;
419 case 0x12:
420 switch (func & 0x7f) {
421 case 0x02: mnem = "mskbl"; break;
422 case 0x06: mnem = "extbl"; break;
423 case 0x0b: mnem = "insbl"; break;
424 case 0x12: mnem = "mskwl"; break;
425 case 0x16: mnem = "extwl"; break;
426 case 0x1b: mnem = "inswl"; break;
427 case 0x22: mnem = "mskll"; break;
428 case 0x26: mnem = "extll"; break;
429 case 0x2b: mnem = "insll"; break;
430 case 0x30: mnem = "zap"; break;
431 case 0x31: mnem = "zapnot"; break;
432 case 0x32: mnem = "mskql"; break;
433 case 0x34: mnem = "srl"; break;
434 case 0x36: mnem = "extql"; break;
435 case 0x39: mnem = "sll"; break;
436 case 0x3b: mnem = "insql"; break;
437 case 0x3c: mnem = "sra"; break;
438 case 0x52: mnem = "mskwh"; break;
439 case 0x57: mnem = "inswh"; break;
440 case 0x5a: mnem = "extwh"; break;
441 case 0x62: mnem = "msklh"; break;
442 case 0x67: mnem = "inslh"; break;
443 case 0x6a: mnem = "extlh"; break;
444 case 0x72: mnem = "mskqh"; break;
445 case 0x77: mnem = "insqh"; break;
446 case 0x7a: mnem = "extqh"; break;
447 default:debug("UNIMPLEMENTED opcode 0x%x func 0x%x\n",
448 opcode, func);
449 }
450 if (mnem == NULL)
451 break;
452 if (func & 0x80)
453 debug("%s\t%s,0x%x,%s\n", mnem,
454 alpha_regname[ra], (rb << 3) + (func >> 8),
455 alpha_regname[rc]);
456 else
457 debug("%s\t%s,%s,%s\n", mnem, alpha_regname[ra],
458 alpha_regname[rb], alpha_regname[rc]);
459 break;
460 case 0x13:
461 switch (func & 0x7f) {
462 case 0x00: mnem = "mull"; break;
463 case 0x20: mnem = "mulq"; break;
464 case 0x30: mnem = "umulh"; break;
465 case 0x40: mnem = "mull/v"; break;
466 case 0x60: mnem = "mulq/v"; break;
467 default:debug("UNIMPLEMENTED opcode 0x%x func 0x%x\n",
468 opcode, func);
469 }
470 if (mnem == NULL)
471 break;
472 if (func & 0x80)
473 debug("%s\t%s,0x%x,%s\n", mnem,
474 alpha_regname[ra], (rb << 3) + (func >> 8),
475 alpha_regname[rc]);
476 else
477 debug("%s\t%s,%s,%s\n", mnem, alpha_regname[ra],
478 alpha_regname[rb], alpha_regname[rc]);
479 break;
480 case 0x16:
481 switch (func & 0x7ff) {
482 case 0x02f: mnem = "cvttq/c"; rbrc = 1; break;
483 case 0x080: mnem = "adds"; break;
484 case 0x081: mnem = "subs"; break;
485 case 0x082: mnem = "muls"; break;
486 case 0x083: mnem = "XXXx083"; break;
487 case 0x0a0: mnem = "addt"; break;
488 case 0x0a1: mnem = "subt"; break;
489 case 0x0a2: mnem = "mult"; break;
490 case 0x0a3: mnem = "divt"; break;
491 case 0x0a5: mnem = "cmpteq"; break;
492 case 0x0a6: mnem = "cmptlt"; break;
493 case 0x0a7: mnem = "cmptle"; break;
494 case 0x0be: mnem = "cvtqt"; rbrc = 1; break;
495 default:debug("UNIMPLEMENTED opcode 0x%x func 0x%x\n",
496 opcode, func);
497 }
498 if (mnem == NULL)
499 break;
500 if (rbrc)
501 debug("%s\tf%i,f%i\n", mnem, rb, rc);
502 else
503 debug("%s\tf%i,f%i,f%i\n", mnem, ra, rb, rc);
504 break;
505 case 0x17:
506 switch (func & 0x7ff) {
507 case 0x020: mnem = "fabs"; rbrc = 1; break;
508 case 0x021: mnem = "fneg"; rbrc = 1; break;
509 default:debug("UNIMPLEMENTED opcode 0x%x func 0x%x\n",
510 opcode, func);
511 }
512 if (mnem == NULL)
513 break;
514 if ((func & 0x7ff) == 0x020 && ra == 31 && rb == 31)
515 debug("fclr\tf%i\n", rc);
516 else if (rbrc)
517 debug("%s\tf%i,f%i\n", mnem, rb, rc);
518 else
519 debug("%s\tf%i,f%i,f%i\n", mnem, ra, rb, rc);
520 break;
521 case 0x18:
522 switch (iw & 0xffff) {
523 case 0x0000: mnem = "trapb"; break;
524 case 0x0400: mnem = "excb"; break;
525 case 0x4000: mnem = "mb"; break;
526 case 0x4400: mnem = "wmb"; break;
527 case 0x8000: mnem = "fetch"; indir = 1; break;
528 case 0xa000: mnem = "fetch_m"; indir = 1; break;
529 case 0xc000: mnem = "rpcc"; break;
530 case 0xe000: mnem = "rc"; break;
531 case 0xe800: mnem = "ecb"; indir = 1; break;
532 case 0xf000: mnem = "rs"; break;
533 case 0xf800: mnem = "wh64"; indir = 1; break;
534 default:debug("UNIMPLEMENTED opcode 0x%x func 0x%x\n",
535 opcode, func);
536 }
537 if (mnem == NULL)
538 break;
539 debug("%s", mnem);
540 if ((iw & 0xffff) >= 0x8000) {
541 debug("\t");
542 if (indir)
543 debug("(%s)", alpha_regname[rb]);
544 else
545 debug("%s", alpha_regname[ra]);
546 }
547 debug("\n");
548 break;
549 case 0x1a:
550 tmp = iw & 0x3fff;
551 if (tmp & 0x2000)
552 tmp |= 0xffffffffffffc000ULL;
553 tmp <<= 2;
554 tmp += dumpaddr + sizeof(uint32_t);
555 switch ((iw >> 14) & 3) {
556 case 0:
557 case 1: if (((iw >> 14) & 3) == 0)
558 debug("jmp");
559 else
560 debug("jsr");
561 debug("\t%s,", alpha_regname[ra]);
562 debug("(%s),", alpha_regname[rb]);
563 debug("0x%"PRIx64, (uint64_t) tmp);
564 symbol = get_symbol_name(&cpu->machine->symbol_context,
565 tmp, &offset);
566 if (symbol != NULL)
567 debug("\t<%s>", symbol);
568 break;
569 case 2: debug("ret");
570 break;
571 default:fatal("unimpl JSR!");
572 }
573 debug("\n");
574 break;
575 case 0x30:
576 case 0x34:
577 tmp = iw & 0x1fffff;
578 if (tmp & 0x100000)
579 tmp |= 0xffffffffffe00000ULL;
580 tmp <<= 2;
581 tmp += dumpaddr + sizeof(uint32_t);
582 debug("%s\t", opcode==0x30? "br" : "bsr");
583 if (ra != ALPHA_ZERO)
584 debug("%s,", alpha_regname[ra]);
585 debug("0x%"PRIx64, (uint64_t) tmp);
586 symbol = get_symbol_name(&cpu->machine->symbol_context,
587 tmp, &offset);
588 if (symbol != NULL)
589 debug("\t<%s>", symbol);
590 debug("\n");
591 break;
592 case 0x31:
593 case 0x35:
594 case 0x38:
595 case 0x39:
596 case 0x3a:
597 case 0x3b:
598 case 0x3c:
599 case 0x3d:
600 case 0x3e:
601 case 0x3f:
602 floating = 0;
603 switch (opcode) {
604 case 0x31: mnem = "fbeq"; floating = 1; break;
605 case 0x35: mnem = "fbne"; floating = 1; break;
606 case 0x38: mnem = "blbc"; break;
607 case 0x39: mnem = "beq"; break;
608 case 0x3a: mnem = "blt"; break;
609 case 0x3b: mnem = "ble"; break;
610 case 0x3c: mnem = "blbs"; break;
611 case 0x3d: mnem = "bne"; break;
612 case 0x3e: mnem = "bge"; break;
613 case 0x3f: mnem = "bgt"; break;
614 }
615 tmp = iw & 0x1fffff;
616 if (tmp & 0x100000)
617 tmp |= 0xffffffffffe00000ULL;
618 tmp <<= 2;
619 tmp += dumpaddr + sizeof(uint32_t);
620 debug("%s\t", mnem);
621 if (floating)
622 debug("f%i,", ra);
623 else
624 debug("%s,", alpha_regname[ra]);
625 debug("0x%"PRIx64, (uint64_t) tmp);
626 symbol = get_symbol_name(&cpu->machine->symbol_context,
627 tmp, &offset);
628 if (symbol != NULL)
629 debug("\t<%s>", symbol);
630 debug("\n");
631 break;
632 default:debug("UNIMPLEMENTED opcode 0x%x\n", opcode);
633 }
634
635 return sizeof(uint32_t);
636 }
637
638
639 #define MEMORY_RW alpha_userland_memory_rw
640 #define MEM_ALPHA
641 #define MEM_USERLAND
642 #include "../memory_rw.c"
643 #undef MEM_USERLAND
644 #undef MEM_ALPHA
645 #undef MEMORY_RW
646
647
648 #include "tmp_alpha_tail.c"
649

  ViewVC Help
Powered by ViewVC 1.1.26