]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/microblaze/interp.c
sim: replace CIA_{GET,SET} with CPU_PC_{GET,SET}
[thirdparty/binutils-gdb.git] / sim / microblaze / interp.c
CommitLineData
bd30e45a 1/* Simulator for Xilinx MicroBlaze processor
32d0add0 2 Copyright 2009-2015 Free Software Foundation, Inc.
bd30e45a
ME
3
4 This file is part of GDB, the GNU debugger.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
3fd725ef 8 the Free Software Foundation; either version 3 of the License, or
bd30e45a
ME
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
51b318de 17 along with this program; if not, see <http://www.gnu.org/licenses/>. */
bd30e45a 18
8fe6640e 19#include "config.h"
bd30e45a 20#include <signal.h>
dc049bf4
MF
21#include <stdlib.h>
22#include <string.h>
dc049bf4 23#include <unistd.h>
bd30e45a
ME
24#include "bfd.h"
25#include "gdb/callback.h"
26#include "libiberty.h"
27#include "gdb/remote-sim.h"
2b4bc832 28
bd30e45a 29#include "sim-main.h"
2b4bc832
MF
30#include "sim-options.h"
31
419c2fda 32#include "microblaze-dis.h"
bd30e45a 33
2b4bc832 34#define target_big_endian (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
bd30e45a 35
feb703b3 36static unsigned long
bd30e45a
ME
37microblaze_extract_unsigned_integer (unsigned char *addr, int len)
38{
39 unsigned long retval;
40 unsigned char *p;
41 unsigned char *startaddr = (unsigned char *)addr;
42 unsigned char *endaddr = startaddr + len;
43
44 if (len > (int) sizeof (unsigned long))
45 printf ("That operation is not available on integers of more than "
3e95021c 46 "%zu bytes.", sizeof (unsigned long));
bd30e45a
ME
47
48 /* Start at the most significant end of the integer, and work towards
49 the least significant. */
50 retval = 0;
51
52 if (!target_big_endian)
53 {
54 for (p = endaddr; p > startaddr;)
55 retval = (retval << 8) | * -- p;
56 }
57 else
58 {
59 for (p = startaddr; p < endaddr;)
60 retval = (retval << 8) | * p ++;
61 }
62
63 return retval;
64}
65
feb703b3 66static void
bd30e45a
ME
67microblaze_store_unsigned_integer (unsigned char *addr, int len,
68 unsigned long val)
69{
70 unsigned char *p;
71 unsigned char *startaddr = (unsigned char *)addr;
72 unsigned char *endaddr = startaddr + len;
73
74 if (!target_big_endian)
75 {
76 for (p = startaddr; p < endaddr;)
77 {
78 *p++ = val & 0xff;
79 val >>= 8;
80 }
81 }
82 else
83 {
84 for (p = endaddr; p > startaddr;)
85 {
86 *--p = val & 0xff;
87 val >>= 8;
88 }
89 }
90}
91
2b4bc832 92/* TODO: Convert to common tracing framework. */
bd30e45a
ME
93static int issue_messages = 0;
94
bd30e45a 95static void /* INLINE */
2b4bc832 96wbat (SIM_CPU *cpu, word x, word v)
bd30e45a
ME
97{
98 if (((uword)x) >= CPU.msize)
99 {
100 if (issue_messages)
101 fprintf (stderr, "byte write to 0x%x outside memory range\n", x);
102
103 CPU.exception = SIGSEGV;
104 }
105 else
106 {
107 unsigned char *p = CPU.memory + x;
108 p[0] = v;
109 }
110}
111
112static void /* INLINE */
2b4bc832 113wlat (SIM_CPU *cpu, word x, word v)
bd30e45a
ME
114{
115 if (((uword)x) >= CPU.msize)
116 {
117 if (issue_messages)
118 fprintf (stderr, "word write to 0x%x outside memory range\n", x);
119
120 CPU.exception = SIGSEGV;
121 }
122 else
123 {
124 if ((x & 3) != 0)
125 {
126 if (issue_messages)
127 fprintf (stderr, "word write to unaligned memory address: 0x%x\n", x);
128
129 CPU.exception = SIGBUS;
130 }
131 else if (!target_big_endian)
132 {
133 unsigned char *p = CPU.memory + x;
134 p[3] = v >> 24;
135 p[2] = v >> 16;
136 p[1] = v >> 8;
137 p[0] = v;
138 }
139 else
140 {
141 unsigned char *p = CPU.memory + x;
142 p[0] = v >> 24;
143 p[1] = v >> 16;
144 p[2] = v >> 8;
145 p[3] = v;
146 }
147 }
148}
149
150static void /* INLINE */
2b4bc832 151what (SIM_CPU *cpu, word x, word v)
bd30e45a
ME
152{
153 if (((uword)x) >= CPU.msize)
154 {
155 if (issue_messages)
156 fprintf (stderr, "short write to 0x%x outside memory range\n", x);
157
158 CPU.exception = SIGSEGV;
159 }
160 else
161 {
162 if ((x & 1) != 0)
163 {
164 if (issue_messages)
165 fprintf (stderr, "short write to unaligned memory address: 0x%x\n",
166 x);
167
168 CPU.exception = SIGBUS;
169 }
170 else if (!target_big_endian)
171 {
172 unsigned char *p = CPU.memory + x;
173 p[1] = v >> 8;
174 p[0] = v;
175 }
176 else
177 {
178 unsigned char *p = CPU.memory + x;
179 p[0] = v >> 8;
180 p[1] = v;
181 }
182 }
183}
184
185/* Read functions. */
186static int /* INLINE */
2b4bc832 187rbat (SIM_CPU *cpu, word x)
bd30e45a
ME
188{
189 if (((uword)x) >= CPU.msize)
190 {
191 if (issue_messages)
192 fprintf (stderr, "byte read from 0x%x outside memory range\n", x);
193
194 CPU.exception = SIGSEGV;
195 return 0;
196 }
197 else
198 {
199 unsigned char *p = CPU.memory + x;
200 return p[0];
201 }
202}
203
204static int /* INLINE */
2b4bc832 205rlat (SIM_CPU *cpu, word x)
bd30e45a
ME
206{
207 if (((uword) x) >= CPU.msize)
208 {
209 if (issue_messages)
210 fprintf (stderr, "word read from 0x%x outside memory range\n", x);
211
212 CPU.exception = SIGSEGV;
213 return 0;
214 }
215 else
216 {
217 if ((x & 3) != 0)
218 {
219 if (issue_messages)
220 fprintf (stderr, "word read from unaligned address: 0x%x\n", x);
221
222 CPU.exception = SIGBUS;
223 return 0;
224 }
225 else if (! target_big_endian)
226 {
227 unsigned char *p = CPU.memory + x;
228 return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
229 }
230 else
231 {
232 unsigned char *p = CPU.memory + x;
233 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
234 }
235 }
236}
237
238static int /* INLINE */
2b4bc832 239rhat (SIM_CPU *cpu, word x)
bd30e45a
ME
240{
241 if (((uword)x) >= CPU.msize)
242 {
243 if (issue_messages)
244 fprintf (stderr, "short read from 0x%x outside memory range\n", x);
245
246 CPU.exception = SIGSEGV;
247 return 0;
248 }
249 else
250 {
251 if ((x & 1) != 0)
252 {
253 if (issue_messages)
254 fprintf (stderr, "short read from unaligned address: 0x%x\n", x);
255
256 CPU.exception = SIGBUS;
257 return 0;
258 }
259 else if (!target_big_endian)
260 {
261 unsigned char *p = CPU.memory + x;
262 return (p[1] << 8) | p[0];
263 }
264 else
265 {
266 unsigned char *p = CPU.memory + x;
267 return (p[0] << 8) | p[1];
268 }
269 }
270}
271
2b4bc832 272/* TODO: Delete all sim_size and use common memory functions. */
bd30e45a
ME
273/* Default to a 8 Mbyte (== 2^23) memory space. */
274static int sim_memory_size = 1 << 23;
275
276#define MEM_SIZE_FLOOR 64
2b4bc832
MF
277static void
278sim_size (SIM_CPU *cpu, int size)
bd30e45a
ME
279{
280 sim_memory_size = size;
281 CPU.msize = sim_memory_size;
282
283 if (CPU.memory)
284 free (CPU.memory);
285
286 CPU.memory = (unsigned char *) calloc (1, CPU.msize);
287
288 if (!CPU.memory)
289 {
290 if (issue_messages)
291 fprintf (stderr,
ba8e7d1e 292 "Not enough VM for simulation of %ld bytes of RAM\n",
bd30e45a
ME
293 CPU.msize);
294
295 CPU.msize = 1;
296 CPU.memory = (unsigned char *) calloc (1, 1);
297 }
298}
299
300static void
2b4bc832 301init_pointers (SIM_CPU *cpu)
bd30e45a
ME
302{
303 if (CPU.msize != (sim_memory_size))
2b4bc832 304 sim_size (cpu, sim_memory_size);
bd30e45a
ME
305}
306
307static void
2b4bc832 308set_initial_gprs (SIM_CPU *cpu)
bd30e45a
ME
309{
310 int i;
311 long space;
312 unsigned long memsize;
313
2b4bc832 314 init_pointers (cpu);
bd30e45a
ME
315
316 /* Set up machine just out of reset. */
317 PC = 0;
318 MSR = 0;
319
320 memsize = CPU.msize / (1024 * 1024);
321
322 if (issue_messages > 1)
ba8e7d1e 323 fprintf (stderr, "Simulated memory of %ld Mbytes (0x0 .. 0x%08lx)\n",
bd30e45a
ME
324 memsize, CPU.msize - 1);
325
326 /* Clean out the GPRs */
327 for (i = 0; i < 32; i++)
328 CPU.regs[i] = 0;
329 CPU.insts = 0;
330 CPU.cycles = 0;
331 CPU.imm_enable = 0;
bd30e45a
ME
332}
333
bd30e45a
ME
334static int tracing = 0;
335
336void
337sim_resume (SIM_DESC sd, int step, int siggnal)
338{
2b4bc832 339 SIM_CPU *cpu = STATE_CPU (sd, 0);
bd30e45a
ME
340 int needfetch;
341 word inst;
342 enum microblaze_instr op;
bd30e45a
ME
343 int memops;
344 int bonus_cycles;
345 int insts;
346 int w;
347 int cycs;
348 word WLhash;
349 ubyte carry;
350 int imm_unsigned;
351 short ra, rb, rd;
352 long immword;
353 uword oldpc, newpc;
354 short delay_slot_enable;
355 short branch_taken;
356 short num_delay_slot; /* UNUSED except as reqd parameter */
357 enum microblaze_instr_type insn_type;
358
bd30e45a
ME
359 CPU.exception = step ? SIGTRAP : 0;
360
361 memops = 0;
362 bonus_cycles = 0;
363 insts = 0;
ba14f941 364
bd30e45a
ME
365 do
366 {
367 /* Fetch the initial instructions that we'll decode. */
2b4bc832 368 inst = rlat (cpu, PC & 0xFFFFFFFC);
bd30e45a 369
ba14f941 370 op = get_insn_microblaze (inst, &imm_unsigned, &insn_type,
bd30e45a
ME
371 &num_delay_slot);
372
373 if (op == invalid_inst)
374 fprintf (stderr, "Unknown instruction 0x%04x", inst);
375
376 if (tracing)
377 fprintf (stderr, "%.4x: inst = %.4x ", PC, inst);
378
379 rd = GET_RD;
380 rb = GET_RB;
381 ra = GET_RA;
382 /* immword = IMM_W; */
383
384 oldpc = PC;
385 delay_slot_enable = 0;
386 branch_taken = 0;
387 if (op == microblaze_brk)
388 CPU.exception = SIGTRAP;
389 else if (inst == MICROBLAZE_HALT_INST)
390 {
391 CPU.exception = SIGQUIT;
392 insts += 1;
393 bonus_cycles++;
394 }
395 else
396 {
397 switch(op)
398 {
399#define INSTRUCTION(NAME, OPCODE, TYPE, ACTION) \
400 case NAME: \
401 ACTION; \
402 break;
403#include "microblaze.isa"
404#undef INSTRUCTION
405
406 default:
407 CPU.exception = SIGILL;
408 fprintf (stderr, "ERROR: Unknown opcode\n");
409 }
410 /* Make R0 consistent */
411 CPU.regs[0] = 0;
412
413 /* Check for imm instr */
414 if (op == imm)
415 IMM_ENABLE = 1;
416 else
417 IMM_ENABLE = 0;
418
419 /* Update cycle counts */
420 insts ++;
421 if (insn_type == memory_store_inst || insn_type == memory_load_inst)
422 memops++;
423 if (insn_type == mult_inst)
424 bonus_cycles++;
425 if (insn_type == barrel_shift_inst)
426 bonus_cycles++;
427 if (insn_type == anyware_inst)
428 bonus_cycles++;
429 if (insn_type == div_inst)
430 bonus_cycles += 33;
431
432 if ((insn_type == branch_inst || insn_type == return_inst)
ba14f941 433 && branch_taken)
bd30e45a
ME
434 {
435 /* Add an extra cycle for taken branches */
436 bonus_cycles++;
437 /* For branch instructions handle the instruction in the delay slot */
ba14f941 438 if (delay_slot_enable)
bd30e45a
ME
439 {
440 newpc = PC;
441 PC = oldpc + INST_SIZE;
2b4bc832 442 inst = rlat (cpu, PC & 0xFFFFFFFC);
bd30e45a
ME
443 op = get_insn_microblaze (inst, &imm_unsigned, &insn_type,
444 &num_delay_slot);
445 if (op == invalid_inst)
446 fprintf (stderr, "Unknown instruction 0x%04x", inst);
447 if (tracing)
448 fprintf (stderr, "%.4x: inst = %.4x ", PC, inst);
449 rd = GET_RD;
450 rb = GET_RB;
451 ra = GET_RA;
452 /* immword = IMM_W; */
453 if (op == microblaze_brk)
454 {
455 if (issue_messages)
456 fprintf (stderr, "Breakpoint set in delay slot "
457 "(at address 0x%x) will not be honored\n", PC);
458 /* ignore the breakpoint */
459 }
460 else if (insn_type == branch_inst || insn_type == return_inst)
461 {
462 if (issue_messages)
463 fprintf (stderr, "Cannot have branch or return instructions "
464 "in delay slot (at address 0x%x)\n", PC);
465 CPU.exception = SIGILL;
466 }
467 else
468 {
469 switch(op)
470 {
471#define INSTRUCTION(NAME, OPCODE, TYPE, ACTION) \
472 case NAME: \
473 ACTION; \
474 break;
475#include "microblaze.isa"
476#undef INSTRUCTION
477
478 default:
479 CPU.exception = SIGILL;
480 fprintf (stderr, "ERROR: Unknown opcode at 0x%x\n", PC);
481 }
482 /* Update cycle counts */
483 insts++;
484 if (insn_type == memory_store_inst
ba14f941 485 || insn_type == memory_load_inst)
bd30e45a
ME
486 memops++;
487 if (insn_type == mult_inst)
488 bonus_cycles++;
489 if (insn_type == barrel_shift_inst)
490 bonus_cycles++;
491 if (insn_type == anyware_inst)
492 bonus_cycles++;
493 if (insn_type == div_inst)
494 bonus_cycles += 33;
495 }
496 /* Restore the PC */
497 PC = newpc;
498 /* Make R0 consistent */
499 CPU.regs[0] = 0;
500 /* Check for imm instr */
501 if (op == imm)
502 IMM_ENABLE = 1;
503 else
504 IMM_ENABLE = 0;
505 }
506 else
507 /* no delay slot: increment cycle count */
508 bonus_cycles++;
509 }
510 }
511
512 if (tracing)
513 fprintf (stderr, "\n");
514 }
515 while (!CPU.exception);
516
517 /* Hide away the things we've cached while executing. */
518 /* CPU.pc = pc; */
519 CPU.insts += insts; /* instructions done ... */
520 CPU.cycles += insts; /* and each takes a cycle */
521 CPU.cycles += bonus_cycles; /* and extra cycles for branches */
522 CPU.cycles += memops; /* and memop cycle delays */
bd30e45a
ME
523}
524
525
526int
5558e7e6 527sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
bd30e45a 528{
2b4bc832 529 SIM_CPU *cpu = STATE_CPU (sd, 0);
bd30e45a 530 int i;
2b4bc832
MF
531
532 init_pointers (cpu);
bd30e45a
ME
533
534 memcpy (&CPU.memory[addr], buffer, size);
535
536 return size;
537}
538
539int
540sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
541{
2b4bc832 542 SIM_CPU *cpu = STATE_CPU (sd, 0);
bd30e45a 543 int i;
2b4bc832
MF
544
545 init_pointers (cpu);
bd30e45a
ME
546
547 memcpy (buffer, &CPU.memory[addr], size);
548
549 return size;
550}
551
552
553int
554sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
555{
2b4bc832
MF
556 SIM_CPU *cpu = STATE_CPU (sd, 0);
557
558 init_pointers (cpu);
bd30e45a
ME
559
560 if (rn < NUM_REGS + NUM_SPECIAL && rn >= 0)
561 {
562 if (length == 4)
563 {
564 /* misalignment safe */
565 long ival = microblaze_extract_unsigned_integer (memory, 4);
566 if (rn < NUM_REGS)
567 CPU.regs[rn] = ival;
568 else
569 CPU.spregs[rn-NUM_REGS] = ival;
570 return 4;
571 }
572 else
573 return 0;
574 }
575 else
576 return 0;
577}
578
579int
580sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
581{
2b4bc832 582 SIM_CPU *cpu = STATE_CPU (sd, 0);
bd30e45a 583 long ival;
2b4bc832
MF
584
585 init_pointers (cpu);
bd30e45a
ME
586
587 if (rn < NUM_REGS + NUM_SPECIAL && rn >= 0)
588 {
589 if (length == 4)
590 {
591 if (rn < NUM_REGS)
592 ival = CPU.regs[rn];
593 else
594 ival = CPU.spregs[rn-NUM_REGS];
595
596 /* misalignment-safe */
597 microblaze_store_unsigned_integer (memory, 4, ival);
598 return 4;
599 }
600 else
601 return 0;
602 }
603 else
604 return 0;
605}
606
bd30e45a
ME
607void
608sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
609{
2b4bc832
MF
610 SIM_CPU *cpu = STATE_CPU (sd, 0);
611
bd30e45a
ME
612 if (CPU.exception == SIGQUIT)
613 {
614 *reason = sim_exited;
615 *sigrc = RETREG;
616 }
617 else
618 {
619 *reason = sim_stopped;
620 *sigrc = CPU.exception;
621 }
622}
623
bd30e45a
ME
624void
625sim_info (SIM_DESC sd, int verbose)
626{
2b4bc832
MF
627 SIM_CPU *cpu = STATE_CPU (sd, 0);
628 host_callback *callback = STATE_CALLBACK (sd);
629
bd30e45a
ME
630 callback->printf_filtered (callback, "\n\n# instructions executed %10d\n",
631 CPU.insts);
632 callback->printf_filtered (callback, "# cycles %10d\n",
633 (CPU.cycles) ? CPU.cycles+2 : 0);
bd30e45a
ME
634}
635
27b97b40
MF
636static sim_cia
637microblaze_pc_get (sim_cpu *cpu)
638{
639 return cpu->microblaze_cpu.spregs[0];
640}
641
642static void
643microblaze_pc_set (sim_cpu *cpu, sim_cia pc)
644{
645 cpu->microblaze_cpu.spregs[0] = pc;
646}
647
2b4bc832
MF
648static void
649free_state (SIM_DESC sd)
650{
651 if (STATE_MODULES (sd) != NULL)
652 sim_module_uninstall (sd);
653 sim_cpu_free_all (sd);
654 sim_state_free (sd);
655}
656
bd30e45a
ME
657SIM_DESC
658sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
659{
2b4bc832
MF
660 int i;
661 SIM_DESC sd = sim_state_alloc (kind, cb);
662 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
663
664 /* The cpu data is kept in a separately allocated chunk of memory. */
665 if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
666 {
667 free_state (sd);
668 return 0;
669 }
670
671 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
672 {
673 free_state (sd);
674 return 0;
675 }
bd30e45a 676
2b4bc832
MF
677 /* getopt will print the error message so we just have to exit if this fails.
678 FIXME: Hmmm... in the case of gdb we need getopt to call
679 print_filtered. */
680 if (sim_parse_args (sd, argv) != SIM_RC_OK)
681 {
682 free_state (sd);
683 return 0;
684 }
685
686 /* Check for/establish the a reference program image. */
687 if (sim_analyze_program (sd,
688 (STATE_PROG_ARGV (sd) != NULL
689 ? *STATE_PROG_ARGV (sd)
690 : NULL), abfd) != SIM_RC_OK)
691 {
692 free_state (sd);
693 return 0;
694 }
695
696 /* Configure/verify the target byte order and other runtime
697 configuration options. */
698 if (sim_config (sd) != SIM_RC_OK)
699 {
700 sim_module_uninstall (sd);
701 return 0;
702 }
703
704 if (sim_post_argv_init (sd) != SIM_RC_OK)
705 {
706 /* Uninstall the modules to avoid memory leaks,
707 file descriptor leaks, etc. */
708 sim_module_uninstall (sd);
709 return 0;
710 }
bd30e45a
ME
711
712 if (kind == SIM_OPEN_STANDALONE)
713 issue_messages = 1;
714
2b4bc832
MF
715 /* CPU specific initialization. */
716 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
717 {
718 SIM_CPU *cpu = STATE_CPU (sd, i);
719 int osize = sim_memory_size;
720
27b97b40
MF
721 CPU_PC_FETCH (cpu) = microblaze_pc_get;
722 CPU_PC_STORE (cpu) = microblaze_pc_set;
723
2b4bc832 724 set_initial_gprs (cpu);
bd30e45a 725
2b4bc832
MF
726 /* Discard and reacquire memory -- start with a clean slate. */
727 sim_size (cpu, 1); /* small */
728 sim_size (cpu, osize); /* and back again */
729 }
bd30e45a 730
2b4bc832 731 return sd;
bd30e45a
ME
732}
733
734void
735sim_close (SIM_DESC sd, int quitting)
736{
2b4bc832 737 /* Do nothing. */
bd30e45a
ME
738}
739
740SIM_RC
741sim_create_inferior (SIM_DESC sd, struct bfd *prog_bfd, char **argv, char **env)
742{
2b4bc832 743 SIM_CPU *cpu = STATE_CPU (sd, 0);
bd30e45a 744
bd30e45a
ME
745 PC = bfd_get_start_address (prog_bfd);
746
bd30e45a
ME
747 return SIM_RC_OK;
748}
749
bd30e45a 750void
60d847df 751sim_do_command (SIM_DESC sd, const char *cmd)
bd30e45a 752{
2b4bc832
MF
753 SIM_CPU *cpu = STATE_CPU (sd, 0);
754
bd30e45a
ME
755 /* Nothing there yet; it's all an error. */
756
757 if (cmd != NULL)
758 {
759 char ** simargv = buildargv (cmd);
760
97eca187 761 if (strcmp (simargv[0], "dumpmem") == 0)
bd30e45a
ME
762 {
763 unsigned char * p;
764 FILE * dumpfile;
765
766 if (simargv[1] == NULL)
767 fprintf (stderr, "Error: missing argument to dumpmem cmd.\n");
768
769 fprintf (stderr, "Writing dumpfile %s...",simargv[1]);
770
771 dumpfile = fopen (simargv[1], "w");
772 p = CPU.memory;
773 fwrite (p, CPU.msize-1, 1, dumpfile);
774 fclose (dumpfile);
775
776 fprintf (stderr, "done.\n");
777 }
778 else if (strcmp (simargv[0], "clearstats") == 0)
779 {
780 CPU.cycles = 0;
781 CPU.insts = 0;
bd30e45a
ME
782 }
783 else if (strcmp (simargv[0], "verbose") == 0)
784 {
785 issue_messages = 2;
786 }
787 else
788 {
789 fprintf (stderr,"Error: \"%s\" is not a valid M.CORE simulator command.\n",
790 cmd);
791 }
907c4910
CG
792
793 freeargv (simargv);
bd30e45a
ME
794 }
795 else
796 {
797 fprintf (stderr, "M.CORE sim commands: \n");
bd30e45a
ME
798 fprintf (stderr, " dumpmem <filename>\n");
799 fprintf (stderr, " clearstats\n");
800 fprintf (stderr, " verbose\n");
801 }
802}