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 host_callback
* callback
;
45 mcore_extract_unsigned_integer (unsigned char *addr
, int len
)
49 unsigned char * startaddr
= (unsigned char *)addr
;
50 unsigned char * endaddr
= startaddr
+ len
;
52 if (len
> (int) sizeof (unsigned long))
53 printf ("That operation is not available on integers of more than %zu bytes.",
54 sizeof (unsigned long));
56 /* Start at the most significant end of the integer, and work towards
57 the least significant. */
60 if (! target_big_endian
)
62 for (p
= endaddr
; p
> startaddr
;)
63 retval
= (retval
<< 8) | * -- p
;
67 for (p
= startaddr
; p
< endaddr
;)
68 retval
= (retval
<< 8) | * p
++;
75 mcore_store_unsigned_integer (unsigned char *addr
, int len
, unsigned long val
)
78 unsigned char * startaddr
= (unsigned char *)addr
;
79 unsigned char * endaddr
= startaddr
+ len
;
81 if (! target_big_endian
)
83 for (p
= startaddr
; p
< endaddr
;)
91 for (p
= endaddr
; p
> startaddr
;)
100 This state is maintained in host byte order. The
101 fetch/store register functions must translate between host
102 byte order and the target processor byte order.
103 Keeping this data in target byte order simplifies the register
104 read/write functions. Keeping this data in native order improves
105 the performance of the simulator. Simulation speed is deemed more
108 /* The ordering of the mcore_regset structure is matched in the
109 gdb/config/mcore/tm-mcore.h file in the REGISTER_NAMES macro. */
112 word gregs
[16]; /* primary registers */
113 word alt_gregs
[16]; /* alt register file */
114 word cregs
[32]; /* control registers */
115 word pc
; /* the pc */
122 unsigned char * memory
;
128 struct mcore_regset asregs
;
129 word asints
[1]; /* but accessed larger... */
132 #define LAST_VALID_CREG 32 /* only 0..12 implemented */
133 #define NUM_MCORE_REGS (16 + 16 + LAST_VALID_CREG + 1)
137 static SIM_OPEN_KIND sim_kind
;
138 static char * myname
;
140 static int issue_messages
= 0;
142 #define gr asregs.active_gregs
143 #define cr asregs.cregs
144 #define sr asregs.cregs[0]
145 #define vbr asregs.cregs[1]
146 #define esr asregs.cregs[2]
147 #define fsr asregs.cregs[3]
148 #define epc asregs.cregs[4]
149 #define fpc asregs.cregs[5]
150 #define ss0 asregs.cregs[6]
151 #define ss1 asregs.cregs[7]
152 #define ss2 asregs.cregs[8]
153 #define ss3 asregs.cregs[9]
154 #define ss4 asregs.cregs[10]
155 #define gcr asregs.cregs[11]
156 #define gsr asregs.cregs[12]
157 #define mem asregs.memory
159 /* maniuplate the carry bit */
160 #define C_ON() (cpu.sr & 1)
161 #define C_VALUE() (cpu.sr & 1)
162 #define C_OFF() ((cpu.sr & 1) == 0)
163 #define SET_C() {cpu.sr |= 1;}
164 #define CLR_C() {cpu.sr &= 0xfffffffe;}
165 #define NEW_C(v) {CLR_C(); cpu.sr |= ((v) & 1);}
167 #define SR_AF() ((cpu.sr >> 1) & 1)
169 #define TRAPCODE 1 /* r1 holds which function we want */
170 #define PARM1 2 /* first parameter */
174 #define RET1 2 /* register for return values. */
177 wbat (word x
, word v
)
179 if (((uword
)x
) >= cpu
.asregs
.msize
)
182 fprintf (stderr
, "byte write to 0x%x outside memory range\n", x
);
184 cpu
.asregs
.exception
= SIGSEGV
;
188 unsigned char *p
= cpu
.mem
+ x
;
194 wlat (word x
, word v
)
196 if (((uword
)x
) >= cpu
.asregs
.msize
)
199 fprintf (stderr
, "word write to 0x%x outside memory range\n", x
);
201 cpu
.asregs
.exception
= SIGSEGV
;
208 fprintf (stderr
, "word write to unaligned memory address: 0x%x\n", x
);
210 cpu
.asregs
.exception
= SIGBUS
;
212 else if (! target_big_endian
)
214 unsigned char * p
= cpu
.mem
+ x
;
222 unsigned char * p
= cpu
.mem
+ x
;
232 what (word x
, word v
)
234 if (((uword
)x
) >= cpu
.asregs
.msize
)
237 fprintf (stderr
, "short write to 0x%x outside memory range\n", x
);
239 cpu
.asregs
.exception
= SIGSEGV
;
246 fprintf (stderr
, "short write to unaligned memory address: 0x%x\n",
249 cpu
.asregs
.exception
= SIGBUS
;
251 else if (! target_big_endian
)
253 unsigned char * p
= cpu
.mem
+ x
;
259 unsigned char * p
= cpu
.mem
+ x
;
266 /* Read functions. */
270 if (((uword
)x
) >= cpu
.asregs
.msize
)
273 fprintf (stderr
, "byte read from 0x%x outside memory range\n", x
);
275 cpu
.asregs
.exception
= SIGSEGV
;
280 unsigned char * p
= cpu
.mem
+ x
;
288 if (((uword
) x
) >= cpu
.asregs
.msize
)
291 fprintf (stderr
, "word read from 0x%x outside memory range\n", x
);
293 cpu
.asregs
.exception
= SIGSEGV
;
301 fprintf (stderr
, "word read from unaligned address: 0x%x\n", x
);
303 cpu
.asregs
.exception
= SIGBUS
;
306 else if (! target_big_endian
)
308 unsigned char * p
= cpu
.mem
+ x
;
309 return (p
[3] << 24) | (p
[2] << 16) | (p
[1] << 8) | p
[0];
313 unsigned char * p
= cpu
.mem
+ x
;
314 return (p
[0] << 24) | (p
[1] << 16) | (p
[2] << 8) | p
[3];
322 if (((uword
)x
) >= cpu
.asregs
.msize
)
325 fprintf (stderr
, "short read from 0x%x outside memory range\n", x
);
327 cpu
.asregs
.exception
= SIGSEGV
;
335 fprintf (stderr
, "short read from unaligned address: 0x%x\n", x
);
337 cpu
.asregs
.exception
= SIGBUS
;
340 else if (! target_big_endian
)
342 unsigned char * p
= cpu
.mem
+ x
;
343 return (p
[1] << 8) | p
[0];
347 unsigned char * p
= cpu
.mem
+ x
;
348 return (p
[0] << 8) | p
[1];
354 /* Default to a 8 Mbyte (== 2^23) memory space. */
355 static int sim_memory_size
= 23;
357 #define MEM_SIZE_FLOOR 64
361 sim_memory_size
= power
;
362 cpu
.asregs
.msize
= 1 << sim_memory_size
;
367 /* Watch out for the '0 count' problem. There's probably a better
368 way.. e.g., why do we use 64 here? */
369 if (cpu
.asregs
.msize
< 64) /* Ensure a boundary. */
370 cpu
.mem
= (unsigned char *) calloc (64, (64 + cpu
.asregs
.msize
) / 64);
372 cpu
.mem
= (unsigned char *) calloc (64, cpu
.asregs
.msize
/ 64);
378 "Not enough VM for simulation of %lu bytes of RAM\n",
381 cpu
.asregs
.msize
= 1;
382 cpu
.mem
= (unsigned char *) calloc (1, 1);
389 if (cpu
.asregs
.msize
!= (1 << sim_memory_size
))
390 sim_size (sim_memory_size
);
394 set_initial_gprs (void)
398 unsigned long memsize
;
402 /* Set up machine just out of reset. */
406 memsize
= cpu
.asregs
.msize
/ (1024 * 1024);
408 if (issue_messages
> 1)
409 fprintf (stderr
, "Simulated memory of %lu Mbytes (0x0 .. 0x%08lx)\n",
410 memsize
, cpu
.asregs
.msize
- 1);
412 /* Clean out the GPRs and alternate GPRs. */
413 for (i
= 0; i
< 16; i
++)
415 cpu
.asregs
.gregs
[i
] = 0;
416 cpu
.asregs
.alt_gregs
[i
] = 0;
419 /* Make our register set point to the right place. */
421 cpu
.asregs
.active_gregs
= &cpu
.asregs
.alt_gregs
[0];
423 cpu
.asregs
.active_gregs
= &cpu
.asregs
.gregs
[0];
425 /* ABI specifies initial values for these registers. */
426 cpu
.gr
[0] = cpu
.asregs
.msize
- 4;
428 /* dac fix, the stack address must be 8-byte aligned! */
429 cpu
.gr
[0] = cpu
.gr
[0] - cpu
.gr
[0] % 8;
433 cpu
.gr
[PARM4
] = cpu
.gr
[0];
436 /* Functions so that trapped open/close don't interfere with the
437 parent's functions. We say that we can't close the descriptors
438 that we didn't open. exit() and cleanup() get in trouble here,
439 to some extent. That's the price of emulation. */
441 unsigned char opened
[100];
446 if (fd
< 0 || fd
> NUM_ELEM (opened
))
455 if (fd
< 0 || fd
> NUM_ELEM (opened
))
464 if (fd
< 0 || fd
> NUM_ELEM (opened
))
475 switch ((unsigned long) (cpu
.gr
[TRAPCODE
]))
478 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
479 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
480 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
481 cpu
.gr
[RET1
] = callback
->read (callback
, a
[0], (char *) a
[1], a
[2]);
485 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
486 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
487 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
488 cpu
.gr
[RET1
] = (int)callback
->write (callback
, a
[0], (char *) a
[1], a
[2]);
492 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
493 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
494 /* a[2] = (unsigned long) (cpu.gr[PARM3]); */
495 cpu
.gr
[RET1
] = callback
->open (callback
, (char *) a
[0], a
[1]);
496 log_open (cpu
.gr
[RET1
]);
500 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
501 /* Watch out for debugger's files. */
502 if (is_opened (a
[0]))
505 cpu
.gr
[RET1
] = callback
->close (callback
, a
[0]);
509 /* Don't let him close it. */
515 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
516 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
517 cpu
.gr
[RET1
] = link ((char *) a
[0], (char *) a
[1]);
521 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
522 cpu
.gr
[RET1
] = callback
->unlink (callback
, (char *) a
[0]);
526 /* handle time(0) vs time(&var) */
527 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
529 a
[0] += (unsigned long) cpu
.mem
;
530 cpu
.gr
[RET1
] = callback
->time (callback
, (time_t *) a
[0]);
534 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
535 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
536 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
537 cpu
.gr
[RET1
] = callback
->lseek (callback
, a
[0], a
[1], a
[2]);
541 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
542 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
543 cpu
.gr
[RET1
] = access ((char *) a
[0], a
[1]);
547 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
549 cpu
.gr
[RET1
] = times ((char *)a
[0]);
552 /* Give him simulated cycles for utime
553 and an instruction count for stime. */
562 t
.tms_utime
= cpu
.asregs
.cycles
;
563 t
.tms_stime
= cpu
.asregs
.insts
;
564 t
.tms_cutime
= t
.tms_utime
;
565 t
.tms_cstime
= t
.tms_stime
;
567 memcpy ((struct tms
*)(a
[0]), &t
, sizeof (t
));
569 cpu
.gr
[RET1
] = cpu
.asregs
.cycles
;
575 /* Historically this was sbrk(), but no one used it, and the
576 implementation didn't actually work, so it's a stub now. */
577 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
583 fprintf (stderr
, "WARNING: sys call %d unimplemented\n",
590 process_stub (int what
)
592 /* These values should match those in libgloss/mcore/syscalls.s. */
599 case 10: /* _unlink */
600 case 19: /* _lseek */
601 case 43: /* _times */
602 cpu
.gr
[TRAPCODE
] = what
;
608 fprintf (stderr
, "Unhandled stub opcode: %d\n", what
);
619 cpu
.asregs
.exception
= SIGQUIT
;
628 a
[0] = (unsigned long)(cpu
.mem
+ cpu
.gr
[PARM1
]);
630 for (s
= (unsigned char *)a
[0], i
= 1 ; *s
&& i
< 6 ; s
++)
635 a
[i
] = (unsigned long)(cpu
.mem
+ cpu
.gr
[PARM1
+i
]);
637 a
[i
] = cpu
.gr
[i
+PARM1
];
642 cpu
.gr
[RET1
] = printf ((char *)a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
648 fprintf (stderr
, "WARNING: scanf unimplemented\n");
652 cpu
.gr
[RET1
] = cpu
.asregs
.insts
;
656 process_stub (cpu
.gr
[1]);
661 fprintf (stderr
, "Unhandled util code: %x\n", what
);
666 /* For figuring out whether we carried; addc/subc use this. */
668 iu_carry (unsigned long a
, unsigned long b
, int cin
)
672 x
= (a
& 0xffff) + (b
& 0xffff) + cin
;
673 x
= (x
>> 16) + (a
>> 16) + (b
>> 16);
679 #define WATCHFUNCTIONS 1
680 #ifdef WATCHFUNCTIONS
697 #define RD (inst & 0xF)
698 #define RS ((inst >> 4) & 0xF)
699 #define RX ((inst >> 8) & 0xF)
700 #define IMM5 ((inst >> 4) & 0x1F)
701 #define IMM4 ((inst) & 0xF)
703 static int tracing
= 0;
706 sim_resume (SIM_DESC sd
, int step
, int siggnal
)
719 cpu
.asregs
.exception
= step
? SIGTRAP
: 0;
722 /* Fetch the initial instructions that we'll decode. */
723 ibuf
= rlat (pc
& 0xFFFFFFFC);
730 /* make our register set point to the right place */
732 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
734 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
736 /* make a hash to speed exec loop, hope it's nonzero */
739 for (w
= 1; w
<= ENDWL
; w
++)
740 WLhash
= WLhash
& WL
[w
];
750 if (! target_big_endian
)
753 inst
= ibuf
& 0xFFFF;
758 if (! target_big_endian
)
759 inst
= ibuf
& 0xFFFF;
764 #ifdef WATCHFUNCTIONS
765 /* now scan list of watch addresses, if match, count it and
766 note return address and count cycles until pc=return address */
768 if ((WLincyc
== 1) && (pc
== WLendpc
))
770 cycs
= (cpu
.asregs
.cycles
+ (insts
+ bonus_cycles
+
771 (memops
* memcycles
)) - WLbcyc
);
773 if (WLcnts
[WLW
] == 1)
780 if (cycs
> WLmax
[WLW
])
785 if (cycs
< WLmin
[WLW
])
795 /* Optimize with a hash to speed loop. */
798 if ((WLhash
== 0) || ((WLhash
& pc
) != 0))
800 for (w
=1; w
<= ENDWL
; w
++)
805 WLbcyc
= cpu
.asregs
.cycles
+ insts
806 + bonus_cycles
+ (memops
* memcycles
);
807 WLendpc
= cpu
.gr
[15];
818 fprintf (stderr
, "%.4x: inst = %.4x ", pc
, inst
);
833 cpu
.asregs
.exception
= SIGTRAP
;
846 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
848 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
857 cpu
.asregs
.active_gregs
= &cpu
.asregs
.alt_gregs
[0];
859 cpu
.asregs
.active_gregs
= &cpu
.asregs
.gregs
[0];
864 fprintf (stderr
, "WARNING: stop unimplemented\n");
869 fprintf (stderr
, "WARNING: wait unimplemented\n");
874 fprintf (stderr
, "WARNING: doze unimplemented\n");
878 cpu
.asregs
.exception
= SIGILL
; /* illegal */
881 case 0x8: /* trap 0 */
882 case 0xA: /* trap 2 */
883 case 0xB: /* trap 3 */
884 cpu
.asregs
.exception
= SIGTRAP
;
887 case 0xC: /* trap 4 */
888 case 0xD: /* trap 5 */
889 case 0xE: /* trap 6 */
890 cpu
.asregs
.exception
= SIGILL
; /* illegal */
893 case 0xF: /* trap 7 */
894 cpu
.asregs
.exception
= SIGTRAP
; /* integer div-by-0 */
897 case 0x9: /* trap 1 */
904 cpu
.asregs
.exception
= SIGILL
; /* illegal */
908 cpu
.gr
[RD
] = C_VALUE();
911 cpu
.gr
[RD
] = C_OFF();
915 word addr
= cpu
.gr
[RD
];
916 int regno
= 4; /* always r4-r7 */
922 cpu
.gr
[regno
] = rlat(addr
);
926 while ((regno
&0x3) != 0);
931 word addr
= cpu
.gr
[RD
];
932 int regno
= 4; /* always r4-r7 */
938 wlat(addr
, cpu
.gr
[regno
]);
942 while ((regno
& 0x3) != 0);
947 word addr
= cpu
.gr
[0];
950 /* bonus cycle is really only needed if
951 the next insn shifts the last reg loaded.
958 cpu
.gr
[regno
] = rlat(addr
);
966 word addr
= cpu
.gr
[0];
969 /* this should be removed! */
970 /* bonus_cycles ++; */
972 memops
+= 16 - regno
;
975 wlat(addr
, cpu
.gr
[regno
]);
983 cpu
.gr
[RD
] -= C_VALUE();
986 cpu
.gr
[RD
] -= C_OFF();
989 cpu
.gr
[RD
] += C_VALUE();
992 cpu
.gr
[RD
] += C_OFF();
996 if (tracing
&& RD
== 15)
997 fprintf (stderr
, "Func return, r2 = %x, r3 = %x\n",
998 cpu
.gr
[2], cpu
.gr
[3]);
1012 for (i
= 0; !(tmp
& 0x80000000) && i
< 32; i
++)
1017 case 0xF: /* brev */
1021 tmp
= ((tmp
& 0xaaaaaaaa) >> 1) | ((tmp
& 0x55555555) << 1);
1022 tmp
= ((tmp
& 0xcccccccc) >> 2) | ((tmp
& 0x33333333) << 2);
1023 tmp
= ((tmp
& 0xf0f0f0f0) >> 4) | ((tmp
& 0x0f0f0f0f) << 4);
1024 tmp
= ((tmp
& 0xff00ff00) >> 8) | ((tmp
& 0x00ff00ff) << 8);
1025 cpu
.gr
[RD
] = ((tmp
& 0xffff0000) >> 16) | ((tmp
& 0x0000ffff) << 16);
1033 case 0x0: /* xtrb3 */
1034 cpu
.gr
[1] = (cpu
.gr
[RD
]) & 0xFF;
1035 NEW_C (cpu
.gr
[RD
] != 0);
1037 case 0x1: /* xtrb2 */
1038 cpu
.gr
[1] = (cpu
.gr
[RD
]>>8) & 0xFF;
1039 NEW_C (cpu
.gr
[RD
] != 0);
1041 case 0x2: /* xtrb1 */
1042 cpu
.gr
[1] = (cpu
.gr
[RD
]>>16) & 0xFF;
1043 NEW_C (cpu
.gr
[RD
] != 0);
1045 case 0x3: /* xtrb0 */
1046 cpu
.gr
[1] = (cpu
.gr
[RD
]>>24) & 0xFF;
1047 NEW_C (cpu
.gr
[RD
] != 0);
1049 case 0x4: /* zextb */
1050 cpu
.gr
[RD
] &= 0x000000FF;
1052 case 0x5: /* sextb */
1061 case 0x6: /* zexth */
1062 cpu
.gr
[RD
] &= 0x0000FFFF;
1064 case 0x7: /* sexth */
1073 case 0x8: /* declt */
1075 NEW_C ((long)cpu
.gr
[RD
] < 0);
1077 case 0x9: /* tstnbz */
1079 word tmp
= cpu
.gr
[RD
];
1080 NEW_C ((tmp
& 0xFF000000) != 0 &&
1081 (tmp
& 0x00FF0000) != 0 && (tmp
& 0x0000FF00) != 0 &&
1082 (tmp
& 0x000000FF) != 0);
1085 case 0xA: /* decgt */
1087 NEW_C ((long)cpu
.gr
[RD
] > 0);
1089 case 0xB: /* decne */
1091 NEW_C ((long)cpu
.gr
[RD
] != 0);
1093 case 0xC: /* clrt */
1097 case 0xD: /* clrf */
1102 if (cpu
.gr
[RD
] & 0x80000000)
1103 cpu
.gr
[RD
] = ~cpu
.gr
[RD
] + 1;
1106 cpu
.gr
[RD
] = ~cpu
.gr
[RD
];
1110 case 0x02: /* movt */
1112 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1114 case 0x03: /* mult */
1115 /* consume 2 bits per cycle from rs, until rs is 0 */
1117 unsigned int t
= cpu
.gr
[RS
];
1119 for (ticks
= 0; t
!= 0 ; t
>>= 2)
1121 bonus_cycles
+= ticks
;
1123 bonus_cycles
+= 2; /* min. is 3, so add 2, plus ticks above */
1125 fprintf (stderr
, " mult %x by %x to give %x",
1126 cpu
.gr
[RD
], cpu
.gr
[RS
], cpu
.gr
[RD
] * cpu
.gr
[RS
]);
1127 cpu
.gr
[RD
] = cpu
.gr
[RD
] * cpu
.gr
[RS
];
1129 case 0x04: /* loopt */
1132 pc
+= (IMM4
<< 1) - 32;
1136 --cpu
.gr
[RS
]; /* not RD! */
1137 NEW_C (((long)cpu
.gr
[RS
]) > 0);
1139 case 0x05: /* subu */
1140 cpu
.gr
[RD
] -= cpu
.gr
[RS
];
1142 case 0x06: /* addc */
1144 unsigned long tmp
, a
, b
;
1147 cpu
.gr
[RD
] = a
+ b
+ C_VALUE ();
1148 tmp
= iu_carry (a
, b
, C_VALUE ());
1152 case 0x07: /* subc */
1154 unsigned long tmp
, a
, b
;
1157 cpu
.gr
[RD
] = a
- b
+ C_VALUE () - 1;
1158 tmp
= iu_carry (a
,~b
, C_VALUE ());
1162 case 0x08: /* illegal */
1163 case 0x09: /* illegal*/
1164 cpu
.asregs
.exception
= SIGILL
;
1166 case 0x0A: /* movf */
1168 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1170 case 0x0B: /* lsr */
1172 unsigned long dst
, src
;
1175 /* We must not rely solely upon the native shift operations, since they
1176 may not match the M*Core's behaviour on boundary conditions. */
1177 dst
= src
> 31 ? 0 : dst
>> src
;
1181 case 0x0C: /* cmphs */
1182 NEW_C ((unsigned long )cpu
.gr
[RD
] >=
1183 (unsigned long)cpu
.gr
[RS
]);
1185 case 0x0D: /* cmplt */
1186 NEW_C ((long)cpu
.gr
[RD
] < (long)cpu
.gr
[RS
]);
1188 case 0x0E: /* tst */
1189 NEW_C ((cpu
.gr
[RD
] & cpu
.gr
[RS
]) != 0);
1191 case 0x0F: /* cmpne */
1192 NEW_C (cpu
.gr
[RD
] != cpu
.gr
[RS
]);
1194 case 0x10: case 0x11: /* mfcr */
1198 if (r
<= LAST_VALID_CREG
)
1199 cpu
.gr
[RD
] = cpu
.cr
[r
];
1201 cpu
.asregs
.exception
= SIGILL
;
1205 case 0x12: /* mov */
1206 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1208 fprintf (stderr
, "MOV %x into reg %d", cpu
.gr
[RD
], RD
);
1211 case 0x13: /* bgenr */
1212 if (cpu
.gr
[RS
] & 0x20)
1215 cpu
.gr
[RD
] = 1 << (cpu
.gr
[RS
] & 0x1F);
1218 case 0x14: /* rsub */
1219 cpu
.gr
[RD
] = cpu
.gr
[RS
] - cpu
.gr
[RD
];
1222 case 0x15: /* ixw */
1223 cpu
.gr
[RD
] += cpu
.gr
[RS
]<<2;
1226 case 0x16: /* and */
1227 cpu
.gr
[RD
] &= cpu
.gr
[RS
];
1230 case 0x17: /* xor */
1231 cpu
.gr
[RD
] ^= cpu
.gr
[RS
];
1234 case 0x18: case 0x19: /* mtcr */
1238 if (r
<= LAST_VALID_CREG
)
1239 cpu
.cr
[r
] = cpu
.gr
[RD
];
1241 cpu
.asregs
.exception
= SIGILL
;
1243 /* we might have changed register sets... */
1245 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
1247 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
1251 case 0x1A: /* asr */
1252 /* We must not rely solely upon the native shift operations, since they
1253 may not match the M*Core's behaviour on boundary conditions. */
1254 if (cpu
.gr
[RS
] > 30)
1255 cpu
.gr
[RD
] = ((long) cpu
.gr
[RD
]) < 0 ? -1 : 0;
1257 cpu
.gr
[RD
] = (long) cpu
.gr
[RD
] >> cpu
.gr
[RS
];
1260 case 0x1B: /* lsl */
1261 /* We must not rely solely upon the native shift operations, since they
1262 may not match the M*Core's behaviour on boundary conditions. */
1263 cpu
.gr
[RD
] = cpu
.gr
[RS
] > 31 ? 0 : cpu
.gr
[RD
] << cpu
.gr
[RS
];
1266 case 0x1C: /* addu */
1267 cpu
.gr
[RD
] += cpu
.gr
[RS
];
1270 case 0x1D: /* ixh */
1271 cpu
.gr
[RD
] += cpu
.gr
[RS
] << 1;
1275 cpu
.gr
[RD
] |= cpu
.gr
[RS
];
1278 case 0x1F: /* andn */
1279 cpu
.gr
[RD
] &= ~cpu
.gr
[RS
];
1281 case 0x20: case 0x21: /* addi */
1283 cpu
.gr
[RD
] + (IMM5
+ 1);
1285 case 0x22: case 0x23: /* cmplti */
1287 int tmp
= (IMM5
+ 1);
1288 if (cpu
.gr
[RD
] < tmp
)
1298 case 0x24: case 0x25: /* subi */
1300 cpu
.gr
[RD
] - (IMM5
+ 1);
1302 case 0x26: case 0x27: /* illegal */
1303 cpu
.asregs
.exception
= SIGILL
;
1305 case 0x28: case 0x29: /* rsubi */
1309 case 0x2A: case 0x2B: /* cmpnei */
1310 if (cpu
.gr
[RD
] != IMM5
)
1320 case 0x2C: case 0x2D: /* bmaski, divu */
1322 unsigned imm
= IMM5
;
1328 unsigned int rx
, r1
;
1334 /* unsigned divide */
1335 cpu
.gr
[RD
] = (word
) ((unsigned int) cpu
.gr
[RD
] / (unsigned int)cpu
.gr
[1] );
1337 /* compute bonus_cycles for divu */
1338 for (r1nlz
= 0; ((r1
& 0x80000000) == 0) && (r1nlz
< 32); r1nlz
++)
1341 for (rxnlz
= 0; ((rx
& 0x80000000) == 0) && (rxnlz
< 32); rxnlz
++)
1347 exe
+= 5 + r1nlz
- rxnlz
;
1349 if (exe
>= (2 * memcycles
- 1))
1351 bonus_cycles
+= exe
- (2 * memcycles
) + 1;
1354 else if (imm
== 0 || imm
>= 8)
1360 cpu
.gr
[RD
] = (1 << imm
) - 1;
1365 cpu
.asregs
.exception
= SIGILL
;
1369 case 0x2E: case 0x2F: /* andi */
1370 cpu
.gr
[RD
] = cpu
.gr
[RD
] & IMM5
;
1372 case 0x30: case 0x31: /* bclri */
1373 cpu
.gr
[RD
] = cpu
.gr
[RD
] & ~(1<<IMM5
);
1375 case 0x32: case 0x33: /* bgeni, divs */
1377 unsigned imm
= IMM5
;
1384 /* compute bonus_cycles for divu */
1389 if (((rx
< 0) && (r1
> 0)) || ((rx
>= 0) && (r1
< 0)))
1397 /* signed divide, general registers are of type int, so / op is OK */
1398 cpu
.gr
[RD
] = cpu
.gr
[RD
] / cpu
.gr
[1];
1400 for (r1nlz
= 0; ((r1
& 0x80000000) == 0) && (r1nlz
< 32) ; r1nlz
++ )
1403 for (rxnlz
= 0; ((rx
& 0x80000000) == 0) && (rxnlz
< 32) ; rxnlz
++ )
1409 exe
+= 6 + r1nlz
- rxnlz
+ sc
;
1411 if (exe
>= (2 * memcycles
- 1))
1413 bonus_cycles
+= exe
- (2 * memcycles
) + 1;
1419 cpu
.gr
[RD
] = (1 << IMM5
);
1424 cpu
.asregs
.exception
= SIGILL
;
1428 case 0x34: case 0x35: /* bseti */
1429 cpu
.gr
[RD
] = cpu
.gr
[RD
] | (1 << IMM5
);
1431 case 0x36: case 0x37: /* btsti */
1432 NEW_C (cpu
.gr
[RD
] >> IMM5
);
1434 case 0x38: case 0x39: /* xsr, rotli */
1436 unsigned imm
= IMM5
;
1437 unsigned long tmp
= cpu
.gr
[RD
];
1443 cpu
.gr
[RD
] = (cbit
<< 31) | (tmp
>> 1);
1446 cpu
.gr
[RD
] = (tmp
<< imm
) | (tmp
>> (32 - imm
));
1449 case 0x3A: case 0x3B: /* asrc, asri */
1451 unsigned imm
= IMM5
;
1452 long tmp
= cpu
.gr
[RD
];
1456 cpu
.gr
[RD
] = tmp
>> 1;
1459 cpu
.gr
[RD
] = tmp
>> imm
;
1462 case 0x3C: case 0x3D: /* lslc, lsli */
1464 unsigned imm
= IMM5
;
1465 unsigned long tmp
= cpu
.gr
[RD
];
1469 cpu
.gr
[RD
] = tmp
<< 1;
1472 cpu
.gr
[RD
] = tmp
<< imm
;
1475 case 0x3E: case 0x3F: /* lsrc, lsri */
1477 unsigned imm
= IMM5
;
1478 unsigned long tmp
= cpu
.gr
[RD
];
1482 cpu
.gr
[RD
] = tmp
>> 1;
1485 cpu
.gr
[RD
] = tmp
>> imm
;
1488 case 0x40: case 0x41: case 0x42: case 0x43:
1489 case 0x44: case 0x45: case 0x46: case 0x47:
1490 case 0x48: case 0x49: case 0x4A: case 0x4B:
1491 case 0x4C: case 0x4D: case 0x4E: case 0x4F:
1492 cpu
.asregs
.exception
= SIGILL
;
1497 case 0x51: case 0x52: case 0x53:
1498 case 0x54: case 0x55: case 0x56: case 0x57:
1499 case 0x58: case 0x59: case 0x5A: case 0x5B:
1500 case 0x5C: case 0x5D: case 0x5E: case 0x5F:
1501 cpu
.asregs
.exception
= SIGILL
;
1503 case 0x60: case 0x61: case 0x62: case 0x63: /* movi */
1504 case 0x64: case 0x65: case 0x66: case 0x67:
1505 cpu
.gr
[RD
] = (inst
>> 4) & 0x7F;
1507 case 0x68: case 0x69: case 0x6A: case 0x6B:
1508 case 0x6C: case 0x6D: case 0x6E: case 0x6F: /* illegal */
1509 cpu
.asregs
.exception
= SIGILL
;
1511 case 0x71: case 0x72: case 0x73:
1512 case 0x74: case 0x75: case 0x76: case 0x77:
1513 case 0x78: case 0x79: case 0x7A: case 0x7B:
1514 case 0x7C: case 0x7D: case 0x7E: /* lrw */
1515 cpu
.gr
[RX
] = rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC);
1517 fprintf (stderr
, "LRW of 0x%x from 0x%x to reg %d",
1518 rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC),
1519 (pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC, RX
);
1522 case 0x7F: /* jsri */
1525 fprintf (stderr
, "func call: r2 = %x r3 = %x r4 = %x r5 = %x r6 = %x r7 = %x\n",
1526 cpu
.gr
[2], cpu
.gr
[3], cpu
.gr
[4], cpu
.gr
[5], cpu
.gr
[6], cpu
.gr
[7]);
1527 case 0x70: /* jmpi */
1528 pc
= rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC);
1534 case 0x80: case 0x81: case 0x82: case 0x83:
1535 case 0x84: case 0x85: case 0x86: case 0x87:
1536 case 0x88: case 0x89: case 0x8A: case 0x8B:
1537 case 0x8C: case 0x8D: case 0x8E: case 0x8F: /* ld */
1538 cpu
.gr
[RX
] = rlat (cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C));
1540 fprintf (stderr
, "load reg %d from 0x%x with 0x%x",
1542 cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C), cpu
.gr
[RX
]);
1545 case 0x90: case 0x91: case 0x92: case 0x93:
1546 case 0x94: case 0x95: case 0x96: case 0x97:
1547 case 0x98: case 0x99: case 0x9A: case 0x9B:
1548 case 0x9C: case 0x9D: case 0x9E: case 0x9F: /* st */
1549 wlat (cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C), cpu
.gr
[RX
]);
1551 fprintf (stderr
, "store reg %d (containing 0x%x) to 0x%x",
1553 cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C));
1556 case 0xA0: case 0xA1: case 0xA2: case 0xA3:
1557 case 0xA4: case 0xA5: case 0xA6: case 0xA7:
1558 case 0xA8: case 0xA9: case 0xAA: case 0xAB:
1559 case 0xAC: case 0xAD: case 0xAE: case 0xAF: /* ld.b */
1560 cpu
.gr
[RX
] = rbat (cpu
.gr
[RD
] + RS
);
1563 case 0xB0: case 0xB1: case 0xB2: case 0xB3:
1564 case 0xB4: case 0xB5: case 0xB6: case 0xB7:
1565 case 0xB8: case 0xB9: case 0xBA: case 0xBB:
1566 case 0xBC: case 0xBD: case 0xBE: case 0xBF: /* st.b */
1567 wbat (cpu
.gr
[RD
] + RS
, cpu
.gr
[RX
]);
1570 case 0xC0: case 0xC1: case 0xC2: case 0xC3:
1571 case 0xC4: case 0xC5: case 0xC6: case 0xC7:
1572 case 0xC8: case 0xC9: case 0xCA: case 0xCB:
1573 case 0xCC: case 0xCD: case 0xCE: case 0xCF: /* ld.h */
1574 cpu
.gr
[RX
] = rhat (cpu
.gr
[RD
] + ((inst
>> 3) & 0x001E));
1577 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
1578 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
1579 case 0xD8: case 0xD9: case 0xDA: case 0xDB:
1580 case 0xDC: case 0xDD: case 0xDE: case 0xDF: /* st.h */
1581 what (cpu
.gr
[RD
] + ((inst
>> 3) & 0x001E), cpu
.gr
[RX
]);
1584 case 0xE8: case 0xE9: case 0xEA: case 0xEB:
1585 case 0xEC: case 0xED: case 0xEE: case 0xEF: /* bf */
1589 disp
= inst
& 0x03FF;
1597 case 0xE0: case 0xE1: case 0xE2: case 0xE3:
1598 case 0xE4: case 0xE5: case 0xE6: case 0xE7: /* bt */
1602 disp
= inst
& 0x03FF;
1611 case 0xF8: case 0xF9: case 0xFA: case 0xFB:
1612 case 0xFC: case 0xFD: case 0xFE: case 0xFF: /* bsr */
1614 case 0xF0: case 0xF1: case 0xF2: case 0xF3:
1615 case 0xF4: case 0xF5: case 0xF6: case 0xF7: /* br */
1618 disp
= inst
& 0x03FF;
1630 fprintf (stderr
, "\n");
1634 /* Do not let him fetch from a bad address! */
1635 if (((uword
)pc
) >= cpu
.asregs
.msize
)
1638 fprintf (stderr
, "PC loaded at 0x%x is outside of available memory! (0x%x)\n", oldpc
, pc
);
1640 cpu
.asregs
.exception
= SIGSEGV
;
1644 ibuf
= rlat (pc
& 0xFFFFFFFC);
1649 while (!cpu
.asregs
.exception
);
1651 /* Hide away the things we've cached while executing. */
1653 cpu
.asregs
.insts
+= insts
; /* instructions done ... */
1654 cpu
.asregs
.cycles
+= insts
; /* and each takes a cycle */
1655 cpu
.asregs
.cycles
+= bonus_cycles
; /* and extra cycles for branches */
1656 cpu
.asregs
.cycles
+= memops
* memcycles
; /* and memop cycle delays */
1661 sim_write (SIM_DESC sd
, SIM_ADDR addr
, const unsigned char *buffer
, int size
)
1666 memcpy (& cpu
.mem
[addr
], buffer
, size
);
1672 sim_read (SIM_DESC sd
, SIM_ADDR addr
, unsigned char *buffer
, int size
)
1677 memcpy (buffer
, & cpu
.mem
[addr
], size
);
1684 sim_store_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
1688 if (rn
< NUM_MCORE_REGS
&& rn
>= 0)
1694 /* misalignment safe */
1695 ival
= mcore_extract_unsigned_integer (memory
, 4);
1696 cpu
.asints
[rn
] = ival
;
1706 sim_fetch_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
1710 if (rn
< NUM_MCORE_REGS
&& rn
>= 0)
1714 long ival
= cpu
.asints
[rn
];
1716 /* misalignment-safe */
1717 mcore_store_unsigned_integer (memory
, 4, ival
);
1728 sim_trace (SIM_DESC sd
)
1732 sim_resume (sd
, 0, 0);
1740 sim_stop_reason (SIM_DESC sd
, enum sim_stop
*reason
, int *sigrc
)
1742 if (cpu
.asregs
.exception
== SIGQUIT
)
1744 * reason
= sim_exited
;
1745 * sigrc
= cpu
.gr
[PARM1
];
1749 * reason
= sim_stopped
;
1750 * sigrc
= cpu
.asregs
.exception
;
1756 sim_stop (SIM_DESC sd
)
1758 cpu
.asregs
.exception
= SIGINT
;
1764 sim_info (SIM_DESC sd
, int verbose
)
1766 #ifdef WATCHFUNCTIONS
1769 double virttime
= cpu
.asregs
.cycles
/ 36.0e6
;
1771 callback
->printf_filtered (callback
, "\n\n# instructions executed %10d\n",
1773 callback
->printf_filtered (callback
, "# cycles %10d\n",
1775 callback
->printf_filtered (callback
, "# pipeline stalls %10d\n",
1777 callback
->printf_filtered (callback
, "# virtual time taken %10.4f\n",
1780 #ifdef WATCHFUNCTIONS
1781 callback
->printf_filtered (callback
, "\nNumber of watched functions: %d\n",
1786 for (w
= 1; w
<= ENDWL
; w
++)
1788 callback
->printf_filtered (callback
, "WL = %s %8x\n",WLstr
[w
],WL
[w
]);
1789 callback
->printf_filtered (callback
, " calls = %d, cycles = %d\n",
1790 WLcnts
[w
],WLcyc
[w
]);
1793 callback
->printf_filtered (callback
,
1794 " maxcpc = %d, mincpc = %d, avecpc = %d\n",
1795 WLmax
[w
],WLmin
[w
],WLcyc
[w
]/WLcnts
[w
]);
1799 callback
->printf_filtered (callback
,
1800 "Total cycles for watched functions: %d\n",wcyc
);
1806 unsigned char sa_machtype
[2];
1807 unsigned char sa_magic
[2];
1808 unsigned char sa_tsize
[4];
1809 unsigned char sa_dsize
[4];
1810 unsigned char sa_bsize
[4];
1811 unsigned char sa_syms
[4];
1812 unsigned char sa_entry
[4];
1813 unsigned char sa_trelo
[4];
1814 unsigned char sa_drelo
[4];
1817 #define LONG(x) (((x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
1818 #define SHORT(x) (((x)[0]<<8)|(x)[1])
1821 sim_open (SIM_OPEN_KIND kind
, host_callback
*cb
, struct bfd
*abfd
, char **argv
)
1823 int osize
= sim_memory_size
;
1827 if (kind
== SIM_OPEN_STANDALONE
)
1830 /* Discard and reacquire memory -- start with a clean slate. */
1831 sim_size (1); /* small */
1832 sim_size (osize
); /* and back again */
1834 set_initial_gprs (); /* Reset the GPR registers. */
1836 /* Fudge our descriptor for now. */
1837 return (SIM_DESC
) 1;
1841 sim_close (SIM_DESC sd
, int quitting
)
1847 sim_load (SIM_DESC sd
, const char *prog
, bfd
*abfd
, int from_tty
)
1849 /* Do the right thing for ELF executables; this turns out to be
1850 just about the right thing for any object format that:
1851 - we crack using BFD routines
1852 - follows the traditional UNIX text/data/bss layout
1853 - calls the bss section ".bss". */
1855 extern bfd
* sim_load_file (); /* ??? Don't know where this should live. */
1860 handle
= bfd_openr (prog
, 0); /* could be "mcore" */
1864 printf("``%s'' could not be opened.\n", prog
);
1868 /* Makes sure that we have an object file, also cleans gets the
1869 section headers in place. */
1870 if (!bfd_check_format (handle
, bfd_object
))
1872 /* wasn't an object file */
1874 printf ("``%s'' is not appropriate object file.\n", prog
);
1878 /* Clean up after ourselves. */
1881 /* XXX: do we need to free the s_bss and handle structures? */
1884 /* from sh -- dac */
1885 prog_bfd
= sim_load_file (sd
, myname
, callback
, prog
, abfd
,
1886 sim_kind
== SIM_OPEN_DEBUG
,
1888 if (prog_bfd
== NULL
)
1891 target_big_endian
= bfd_big_endian (prog_bfd
);
1894 bfd_close (prog_bfd
);
1900 sim_create_inferior (SIM_DESC sd
, struct bfd
*prog_bfd
, char **argv
, char **env
)
1907 unsigned long strings
;
1908 unsigned long pointers
;
1909 unsigned long hi_stack
;
1912 /* Set the initial register set. */
1915 set_initial_gprs ();
1918 hi_stack
= cpu
.asregs
.msize
- 4;
1919 cpu
.asregs
.pc
= bfd_get_start_address (prog_bfd
);
1921 /* Calculate the argument and environment strings. */
1927 l
= strlen (*avp
) + 1; /* include the null */
1928 s_length
+= (l
+ 3) & ~3; /* make it a 4 byte boundary */
1936 l
= strlen (*avp
) + 1; /* include the null */
1937 s_length
+= (l
+ 3) & ~ 3;/* make it a 4 byte boundary */
1941 /* Claim some memory for the pointers and strings. */
1942 pointers
= hi_stack
- sizeof(word
) * (nenv
+1+nargs
+1);
1943 pointers
&= ~3; /* must be 4-byte aligned */
1944 cpu
.gr
[0] = pointers
;
1946 strings
= cpu
.gr
[0] - s_length
;
1947 strings
&= ~3; /* want to make it 4-byte aligned */
1948 cpu
.gr
[0] = strings
;
1949 /* dac fix, the stack address must be 8-byte aligned! */
1950 cpu
.gr
[0] = cpu
.gr
[0] - cpu
.gr
[0] % 8;
1952 /* Loop through the arguments and fill them in. */
1953 cpu
.gr
[PARM1
] = nargs
;
1956 /* No strings to fill in. */
1961 cpu
.gr
[PARM2
] = pointers
;
1965 /* Save where we're putting it. */
1966 wlat (pointers
, strings
);
1968 /* Copy the string. */
1969 l
= strlen (* avp
) + 1;
1970 strcpy ((char *)(cpu
.mem
+ strings
), *avp
);
1972 /* Bump the pointers. */
1978 /* A null to finish the list. */
1983 /* Now do the environment pointers. */
1986 /* No strings to fill in. */
1991 cpu
.gr
[PARM3
] = pointers
;
1996 /* Save where we're putting it. */
1997 wlat (pointers
, strings
);
1999 /* Copy the string. */
2000 l
= strlen (* avp
) + 1;
2001 strcpy ((char *)(cpu
.mem
+ strings
), *avp
);
2003 /* Bump the pointers. */
2009 /* A null to finish the list. */
2018 sim_do_command (SIM_DESC sd
, const char *cmd
)
2020 /* Nothing there yet; it's all an error. */
2024 char ** simargv
= buildargv (cmd
);
2026 if (strcmp (simargv
[0], "watch") == 0)
2028 if ((simargv
[1] == NULL
) || (simargv
[2] == NULL
))
2030 fprintf (stderr
, "Error: missing argument to watch cmd.\n");
2037 WL
[ENDWL
] = strtol (simargv
[2], NULL
, 0);
2038 WLstr
[ENDWL
] = strdup (simargv
[1]);
2039 fprintf (stderr
, "Added %s (%x) to watchlist, #%d\n",WLstr
[ENDWL
],
2043 else if (strcmp (simargv
[0], "dumpmem") == 0)
2048 if (simargv
[1] == NULL
)
2049 fprintf (stderr
, "Error: missing argument to dumpmem cmd.\n");
2051 fprintf (stderr
, "Writing dumpfile %s...",simargv
[1]);
2053 dumpfile
= fopen (simargv
[1], "w");
2055 fwrite (p
, cpu
.asregs
.msize
-1, 1, dumpfile
);
2058 fprintf (stderr
, "done.\n");
2060 else if (strcmp (simargv
[0], "clearstats") == 0)
2062 cpu
.asregs
.cycles
= 0;
2063 cpu
.asregs
.insts
= 0;
2064 cpu
.asregs
.stalls
= 0;
2067 else if (strcmp (simargv
[0], "verbose") == 0)
2073 fprintf (stderr
,"Error: \"%s\" is not a valid M.CORE simulator command.\n",
2081 fprintf (stderr
, "M.CORE sim commands: \n");
2082 fprintf (stderr
, " watch <funcname> <addr>\n");
2083 fprintf (stderr
, " dumpmem <filename>\n");
2084 fprintf (stderr
, " clearstats\n");
2085 fprintf (stderr
, " verbose\n");
2090 sim_set_callbacks (host_callback
*ptr
)
This page took 0.083561 seconds and 5 git commands to generate.