1 /* Simulator for Motorola's MCore processor
2 Copyright (C) 1999-2015 Free Software Foundation, Inc.
3 Contributed by Cygnus Solutions.
5 This file is part of GDB, the GNU debugger.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 #include <sys/times.h>
25 #include <sys/param.h>
28 #include "gdb/callback.h"
29 #include "libiberty.h"
30 #include "gdb/remote-sim.h"
33 #define NUM_ELEM(A) (sizeof (A) / sizeof (A)[0])
37 typedef long int word
;
38 typedef unsigned long int uword
;
40 static int target_big_endian
= 0;
41 static unsigned long heap_ptr
= 0;
42 host_callback
* callback
;
46 mcore_extract_unsigned_integer (unsigned char *addr
, int len
)
50 unsigned char * startaddr
= (unsigned char *)addr
;
51 unsigned char * endaddr
= startaddr
+ len
;
53 if (len
> (int) sizeof (unsigned long))
54 printf ("That operation is not available on integers of more than %zu bytes.",
55 sizeof (unsigned long));
57 /* Start at the most significant end of the integer, and work towards
58 the least significant. */
61 if (! target_big_endian
)
63 for (p
= endaddr
; p
> startaddr
;)
64 retval
= (retval
<< 8) | * -- p
;
68 for (p
= startaddr
; p
< endaddr
;)
69 retval
= (retval
<< 8) | * p
++;
76 mcore_store_unsigned_integer (unsigned char *addr
, int len
, unsigned long val
)
79 unsigned char * startaddr
= (unsigned char *)addr
;
80 unsigned char * endaddr
= startaddr
+ len
;
82 if (! target_big_endian
)
84 for (p
= startaddr
; p
< endaddr
;)
92 for (p
= endaddr
; p
> startaddr
;)
100 /* The machine state.
101 This state is maintained in host byte order. The
102 fetch/store register functions must translate between host
103 byte order and the target processor byte order.
104 Keeping this data in target byte order simplifies the register
105 read/write functions. Keeping this data in native order improves
106 the performance of the simulator. Simulation speed is deemed more
109 /* The ordering of the mcore_regset structure is matched in the
110 gdb/config/mcore/tm-mcore.h file in the REGISTER_NAMES macro. */
113 word gregs
[16]; /* primary registers */
114 word alt_gregs
[16]; /* alt register file */
115 word cregs
[32]; /* control registers */
116 word pc
; /* the pc */
123 unsigned char * memory
;
129 struct mcore_regset asregs
;
130 word asints
[1]; /* but accessed larger... */
133 #define LAST_VALID_CREG 32 /* only 0..12 implemented */
134 #define NUM_MCORE_REGS (16 + 16 + LAST_VALID_CREG + 1)
138 static SIM_OPEN_KIND sim_kind
;
139 static char * myname
;
141 static int issue_messages
= 0;
143 #define gr asregs.active_gregs
144 #define cr asregs.cregs
145 #define sr asregs.cregs[0]
146 #define vbr asregs.cregs[1]
147 #define esr asregs.cregs[2]
148 #define fsr asregs.cregs[3]
149 #define epc asregs.cregs[4]
150 #define fpc asregs.cregs[5]
151 #define ss0 asregs.cregs[6]
152 #define ss1 asregs.cregs[7]
153 #define ss2 asregs.cregs[8]
154 #define ss3 asregs.cregs[9]
155 #define ss4 asregs.cregs[10]
156 #define gcr asregs.cregs[11]
157 #define gsr asregs.cregs[12]
158 #define mem asregs.memory
160 /* maniuplate the carry bit */
161 #define C_ON() (cpu.sr & 1)
162 #define C_VALUE() (cpu.sr & 1)
163 #define C_OFF() ((cpu.sr & 1) == 0)
164 #define SET_C() {cpu.sr |= 1;}
165 #define CLR_C() {cpu.sr &= 0xfffffffe;}
166 #define NEW_C(v) {CLR_C(); cpu.sr |= ((v) & 1);}
168 #define SR_AF() ((cpu.sr >> 1) & 1)
170 #define TRAPCODE 1 /* r1 holds which function we want */
171 #define PARM1 2 /* first parameter */
175 #define RET1 2 /* register for return values. */
178 int_sbrk (int inc_bytes
)
184 heap_ptr
+= inc_bytes
;
186 if (issue_messages
&& heap_ptr
>cpu
.gr
[0])
187 fprintf (stderr
, "Warning: heap_ptr overlaps stack!\n");
193 wbat (word x
, word v
)
195 if (((uword
)x
) >= cpu
.asregs
.msize
)
198 fprintf (stderr
, "byte write to 0x%x outside memory range\n", x
);
200 cpu
.asregs
.exception
= SIGSEGV
;
204 unsigned char *p
= cpu
.mem
+ x
;
210 wlat (word x
, word v
)
212 if (((uword
)x
) >= cpu
.asregs
.msize
)
215 fprintf (stderr
, "word write to 0x%x outside memory range\n", x
);
217 cpu
.asregs
.exception
= SIGSEGV
;
224 fprintf (stderr
, "word write to unaligned memory address: 0x%x\n", x
);
226 cpu
.asregs
.exception
= SIGBUS
;
228 else if (! target_big_endian
)
230 unsigned char * p
= cpu
.mem
+ x
;
238 unsigned char * p
= cpu
.mem
+ x
;
248 what (word x
, word v
)
250 if (((uword
)x
) >= cpu
.asregs
.msize
)
253 fprintf (stderr
, "short write to 0x%x outside memory range\n", x
);
255 cpu
.asregs
.exception
= SIGSEGV
;
262 fprintf (stderr
, "short write to unaligned memory address: 0x%x\n",
265 cpu
.asregs
.exception
= SIGBUS
;
267 else if (! target_big_endian
)
269 unsigned char * p
= cpu
.mem
+ x
;
275 unsigned char * p
= cpu
.mem
+ x
;
282 /* Read functions. */
286 if (((uword
)x
) >= cpu
.asregs
.msize
)
289 fprintf (stderr
, "byte read from 0x%x outside memory range\n", x
);
291 cpu
.asregs
.exception
= SIGSEGV
;
296 unsigned char * p
= cpu
.mem
+ x
;
304 if (((uword
) x
) >= cpu
.asregs
.msize
)
307 fprintf (stderr
, "word read from 0x%x outside memory range\n", x
);
309 cpu
.asregs
.exception
= SIGSEGV
;
317 fprintf (stderr
, "word read from unaligned address: 0x%x\n", x
);
319 cpu
.asregs
.exception
= SIGBUS
;
322 else if (! target_big_endian
)
324 unsigned char * p
= cpu
.mem
+ x
;
325 return (p
[3] << 24) | (p
[2] << 16) | (p
[1] << 8) | p
[0];
329 unsigned char * p
= cpu
.mem
+ x
;
330 return (p
[0] << 24) | (p
[1] << 16) | (p
[2] << 8) | p
[3];
338 if (((uword
)x
) >= cpu
.asregs
.msize
)
341 fprintf (stderr
, "short read from 0x%x outside memory range\n", x
);
343 cpu
.asregs
.exception
= SIGSEGV
;
351 fprintf (stderr
, "short read from unaligned address: 0x%x\n", x
);
353 cpu
.asregs
.exception
= SIGBUS
;
356 else if (! target_big_endian
)
358 unsigned char * p
= cpu
.mem
+ x
;
359 return (p
[1] << 8) | p
[0];
363 unsigned char * p
= cpu
.mem
+ x
;
364 return (p
[0] << 8) | p
[1];
370 /* Default to a 8 Mbyte (== 2^23) memory space. */
371 static int sim_memory_size
= 23;
373 #define MEM_SIZE_FLOOR 64
377 sim_memory_size
= power
;
378 cpu
.asregs
.msize
= 1 << sim_memory_size
;
383 /* Watch out for the '0 count' problem. There's probably a better
384 way.. e.g., why do we use 64 here? */
385 if (cpu
.asregs
.msize
< 64) /* Ensure a boundary. */
386 cpu
.mem
= (unsigned char *) calloc (64, (64 + cpu
.asregs
.msize
) / 64);
388 cpu
.mem
= (unsigned char *) calloc (64, cpu
.asregs
.msize
/ 64);
394 "Not enough VM for simulation of %lu bytes of RAM\n",
397 cpu
.asregs
.msize
= 1;
398 cpu
.mem
= (unsigned char *) calloc (1, 1);
405 if (cpu
.asregs
.msize
!= (1 << sim_memory_size
))
406 sim_size (sim_memory_size
);
410 set_initial_gprs (void)
414 unsigned long memsize
;
418 /* Set up machine just out of reset. */
422 memsize
= cpu
.asregs
.msize
/ (1024 * 1024);
424 if (issue_messages
> 1)
425 fprintf (stderr
, "Simulated memory of %lu Mbytes (0x0 .. 0x%08lx)\n",
426 memsize
, cpu
.asregs
.msize
- 1);
428 /* Clean out the GPRs and alternate GPRs. */
429 for (i
= 0; i
< 16; i
++)
431 cpu
.asregs
.gregs
[i
] = 0;
432 cpu
.asregs
.alt_gregs
[i
] = 0;
435 /* Make our register set point to the right place. */
437 cpu
.asregs
.active_gregs
= &cpu
.asregs
.alt_gregs
[0];
439 cpu
.asregs
.active_gregs
= &cpu
.asregs
.gregs
[0];
441 /* ABI specifies initial values for these registers. */
442 cpu
.gr
[0] = cpu
.asregs
.msize
- 4;
444 /* dac fix, the stack address must be 8-byte aligned! */
445 cpu
.gr
[0] = cpu
.gr
[0] - cpu
.gr
[0] % 8;
449 cpu
.gr
[PARM4
] = cpu
.gr
[0];
452 /* Functions so that trapped open/close don't interfere with the
453 parent's functions. We say that we can't close the descriptors
454 that we didn't open. exit() and cleanup() get in trouble here,
455 to some extent. That's the price of emulation. */
457 unsigned char opened
[100];
462 if (fd
< 0 || fd
> NUM_ELEM (opened
))
471 if (fd
< 0 || fd
> NUM_ELEM (opened
))
480 if (fd
< 0 || fd
> NUM_ELEM (opened
))
491 switch ((unsigned long) (cpu
.gr
[TRAPCODE
]))
494 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
495 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
496 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
497 cpu
.gr
[RET1
] = callback
->read (callback
, a
[0], (char *) a
[1], a
[2]);
501 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
502 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
503 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
504 cpu
.gr
[RET1
] = (int)callback
->write (callback
, a
[0], (char *) a
[1], a
[2]);
508 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
509 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
510 /* a[2] = (unsigned long) (cpu.gr[PARM3]); */
511 cpu
.gr
[RET1
] = callback
->open (callback
, (char *) a
[0], a
[1]);
512 log_open (cpu
.gr
[RET1
]);
516 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
517 /* Watch out for debugger's files. */
518 if (is_opened (a
[0]))
521 cpu
.gr
[RET1
] = callback
->close (callback
, a
[0]);
525 /* Don't let him close it. */
531 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
532 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
533 cpu
.gr
[RET1
] = link ((char *) a
[0], (char *) a
[1]);
537 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
538 cpu
.gr
[RET1
] = callback
->unlink (callback
, (char *) a
[0]);
542 /* handle time(0) vs time(&var) */
543 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
545 a
[0] += (unsigned long) cpu
.mem
;
546 cpu
.gr
[RET1
] = callback
->time (callback
, (time_t *) a
[0]);
550 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
551 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
552 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
553 cpu
.gr
[RET1
] = callback
->lseek (callback
, a
[0], a
[1], a
[2]);
557 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
558 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
559 cpu
.gr
[RET1
] = access ((char *) a
[0], a
[1]);
563 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
565 cpu
.gr
[RET1
] = times ((char *)a
[0]);
568 /* Give him simulated cycles for utime
569 and an instruction count for stime. */
578 t
.tms_utime
= cpu
.asregs
.cycles
;
579 t
.tms_stime
= cpu
.asregs
.insts
;
580 t
.tms_cutime
= t
.tms_utime
;
581 t
.tms_cstime
= t
.tms_stime
;
583 memcpy ((struct tms
*)(a
[0]), &t
, sizeof (t
));
585 cpu
.gr
[RET1
] = cpu
.asregs
.cycles
;
591 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
592 cpu
.gr
[RET1
] = int_sbrk (a
[0]);
597 fprintf (stderr
, "WARNING: sys call %d unimplemented\n",
604 process_stub (int what
)
606 /* These values should match those in libgloss/mcore/syscalls.s. */
613 case 10: /* _unlink */
614 case 19: /* _lseek */
615 case 43: /* _times */
616 cpu
.gr
[TRAPCODE
] = what
;
622 fprintf (stderr
, "Unhandled stub opcode: %d\n", what
);
633 cpu
.asregs
.exception
= SIGQUIT
;
642 a
[0] = (unsigned long)(cpu
.mem
+ cpu
.gr
[PARM1
]);
644 for (s
= (unsigned char *)a
[0], i
= 1 ; *s
&& i
< 6 ; s
++)
649 a
[i
] = (unsigned long)(cpu
.mem
+ cpu
.gr
[PARM1
+i
]);
651 a
[i
] = cpu
.gr
[i
+PARM1
];
656 cpu
.gr
[RET1
] = printf ((char *)a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
662 fprintf (stderr
, "WARNING: scanf unimplemented\n");
666 cpu
.gr
[RET1
] = cpu
.asregs
.insts
;
670 process_stub (cpu
.gr
[1]);
675 fprintf (stderr
, "Unhandled util code: %x\n", what
);
680 /* For figuring out whether we carried; addc/subc use this. */
682 iu_carry (unsigned long a
, unsigned long b
, int cin
)
686 x
= (a
& 0xffff) + (b
& 0xffff) + cin
;
687 x
= (x
>> 16) + (a
>> 16) + (b
>> 16);
693 #define WATCHFUNCTIONS 1
694 #ifdef WATCHFUNCTIONS
711 #define RD (inst & 0xF)
712 #define RS ((inst >> 4) & 0xF)
713 #define RX ((inst >> 8) & 0xF)
714 #define IMM5 ((inst >> 4) & 0x1F)
715 #define IMM4 ((inst) & 0xF)
717 static int tracing
= 0;
720 sim_resume (SIM_DESC sd
, int step
, int siggnal
)
733 cpu
.asregs
.exception
= step
? SIGTRAP
: 0;
736 /* Fetch the initial instructions that we'll decode. */
737 ibuf
= rlat (pc
& 0xFFFFFFFC);
744 /* make our register set point to the right place */
746 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
748 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
750 /* make a hash to speed exec loop, hope it's nonzero */
753 for (w
= 1; w
<= ENDWL
; w
++)
754 WLhash
= WLhash
& WL
[w
];
764 if (! target_big_endian
)
767 inst
= ibuf
& 0xFFFF;
772 if (! target_big_endian
)
773 inst
= ibuf
& 0xFFFF;
778 #ifdef WATCHFUNCTIONS
779 /* now scan list of watch addresses, if match, count it and
780 note return address and count cycles until pc=return address */
782 if ((WLincyc
== 1) && (pc
== WLendpc
))
784 cycs
= (cpu
.asregs
.cycles
+ (insts
+ bonus_cycles
+
785 (memops
* memcycles
)) - WLbcyc
);
787 if (WLcnts
[WLW
] == 1)
794 if (cycs
> WLmax
[WLW
])
799 if (cycs
< WLmin
[WLW
])
809 /* Optimize with a hash to speed loop. */
812 if ((WLhash
== 0) || ((WLhash
& pc
) != 0))
814 for (w
=1; w
<= ENDWL
; w
++)
819 WLbcyc
= cpu
.asregs
.cycles
+ insts
820 + bonus_cycles
+ (memops
* memcycles
);
821 WLendpc
= cpu
.gr
[15];
832 fprintf (stderr
, "%.4x: inst = %.4x ", pc
, inst
);
847 cpu
.asregs
.exception
= SIGTRAP
;
860 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
862 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
871 cpu
.asregs
.active_gregs
= &cpu
.asregs
.alt_gregs
[0];
873 cpu
.asregs
.active_gregs
= &cpu
.asregs
.gregs
[0];
878 fprintf (stderr
, "WARNING: stop unimplemented\n");
883 fprintf (stderr
, "WARNING: wait unimplemented\n");
888 fprintf (stderr
, "WARNING: doze unimplemented\n");
892 cpu
.asregs
.exception
= SIGILL
; /* illegal */
895 case 0x8: /* trap 0 */
896 case 0xA: /* trap 2 */
897 case 0xB: /* trap 3 */
898 cpu
.asregs
.exception
= SIGTRAP
;
901 case 0xC: /* trap 4 */
902 case 0xD: /* trap 5 */
903 case 0xE: /* trap 6 */
904 cpu
.asregs
.exception
= SIGILL
; /* illegal */
907 case 0xF: /* trap 7 */
908 cpu
.asregs
.exception
= SIGTRAP
; /* integer div-by-0 */
911 case 0x9: /* trap 1 */
918 cpu
.asregs
.exception
= SIGILL
; /* illegal */
922 cpu
.gr
[RD
] = C_VALUE();
925 cpu
.gr
[RD
] = C_OFF();
929 word addr
= cpu
.gr
[RD
];
930 int regno
= 4; /* always r4-r7 */
936 cpu
.gr
[regno
] = rlat(addr
);
940 while ((regno
&0x3) != 0);
945 word addr
= cpu
.gr
[RD
];
946 int regno
= 4; /* always r4-r7 */
952 wlat(addr
, cpu
.gr
[regno
]);
956 while ((regno
& 0x3) != 0);
961 word addr
= cpu
.gr
[0];
964 /* bonus cycle is really only needed if
965 the next insn shifts the last reg loaded.
972 cpu
.gr
[regno
] = rlat(addr
);
980 word addr
= cpu
.gr
[0];
983 /* this should be removed! */
984 /* bonus_cycles ++; */
986 memops
+= 16 - regno
;
989 wlat(addr
, cpu
.gr
[regno
]);
997 cpu
.gr
[RD
] -= C_VALUE();
1000 cpu
.gr
[RD
] -= C_OFF();
1002 case 0xA: /* inct */
1003 cpu
.gr
[RD
] += C_VALUE();
1005 case 0xB: /* incf */
1006 cpu
.gr
[RD
] += C_OFF();
1010 if (tracing
&& RD
== 15)
1011 fprintf (stderr
, "Func return, r2 = %x, r3 = %x\n",
1012 cpu
.gr
[2], cpu
.gr
[3]);
1026 for (i
= 0; !(tmp
& 0x80000000) && i
< 32; i
++)
1031 case 0xF: /* brev */
1035 tmp
= ((tmp
& 0xaaaaaaaa) >> 1) | ((tmp
& 0x55555555) << 1);
1036 tmp
= ((tmp
& 0xcccccccc) >> 2) | ((tmp
& 0x33333333) << 2);
1037 tmp
= ((tmp
& 0xf0f0f0f0) >> 4) | ((tmp
& 0x0f0f0f0f) << 4);
1038 tmp
= ((tmp
& 0xff00ff00) >> 8) | ((tmp
& 0x00ff00ff) << 8);
1039 cpu
.gr
[RD
] = ((tmp
& 0xffff0000) >> 16) | ((tmp
& 0x0000ffff) << 16);
1047 case 0x0: /* xtrb3 */
1048 cpu
.gr
[1] = (cpu
.gr
[RD
]) & 0xFF;
1049 NEW_C (cpu
.gr
[RD
] != 0);
1051 case 0x1: /* xtrb2 */
1052 cpu
.gr
[1] = (cpu
.gr
[RD
]>>8) & 0xFF;
1053 NEW_C (cpu
.gr
[RD
] != 0);
1055 case 0x2: /* xtrb1 */
1056 cpu
.gr
[1] = (cpu
.gr
[RD
]>>16) & 0xFF;
1057 NEW_C (cpu
.gr
[RD
] != 0);
1059 case 0x3: /* xtrb0 */
1060 cpu
.gr
[1] = (cpu
.gr
[RD
]>>24) & 0xFF;
1061 NEW_C (cpu
.gr
[RD
] != 0);
1063 case 0x4: /* zextb */
1064 cpu
.gr
[RD
] &= 0x000000FF;
1066 case 0x5: /* sextb */
1075 case 0x6: /* zexth */
1076 cpu
.gr
[RD
] &= 0x0000FFFF;
1078 case 0x7: /* sexth */
1087 case 0x8: /* declt */
1089 NEW_C ((long)cpu
.gr
[RD
] < 0);
1091 case 0x9: /* tstnbz */
1093 word tmp
= cpu
.gr
[RD
];
1094 NEW_C ((tmp
& 0xFF000000) != 0 &&
1095 (tmp
& 0x00FF0000) != 0 && (tmp
& 0x0000FF00) != 0 &&
1096 (tmp
& 0x000000FF) != 0);
1099 case 0xA: /* decgt */
1101 NEW_C ((long)cpu
.gr
[RD
] > 0);
1103 case 0xB: /* decne */
1105 NEW_C ((long)cpu
.gr
[RD
] != 0);
1107 case 0xC: /* clrt */
1111 case 0xD: /* clrf */
1116 if (cpu
.gr
[RD
] & 0x80000000)
1117 cpu
.gr
[RD
] = ~cpu
.gr
[RD
] + 1;
1120 cpu
.gr
[RD
] = ~cpu
.gr
[RD
];
1124 case 0x02: /* movt */
1126 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1128 case 0x03: /* mult */
1129 /* consume 2 bits per cycle from rs, until rs is 0 */
1131 unsigned int t
= cpu
.gr
[RS
];
1133 for (ticks
= 0; t
!= 0 ; t
>>= 2)
1135 bonus_cycles
+= ticks
;
1137 bonus_cycles
+= 2; /* min. is 3, so add 2, plus ticks above */
1139 fprintf (stderr
, " mult %x by %x to give %x",
1140 cpu
.gr
[RD
], cpu
.gr
[RS
], cpu
.gr
[RD
] * cpu
.gr
[RS
]);
1141 cpu
.gr
[RD
] = cpu
.gr
[RD
] * cpu
.gr
[RS
];
1143 case 0x04: /* loopt */
1146 pc
+= (IMM4
<< 1) - 32;
1150 --cpu
.gr
[RS
]; /* not RD! */
1151 NEW_C (((long)cpu
.gr
[RS
]) > 0);
1153 case 0x05: /* subu */
1154 cpu
.gr
[RD
] -= cpu
.gr
[RS
];
1156 case 0x06: /* addc */
1158 unsigned long tmp
, a
, b
;
1161 cpu
.gr
[RD
] = a
+ b
+ C_VALUE ();
1162 tmp
= iu_carry (a
, b
, C_VALUE ());
1166 case 0x07: /* subc */
1168 unsigned long tmp
, a
, b
;
1171 cpu
.gr
[RD
] = a
- b
+ C_VALUE () - 1;
1172 tmp
= iu_carry (a
,~b
, C_VALUE ());
1176 case 0x08: /* illegal */
1177 case 0x09: /* illegal*/
1178 cpu
.asregs
.exception
= SIGILL
;
1180 case 0x0A: /* movf */
1182 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1184 case 0x0B: /* lsr */
1186 unsigned long dst
, src
;
1189 /* We must not rely solely upon the native shift operations, since they
1190 may not match the M*Core's behaviour on boundary conditions. */
1191 dst
= src
> 31 ? 0 : dst
>> src
;
1195 case 0x0C: /* cmphs */
1196 NEW_C ((unsigned long )cpu
.gr
[RD
] >=
1197 (unsigned long)cpu
.gr
[RS
]);
1199 case 0x0D: /* cmplt */
1200 NEW_C ((long)cpu
.gr
[RD
] < (long)cpu
.gr
[RS
]);
1202 case 0x0E: /* tst */
1203 NEW_C ((cpu
.gr
[RD
] & cpu
.gr
[RS
]) != 0);
1205 case 0x0F: /* cmpne */
1206 NEW_C (cpu
.gr
[RD
] != cpu
.gr
[RS
]);
1208 case 0x10: case 0x11: /* mfcr */
1212 if (r
<= LAST_VALID_CREG
)
1213 cpu
.gr
[RD
] = cpu
.cr
[r
];
1215 cpu
.asregs
.exception
= SIGILL
;
1219 case 0x12: /* mov */
1220 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1222 fprintf (stderr
, "MOV %x into reg %d", cpu
.gr
[RD
], RD
);
1225 case 0x13: /* bgenr */
1226 if (cpu
.gr
[RS
] & 0x20)
1229 cpu
.gr
[RD
] = 1 << (cpu
.gr
[RS
] & 0x1F);
1232 case 0x14: /* rsub */
1233 cpu
.gr
[RD
] = cpu
.gr
[RS
] - cpu
.gr
[RD
];
1236 case 0x15: /* ixw */
1237 cpu
.gr
[RD
] += cpu
.gr
[RS
]<<2;
1240 case 0x16: /* and */
1241 cpu
.gr
[RD
] &= cpu
.gr
[RS
];
1244 case 0x17: /* xor */
1245 cpu
.gr
[RD
] ^= cpu
.gr
[RS
];
1248 case 0x18: case 0x19: /* mtcr */
1252 if (r
<= LAST_VALID_CREG
)
1253 cpu
.cr
[r
] = cpu
.gr
[RD
];
1255 cpu
.asregs
.exception
= SIGILL
;
1257 /* we might have changed register sets... */
1259 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
1261 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
1265 case 0x1A: /* asr */
1266 /* We must not rely solely upon the native shift operations, since they
1267 may not match the M*Core's behaviour on boundary conditions. */
1268 if (cpu
.gr
[RS
] > 30)
1269 cpu
.gr
[RD
] = ((long) cpu
.gr
[RD
]) < 0 ? -1 : 0;
1271 cpu
.gr
[RD
] = (long) cpu
.gr
[RD
] >> cpu
.gr
[RS
];
1274 case 0x1B: /* lsl */
1275 /* We must not rely solely upon the native shift operations, since they
1276 may not match the M*Core's behaviour on boundary conditions. */
1277 cpu
.gr
[RD
] = cpu
.gr
[RS
] > 31 ? 0 : cpu
.gr
[RD
] << cpu
.gr
[RS
];
1280 case 0x1C: /* addu */
1281 cpu
.gr
[RD
] += cpu
.gr
[RS
];
1284 case 0x1D: /* ixh */
1285 cpu
.gr
[RD
] += cpu
.gr
[RS
] << 1;
1289 cpu
.gr
[RD
] |= cpu
.gr
[RS
];
1292 case 0x1F: /* andn */
1293 cpu
.gr
[RD
] &= ~cpu
.gr
[RS
];
1295 case 0x20: case 0x21: /* addi */
1297 cpu
.gr
[RD
] + (IMM5
+ 1);
1299 case 0x22: case 0x23: /* cmplti */
1301 int tmp
= (IMM5
+ 1);
1302 if (cpu
.gr
[RD
] < tmp
)
1312 case 0x24: case 0x25: /* subi */
1314 cpu
.gr
[RD
] - (IMM5
+ 1);
1316 case 0x26: case 0x27: /* illegal */
1317 cpu
.asregs
.exception
= SIGILL
;
1319 case 0x28: case 0x29: /* rsubi */
1323 case 0x2A: case 0x2B: /* cmpnei */
1324 if (cpu
.gr
[RD
] != IMM5
)
1334 case 0x2C: case 0x2D: /* bmaski, divu */
1336 unsigned imm
= IMM5
;
1342 unsigned int rx
, r1
;
1348 /* unsigned divide */
1349 cpu
.gr
[RD
] = (word
) ((unsigned int) cpu
.gr
[RD
] / (unsigned int)cpu
.gr
[1] );
1351 /* compute bonus_cycles for divu */
1352 for (r1nlz
= 0; ((r1
& 0x80000000) == 0) && (r1nlz
< 32); r1nlz
++)
1355 for (rxnlz
= 0; ((rx
& 0x80000000) == 0) && (rxnlz
< 32); rxnlz
++)
1361 exe
+= 5 + r1nlz
- rxnlz
;
1363 if (exe
>= (2 * memcycles
- 1))
1365 bonus_cycles
+= exe
- (2 * memcycles
) + 1;
1368 else if (imm
== 0 || imm
>= 8)
1374 cpu
.gr
[RD
] = (1 << imm
) - 1;
1379 cpu
.asregs
.exception
= SIGILL
;
1383 case 0x2E: case 0x2F: /* andi */
1384 cpu
.gr
[RD
] = cpu
.gr
[RD
] & IMM5
;
1386 case 0x30: case 0x31: /* bclri */
1387 cpu
.gr
[RD
] = cpu
.gr
[RD
] & ~(1<<IMM5
);
1389 case 0x32: case 0x33: /* bgeni, divs */
1391 unsigned imm
= IMM5
;
1398 /* compute bonus_cycles for divu */
1403 if (((rx
< 0) && (r1
> 0)) || ((rx
>= 0) && (r1
< 0)))
1411 /* signed divide, general registers are of type int, so / op is OK */
1412 cpu
.gr
[RD
] = cpu
.gr
[RD
] / cpu
.gr
[1];
1414 for (r1nlz
= 0; ((r1
& 0x80000000) == 0) && (r1nlz
< 32) ; r1nlz
++ )
1417 for (rxnlz
= 0; ((rx
& 0x80000000) == 0) && (rxnlz
< 32) ; rxnlz
++ )
1423 exe
+= 6 + r1nlz
- rxnlz
+ sc
;
1425 if (exe
>= (2 * memcycles
- 1))
1427 bonus_cycles
+= exe
- (2 * memcycles
) + 1;
1433 cpu
.gr
[RD
] = (1 << IMM5
);
1438 cpu
.asregs
.exception
= SIGILL
;
1442 case 0x34: case 0x35: /* bseti */
1443 cpu
.gr
[RD
] = cpu
.gr
[RD
] | (1 << IMM5
);
1445 case 0x36: case 0x37: /* btsti */
1446 NEW_C (cpu
.gr
[RD
] >> IMM5
);
1448 case 0x38: case 0x39: /* xsr, rotli */
1450 unsigned imm
= IMM5
;
1451 unsigned long tmp
= cpu
.gr
[RD
];
1457 cpu
.gr
[RD
] = (cbit
<< 31) | (tmp
>> 1);
1460 cpu
.gr
[RD
] = (tmp
<< imm
) | (tmp
>> (32 - imm
));
1463 case 0x3A: case 0x3B: /* asrc, asri */
1465 unsigned imm
= IMM5
;
1466 long tmp
= cpu
.gr
[RD
];
1470 cpu
.gr
[RD
] = tmp
>> 1;
1473 cpu
.gr
[RD
] = tmp
>> imm
;
1476 case 0x3C: case 0x3D: /* lslc, lsli */
1478 unsigned imm
= IMM5
;
1479 unsigned long tmp
= cpu
.gr
[RD
];
1483 cpu
.gr
[RD
] = tmp
<< 1;
1486 cpu
.gr
[RD
] = tmp
<< imm
;
1489 case 0x3E: case 0x3F: /* lsrc, lsri */
1491 unsigned imm
= IMM5
;
1492 unsigned long tmp
= cpu
.gr
[RD
];
1496 cpu
.gr
[RD
] = tmp
>> 1;
1499 cpu
.gr
[RD
] = tmp
>> imm
;
1502 case 0x40: case 0x41: case 0x42: case 0x43:
1503 case 0x44: case 0x45: case 0x46: case 0x47:
1504 case 0x48: case 0x49: case 0x4A: case 0x4B:
1505 case 0x4C: case 0x4D: case 0x4E: case 0x4F:
1506 cpu
.asregs
.exception
= SIGILL
;
1511 case 0x51: case 0x52: case 0x53:
1512 case 0x54: case 0x55: case 0x56: case 0x57:
1513 case 0x58: case 0x59: case 0x5A: case 0x5B:
1514 case 0x5C: case 0x5D: case 0x5E: case 0x5F:
1515 cpu
.asregs
.exception
= SIGILL
;
1517 case 0x60: case 0x61: case 0x62: case 0x63: /* movi */
1518 case 0x64: case 0x65: case 0x66: case 0x67:
1519 cpu
.gr
[RD
] = (inst
>> 4) & 0x7F;
1521 case 0x68: case 0x69: case 0x6A: case 0x6B:
1522 case 0x6C: case 0x6D: case 0x6E: case 0x6F: /* illegal */
1523 cpu
.asregs
.exception
= SIGILL
;
1525 case 0x71: case 0x72: case 0x73:
1526 case 0x74: case 0x75: case 0x76: case 0x77:
1527 case 0x78: case 0x79: case 0x7A: case 0x7B:
1528 case 0x7C: case 0x7D: case 0x7E: /* lrw */
1529 cpu
.gr
[RX
] = rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC);
1531 fprintf (stderr
, "LRW of 0x%x from 0x%x to reg %d",
1532 rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC),
1533 (pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC, RX
);
1536 case 0x7F: /* jsri */
1539 fprintf (stderr
, "func call: r2 = %x r3 = %x r4 = %x r5 = %x r6 = %x r7 = %x\n",
1540 cpu
.gr
[2], cpu
.gr
[3], cpu
.gr
[4], cpu
.gr
[5], cpu
.gr
[6], cpu
.gr
[7]);
1541 case 0x70: /* jmpi */
1542 pc
= rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC);
1548 case 0x80: case 0x81: case 0x82: case 0x83:
1549 case 0x84: case 0x85: case 0x86: case 0x87:
1550 case 0x88: case 0x89: case 0x8A: case 0x8B:
1551 case 0x8C: case 0x8D: case 0x8E: case 0x8F: /* ld */
1552 cpu
.gr
[RX
] = rlat (cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C));
1554 fprintf (stderr
, "load reg %d from 0x%x with 0x%x",
1556 cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C), cpu
.gr
[RX
]);
1559 case 0x90: case 0x91: case 0x92: case 0x93:
1560 case 0x94: case 0x95: case 0x96: case 0x97:
1561 case 0x98: case 0x99: case 0x9A: case 0x9B:
1562 case 0x9C: case 0x9D: case 0x9E: case 0x9F: /* st */
1563 wlat (cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C), cpu
.gr
[RX
]);
1565 fprintf (stderr
, "store reg %d (containing 0x%x) to 0x%x",
1567 cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C));
1570 case 0xA0: case 0xA1: case 0xA2: case 0xA3:
1571 case 0xA4: case 0xA5: case 0xA6: case 0xA7:
1572 case 0xA8: case 0xA9: case 0xAA: case 0xAB:
1573 case 0xAC: case 0xAD: case 0xAE: case 0xAF: /* ld.b */
1574 cpu
.gr
[RX
] = rbat (cpu
.gr
[RD
] + RS
);
1577 case 0xB0: case 0xB1: case 0xB2: case 0xB3:
1578 case 0xB4: case 0xB5: case 0xB6: case 0xB7:
1579 case 0xB8: case 0xB9: case 0xBA: case 0xBB:
1580 case 0xBC: case 0xBD: case 0xBE: case 0xBF: /* st.b */
1581 wbat (cpu
.gr
[RD
] + RS
, cpu
.gr
[RX
]);
1584 case 0xC0: case 0xC1: case 0xC2: case 0xC3:
1585 case 0xC4: case 0xC5: case 0xC6: case 0xC7:
1586 case 0xC8: case 0xC9: case 0xCA: case 0xCB:
1587 case 0xCC: case 0xCD: case 0xCE: case 0xCF: /* ld.h */
1588 cpu
.gr
[RX
] = rhat (cpu
.gr
[RD
] + ((inst
>> 3) & 0x001E));
1591 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
1592 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
1593 case 0xD8: case 0xD9: case 0xDA: case 0xDB:
1594 case 0xDC: case 0xDD: case 0xDE: case 0xDF: /* st.h */
1595 what (cpu
.gr
[RD
] + ((inst
>> 3) & 0x001E), cpu
.gr
[RX
]);
1598 case 0xE8: case 0xE9: case 0xEA: case 0xEB:
1599 case 0xEC: case 0xED: case 0xEE: case 0xEF: /* bf */
1603 disp
= inst
& 0x03FF;
1611 case 0xE0: case 0xE1: case 0xE2: case 0xE3:
1612 case 0xE4: case 0xE5: case 0xE6: case 0xE7: /* bt */
1616 disp
= inst
& 0x03FF;
1625 case 0xF8: case 0xF9: case 0xFA: case 0xFB:
1626 case 0xFC: case 0xFD: case 0xFE: case 0xFF: /* bsr */
1628 case 0xF0: case 0xF1: case 0xF2: case 0xF3:
1629 case 0xF4: case 0xF5: case 0xF6: case 0xF7: /* br */
1632 disp
= inst
& 0x03FF;
1644 fprintf (stderr
, "\n");
1648 /* Do not let him fetch from a bad address! */
1649 if (((uword
)pc
) >= cpu
.asregs
.msize
)
1652 fprintf (stderr
, "PC loaded at 0x%x is outside of available memory! (0x%x)\n", oldpc
, pc
);
1654 cpu
.asregs
.exception
= SIGSEGV
;
1658 ibuf
= rlat (pc
& 0xFFFFFFFC);
1663 while (!cpu
.asregs
.exception
);
1665 /* Hide away the things we've cached while executing. */
1667 cpu
.asregs
.insts
+= insts
; /* instructions done ... */
1668 cpu
.asregs
.cycles
+= insts
; /* and each takes a cycle */
1669 cpu
.asregs
.cycles
+= bonus_cycles
; /* and extra cycles for branches */
1670 cpu
.asregs
.cycles
+= memops
* memcycles
; /* and memop cycle delays */
1675 sim_write (SIM_DESC sd
, SIM_ADDR addr
, const unsigned char *buffer
, int size
)
1680 memcpy (& cpu
.mem
[addr
], buffer
, size
);
1686 sim_read (SIM_DESC sd
, SIM_ADDR addr
, unsigned char *buffer
, int size
)
1691 memcpy (buffer
, & cpu
.mem
[addr
], size
);
1698 sim_store_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
1702 if (rn
< NUM_MCORE_REGS
&& rn
>= 0)
1708 /* misalignment safe */
1709 ival
= mcore_extract_unsigned_integer (memory
, 4);
1710 cpu
.asints
[rn
] = ival
;
1720 sim_fetch_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
1724 if (rn
< NUM_MCORE_REGS
&& rn
>= 0)
1728 long ival
= cpu
.asints
[rn
];
1730 /* misalignment-safe */
1731 mcore_store_unsigned_integer (memory
, 4, ival
);
1742 sim_trace (SIM_DESC sd
)
1746 sim_resume (sd
, 0, 0);
1754 sim_stop_reason (SIM_DESC sd
, enum sim_stop
*reason
, int *sigrc
)
1756 if (cpu
.asregs
.exception
== SIGQUIT
)
1758 * reason
= sim_exited
;
1759 * sigrc
= cpu
.gr
[PARM1
];
1763 * reason
= sim_stopped
;
1764 * sigrc
= cpu
.asregs
.exception
;
1770 sim_stop (SIM_DESC sd
)
1772 cpu
.asregs
.exception
= SIGINT
;
1778 sim_info (SIM_DESC sd
, int verbose
)
1780 #ifdef WATCHFUNCTIONS
1783 double virttime
= cpu
.asregs
.cycles
/ 36.0e6
;
1785 callback
->printf_filtered (callback
, "\n\n# instructions executed %10d\n",
1787 callback
->printf_filtered (callback
, "# cycles %10d\n",
1789 callback
->printf_filtered (callback
, "# pipeline stalls %10d\n",
1791 callback
->printf_filtered (callback
, "# virtual time taken %10.4f\n",
1794 #ifdef WATCHFUNCTIONS
1795 callback
->printf_filtered (callback
, "\nNumber of watched functions: %d\n",
1800 for (w
= 1; w
<= ENDWL
; w
++)
1802 callback
->printf_filtered (callback
, "WL = %s %8x\n",WLstr
[w
],WL
[w
]);
1803 callback
->printf_filtered (callback
, " calls = %d, cycles = %d\n",
1804 WLcnts
[w
],WLcyc
[w
]);
1807 callback
->printf_filtered (callback
,
1808 " maxcpc = %d, mincpc = %d, avecpc = %d\n",
1809 WLmax
[w
],WLmin
[w
],WLcyc
[w
]/WLcnts
[w
]);
1813 callback
->printf_filtered (callback
,
1814 "Total cycles for watched functions: %d\n",wcyc
);
1820 unsigned char sa_machtype
[2];
1821 unsigned char sa_magic
[2];
1822 unsigned char sa_tsize
[4];
1823 unsigned char sa_dsize
[4];
1824 unsigned char sa_bsize
[4];
1825 unsigned char sa_syms
[4];
1826 unsigned char sa_entry
[4];
1827 unsigned char sa_trelo
[4];
1828 unsigned char sa_drelo
[4];
1831 #define LONG(x) (((x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
1832 #define SHORT(x) (((x)[0]<<8)|(x)[1])
1835 sim_open (SIM_OPEN_KIND kind
, host_callback
*cb
, struct bfd
*abfd
, char **argv
)
1837 int osize
= sim_memory_size
;
1841 if (kind
== SIM_OPEN_STANDALONE
)
1844 /* Discard and reacquire memory -- start with a clean slate. */
1845 sim_size (1); /* small */
1846 sim_size (osize
); /* and back again */
1848 set_initial_gprs (); /* Reset the GPR registers. */
1850 /* Fudge our descriptor for now. */
1851 return (SIM_DESC
) 1;
1855 sim_close (SIM_DESC sd
, int quitting
)
1861 sim_load (SIM_DESC sd
, const char *prog
, bfd
*abfd
, int from_tty
)
1863 /* Do the right thing for ELF executables; this turns out to be
1864 just about the right thing for any object format that:
1865 - we crack using BFD routines
1866 - follows the traditional UNIX text/data/bss layout
1867 - calls the bss section ".bss". */
1869 extern bfd
* sim_load_file (); /* ??? Don't know where this should live. */
1875 handle
= bfd_openr (prog
, 0); /* could be "mcore" */
1879 printf("``%s'' could not be opened.\n", prog
);
1883 /* Makes sure that we have an object file, also cleans gets the
1884 section headers in place. */
1885 if (!bfd_check_format (handle
, bfd_object
))
1887 /* wasn't an object file */
1889 printf ("``%s'' is not appropriate object file.\n", prog
);
1893 /* Look for that bss section. */
1894 s_bss
= bfd_get_section_by_name (handle
, ".bss");
1898 printf("``%s'' has no bss section.\n", prog
);
1902 /* Appropriately paranoid would check that we have
1903 a traditional text/data/bss ordering within memory. */
1905 /* figure the end of the bss section */
1907 printf ("bss section at 0x%08x for 0x%08x bytes\n",
1908 (unsigned long) bfd_get_section_vma (handle
, s_bss
),
1909 (unsigned long) bfd_section_size (handle
, s_bss
));
1911 heap_ptr
= ((unsigned long) bfd_get_section_vma (handle
, s_bss
)
1912 + (unsigned long) bfd_section_size (handle
, s_bss
));
1914 /* Clean up after ourselves. */
1917 /* XXX: do we need to free the s_bss and handle structures? */
1920 /* from sh -- dac */
1921 prog_bfd
= sim_load_file (sd
, myname
, callback
, prog
, abfd
,
1922 sim_kind
== SIM_OPEN_DEBUG
,
1924 if (prog_bfd
== NULL
)
1927 target_big_endian
= bfd_big_endian (prog_bfd
);
1930 bfd_close (prog_bfd
);
1936 sim_create_inferior (SIM_DESC sd
, struct bfd
*prog_bfd
, char **argv
, char **env
)
1943 unsigned long strings
;
1944 unsigned long pointers
;
1945 unsigned long hi_stack
;
1948 /* Set the initial register set. */
1951 set_initial_gprs ();
1954 hi_stack
= cpu
.asregs
.msize
- 4;
1955 cpu
.asregs
.pc
= bfd_get_start_address (prog_bfd
);
1957 /* Calculate the argument and environment strings. */
1963 l
= strlen (*avp
) + 1; /* include the null */
1964 s_length
+= (l
+ 3) & ~3; /* make it a 4 byte boundary */
1972 l
= strlen (*avp
) + 1; /* include the null */
1973 s_length
+= (l
+ 3) & ~ 3;/* make it a 4 byte boundary */
1977 /* Claim some memory for the pointers and strings. */
1978 pointers
= hi_stack
- sizeof(word
) * (nenv
+1+nargs
+1);
1979 pointers
&= ~3; /* must be 4-byte aligned */
1980 cpu
.gr
[0] = pointers
;
1982 strings
= cpu
.gr
[0] - s_length
;
1983 strings
&= ~3; /* want to make it 4-byte aligned */
1984 cpu
.gr
[0] = strings
;
1985 /* dac fix, the stack address must be 8-byte aligned! */
1986 cpu
.gr
[0] = cpu
.gr
[0] - cpu
.gr
[0] % 8;
1988 /* Loop through the arguments and fill them in. */
1989 cpu
.gr
[PARM1
] = nargs
;
1992 /* No strings to fill in. */
1997 cpu
.gr
[PARM2
] = pointers
;
2001 /* Save where we're putting it. */
2002 wlat (pointers
, strings
);
2004 /* Copy the string. */
2005 l
= strlen (* avp
) + 1;
2006 strcpy ((char *)(cpu
.mem
+ strings
), *avp
);
2008 /* Bump the pointers. */
2014 /* A null to finish the list. */
2019 /* Now do the environment pointers. */
2022 /* No strings to fill in. */
2027 cpu
.gr
[PARM3
] = pointers
;
2032 /* Save where we're putting it. */
2033 wlat (pointers
, strings
);
2035 /* Copy the string. */
2036 l
= strlen (* avp
) + 1;
2037 strcpy ((char *)(cpu
.mem
+ strings
), *avp
);
2039 /* Bump the pointers. */
2045 /* A null to finish the list. */
2054 sim_do_command (SIM_DESC sd
, const char *cmd
)
2056 /* Nothing there yet; it's all an error. */
2060 char ** simargv
= buildargv (cmd
);
2062 if (strcmp (simargv
[0], "watch") == 0)
2064 if ((simargv
[1] == NULL
) || (simargv
[2] == NULL
))
2066 fprintf (stderr
, "Error: missing argument to watch cmd.\n");
2073 WL
[ENDWL
] = strtol (simargv
[2], NULL
, 0);
2074 WLstr
[ENDWL
] = strdup (simargv
[1]);
2075 fprintf (stderr
, "Added %s (%x) to watchlist, #%d\n",WLstr
[ENDWL
],
2079 else if (strcmp (simargv
[0], "dumpmem") == 0)
2084 if (simargv
[1] == NULL
)
2085 fprintf (stderr
, "Error: missing argument to dumpmem cmd.\n");
2087 fprintf (stderr
, "Writing dumpfile %s...",simargv
[1]);
2089 dumpfile
= fopen (simargv
[1], "w");
2091 fwrite (p
, cpu
.asregs
.msize
-1, 1, dumpfile
);
2094 fprintf (stderr
, "done.\n");
2096 else if (strcmp (simargv
[0], "clearstats") == 0)
2098 cpu
.asregs
.cycles
= 0;
2099 cpu
.asregs
.insts
= 0;
2100 cpu
.asregs
.stalls
= 0;
2103 else if (strcmp (simargv
[0], "verbose") == 0)
2109 fprintf (stderr
,"Error: \"%s\" is not a valid M.CORE simulator command.\n",
2117 fprintf (stderr
, "M.CORE sim commands: \n");
2118 fprintf (stderr
, " watch <funcname> <addr>\n");
2119 fprintf (stderr
, " dumpmem <filename>\n");
2120 fprintf (stderr
, " clearstats\n");
2121 fprintf (stderr
, " verbose\n");
2126 sim_set_callbacks (host_callback
*ptr
)