/[gxemul]/upstream/0.3.5/src/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 /upstream/0.3.5/src/cpu_alpha.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26