1 /* Simulator for Motorolla's MCore processor
2 Copyright (C) 1999 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 2, or (at your option)
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 along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 #include <sys/times.h>
24 #include <sys/param.h>
25 #include <netinet/in.h> /* for byte ordering macros */
28 #include "libiberty.h"
29 #include "remote-sim.h"
32 #define NUM_ELEM(A) (sizeof (A) / sizeof (A)[0])
36 typedef long int word
;
37 typedef unsigned long int uword
;
39 static unsigned long heap_ptr
= 0;
40 host_callback
* callback
;
44 mcore_extract_unsigned_integer (addr
, 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 %d bytes.",
55 sizeof (unsigned long));
57 /* Start at the most significant end of the integer, and work towards
58 the least significant. */
62 for (p
= startaddr
; p
< endaddr
;)
63 retval
= (retval
<< 8) | * p
++;
70 mcore_store_unsigned_integer (addr
, len
, val
)
76 unsigned char * startaddr
= (unsigned char *)addr
;
77 unsigned char * endaddr
= startaddr
+ len
;
80 for (p
= endaddr
; p
> startaddr
;)
89 This state is maintained in host byte order. The
90 fetch/store register functions must translate between host
91 byte order and the target processor byte order.
92 Keeping this data in target byte order simplifies the register
93 read/write functions. Keeping this data in native order improves
94 the performance of the simulator. Simulation speed is deemed more
97 /* The ordering of the mcore_regset structure is matched in the
98 gdb/config/mcore/tm-mcore.h file in the REGISTER_NAMES macro. */
101 word gregs
[16]; /* primary registers */
102 word alt_gregs
[16]; /* alt register file */
103 word cregs
[32]; /* control registers */
104 word pc
; /* the pc */
111 unsigned char * memory
;
117 struct mcore_regset asregs
;
118 word asints
[1]; /* but accessed larger... */
121 #define LAST_VALID_CREG 32 /* only 0..12 implemented */
122 #define NUM_MCORE_REGS (16 + 16 + LAST_VALID_CREG + 1)
126 static SIM_OPEN_KIND sim_kind
;
127 static char * myname
;
129 static int issue_messages
= 0;
131 #define gr asregs.active_gregs
132 #define cr asregs.cregs
133 #define sr asregs.cregs[0]
134 #define vbr asregs.cregs[1]
135 #define esr asregs.cregs[2]
136 #define fsr asregs.cregs[3]
137 #define epc asregs.cregs[4]
138 #define fpc asregs.cregs[5]
139 #define ss0 asregs.cregs[6]
140 #define ss1 asregs.cregs[7]
141 #define ss2 asregs.cregs[8]
142 #define ss3 asregs.cregs[9]
143 #define ss4 asregs.cregs[10]
144 #define gcr asregs.cregs[11]
145 #define gsr asregs.cregs[12]
146 #define mem asregs.memory
148 /* maniuplate the carry bit */
149 #define C_ON() (cpu.sr & 1)
150 #define C_VALUE() (cpu.sr & 1)
151 #define C_OFF() ((cpu.sr & 1) == 0)
152 #define SET_C() {cpu.sr |= 1;}
153 #define CLR_C() {cpu.sr &= 0xfffffffe;}
154 #define NEW_C(v) {CLR_C(); cpu.sr |= ((v) & 1);}
156 #define SR_AF() ((cpu.sr >> 1) & 1)
158 #define TRAPCODE 1 /* r1 holds which function we want */
159 #define PARM1 2 /* first parameter */
163 #define RET1 2 /* register for return values. */
173 heap_ptr
+= inc_bytes
;
175 if (issue_messages
&& heap_ptr
>cpu
.gr
[0])
176 fprintf (stderr
, "Warning: heap_ptr overlaps stack!\n");
185 if (((uword
)x
) >= cpu
.asregs
.msize
)
188 fprintf (stderr
, "byte write to 0x%x outside memory range\n", x
);
190 cpu
.asregs
.exception
= SIGSEGV
;
194 unsigned char *p
= cpu
.mem
+ x
;
203 if (((uword
)x
) >= cpu
.asregs
.msize
)
206 fprintf (stderr
, "word write to 0x%x outside memory range\n", x
);
208 cpu
.asregs
.exception
= SIGSEGV
;
215 fprintf (stderr
, "word write to unaligned memory address: 0x%x\n", x
);
217 cpu
.asregs
.exception
= SIGBUS
;
221 unsigned char * p
= cpu
.mem
+ x
;
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
;
253 unsigned char * p
= cpu
.mem
+ x
;
265 if (((uword
)x
) >= cpu
.asregs
.msize
)
268 fprintf (stderr
, "byte read from 0x%x outside memory range\n", x
);
270 cpu
.asregs
.exception
= SIGSEGV
;
275 unsigned char * p
= cpu
.mem
+ x
;
284 if (((uword
) x
) >= cpu
.asregs
.msize
)
287 fprintf (stderr
, "word read from 0x%x outside memory range\n", x
);
289 cpu
.asregs
.exception
= SIGSEGV
;
297 fprintf (stderr
, "word read from unaligned address: 0x%x\n", x
);
299 cpu
.asregs
.exception
= SIGBUS
;
304 unsigned char * p
= cpu
.mem
+ x
;
305 return (p
[0] << 24) | (p
[1] << 16) | (p
[2] << 8) | p
[3];
314 if (((uword
)x
) >= cpu
.asregs
.msize
)
317 fprintf (stderr
, "short read from 0x%x outside memory range\n", x
);
319 cpu
.asregs
.exception
= SIGSEGV
;
327 fprintf (stderr
, "short read from unaligned address: 0x%x\n", x
);
329 cpu
.asregs
.exception
= SIGBUS
;
334 unsigned char * p
= cpu
.mem
+ x
;
335 return (p
[0] << 8) | p
[1];
341 #define SEXTB(x) (((x & 0xff) ^ (~ 0x7f)) + 0x80)
342 #define SEXTW(y) ((int)((short)y))
345 IOMEM (addr
, write
, value
)
352 /* default to a 8 Mbyte (== 2^23) memory space */
353 static int sim_memory_size
= 23;
355 #define MEM_SIZE_FLOOR 64
360 sim_memory_size
= power
;
361 cpu
.asregs
.msize
= 1 << sim_memory_size
;
366 /* watch out for the '0 count' problem. There's probably a better
367 way.. e.g., why do we use 64 here? */
368 if (cpu
.asregs
.msize
< 64) /* ensure a boundary */
369 cpu
.mem
= (unsigned char *) calloc (64, (64 + cpu
.asregs
.msize
) / 64);
371 cpu
.mem
= (unsigned char *) calloc (64, cpu
.asregs
.msize
/ 64);
377 "Not enough VM for simulation of %d bytes of RAM\n",
380 cpu
.asregs
.msize
= 1;
381 cpu
.mem
= (unsigned char *) calloc (1, 1);
388 if (cpu
.asregs
.msize
!= (1 << sim_memory_size
))
389 sim_size (sim_memory_size
);
397 unsigned long memsize
;
401 /* Set up machine just out of reset. */
405 memsize
= cpu
.asregs
.msize
/ (1024 * 1024);
407 if (issue_messages
> 1)
408 fprintf (stderr
, "Simulated memory of %d Mbytes (0x0 .. 0x%08x)\n",
409 memsize
, cpu
.asregs
.msize
- 1);
411 /* Clean out the GPRs and alternate GPRs. */
412 for (i
= 0; i
< 16; i
++)
414 cpu
.asregs
.gregs
[i
] = 0;
415 cpu
.asregs
.alt_gregs
[i
] = 0;
418 /* Make our register set point to the right place. */
420 cpu
.asregs
.active_gregs
= &cpu
.asregs
.alt_gregs
[0];
422 cpu
.asregs
.active_gregs
= &cpu
.asregs
.gregs
[0];
424 /* ABI specifies initial values for these registers. */
425 cpu
.gr
[0] = cpu
.asregs
.msize
- 4;
427 /* dac fix, the stack address must be 8-byte aligned! */
428 cpu
.gr
[0] = cpu
.gr
[0] - cpu
.gr
[0] % 8;
432 cpu
.gr
[PARM4
] = cpu
.gr
[0];
438 cpu
.asregs
.exception
= SIGINT
;
441 /* Functions so that trapped open/close don't interfere with the
442 parent's functions. We say that we can't close the descriptors
443 that we didn't open. exit() and cleanup() get in trouble here,
444 to some extent. That's the price of emulation. */
446 unsigned char opened
[100];
452 if (fd
< 0 || fd
> NUM_ELEM (opened
))
462 if (fd
< 0 || fd
> NUM_ELEM (opened
))
472 if (fd
< 0 || fd
> NUM_ELEM (opened
))
483 switch ((unsigned long) (cpu
.gr
[TRAPCODE
]))
486 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
487 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
488 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
489 cpu
.gr
[RET1
] = callback
->read (callback
, a
[0], (char *) a
[1], a
[2]);
493 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
494 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
495 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
496 cpu
.gr
[RET1
] = (int)callback
->write (callback
, a
[0], (char *) a
[1], a
[2]);
500 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
501 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
502 /* a[2] = (unsigned long) (cpu.gr[PARM3]); */
503 cpu
.gr
[RET1
] = callback
->open (callback
, (char *) a
[0], a
[1]);
504 log_open (cpu
.gr
[RET1
]);
508 a
[0] = (unsigned long) (cpu
.gr
[4]);
509 /* Watch out for debugger's files. */
510 if (is_opened (a
[0]))
513 cpu
.gr
[RET1
] = callback
->close (callback
, a
[0]);
517 /* Don't let him close it. */
523 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
524 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
525 cpu
.gr
[RET1
] = link ((char *) a
[0], (char *) a
[1]);
529 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
530 cpu
.gr
[RET1
] = callback
->unlink (callback
, (char *) a
[0]);
534 /* handle time(0) vs time(&var) */
535 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
537 a
[0] += (unsigned long) cpu
.mem
;
538 cpu
.gr
[RET1
] = callback
->time (callback
, (time_t *) a
[0]);
542 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
543 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
544 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
545 cpu
.gr
[RET1
] = callback
->lseek (callback
, a
[0], a
[1], a
[2]);
549 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
550 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
551 cpu
.gr
[RET1
] = access ((char *) a
[0], a
[1]);
555 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
557 cpu
.gr
[RET1
] = times ((char *)a
[0]);
560 /* Give him simulated cycles for utime
561 and an instruction count for stime. */
570 t
.tms_utime
= cpu
.asregs
.cycles
;
571 t
.tms_stime
= cpu
.asregs
.insts
;
572 t
.tms_cutime
= t
.tms_utime
;
573 t
.tms_cstime
= t
.tms_stime
;
575 memcpy ((struct tms
*)(a
[0]), &t
, sizeof (t
));
577 cpu
.gr
[RET1
] = cpu
.asregs
.cycles
;
583 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
584 cpu
.gr
[RET1
] = int_sbrk (a
[0]);
589 fprintf (stderr
, "WARNING: sys call %d unimplemented\n",
599 /* These values should match those in libgloss/mcore/syscalls.s. */
606 case 10: /* _unlink */
607 case 19: /* _lseek */
608 case 43: /* _times */
609 cpu
.gr
[TRAPCODE
] = what
;
615 fprintf (stderr
, "Unhandled stub opcode: %d\n", what
);
627 cpu
.asregs
.exception
= SIGQUIT
;
636 a
[0] = (unsigned long)(cpu
.mem
+ cpu
.gr
[PARM1
]);
638 for (s
= (unsigned char *)a
[0], i
= 1 ; *s
&& i
< 6 ; s
++)
643 a
[i
] = (unsigned long)(cpu
.mem
+ cpu
.gr
[PARM1
+i
]);
645 a
[i
] = cpu
.gr
[i
+PARM1
];
650 cpu
.gr
[RET1
] = printf ((char *)a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
656 fprintf (stderr
, "WARNING: scanf unimplemented\n");
660 cpu
.gr
[RET1
] = cpu
.asregs
.insts
;
664 process_stub (cpu
.gr
[1]);
669 fprintf (stderr
, "Unhandled util code: %x\n", what
);
674 /* For figuring out whether we carried; addc/subc use this. */
683 x
= (a
& 0xffff) + (b
& 0xffff) + cin
;
684 x
= (x
>> 16) + (a
>> 16) + (b
>> 16);
690 #define WATCHFUNCTIONS 1
691 #ifdef WATCHFUNCTIONS
708 #define RD (inst & 0xF)
709 #define RS ((inst >> 4) & 0xF)
710 #define RX ((inst >> 8) & 0xF)
711 #define IMM5 ((inst >> 4) & 0x1F)
712 #define IMM4 ((inst) & 0xF)
714 static int tracing
= 0;
717 sim_resume (sd
, step
, siggnal
)
733 sigsave
= signal (SIGINT
, interrupt
);
734 cpu
.asregs
.exception
= step
? SIGTRAP
: 0;
737 /* Fetch the initial instructions that we'll decode. */
738 ibuf
= rlat (pc
& 0xFFFFFFFC);
745 /* make our register set point to the right place */
747 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
749 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
751 /* make a hash to speed exec loop, hope it's nonzero */
754 for (w
= 1; w
<= ENDWL
; w
++)
755 WLhash
= WLhash
& WL
[w
];
765 inst
= ibuf
& 0xFFFF;
773 #ifdef WATCHFUNCTIONS
774 /* now scan list of watch addresses, if match, count it and
775 note return address and count cycles until pc=return address */
777 if ((WLincyc
== 1) && (pc
== WLendpc
))
779 cycs
= (cpu
.asregs
.cycles
+ (insts
+ bonus_cycles
+
780 (memops
* memcycles
)) - WLbcyc
);
782 if (WLcnts
[WLW
] == 1)
789 if (cycs
> WLmax
[WLW
])
794 if (cycs
< WLmin
[WLW
])
804 /* Optimize with a hash to speed loop. */
807 if ((WLhash
== 0) || ((WLhash
& pc
) != 0))
809 for (w
=1; w
<= ENDWL
; w
++)
814 WLbcyc
= cpu
.asregs
.cycles
+ insts
815 + bonus_cycles
+ (memops
* memcycles
);
816 WLendpc
= cpu
.gr
[15];
827 fprintf (stderr
, "%.4x: inst = %.4x ", pc
, inst
);
842 cpu
.asregs
.exception
= SIGTRAP
;
855 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
857 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
866 cpu
.asregs
.active_gregs
= &cpu
.asregs
.alt_gregs
[0];
868 cpu
.asregs
.active_gregs
= &cpu
.asregs
.gregs
[0];
873 fprintf (stderr
, "WARNING: stop unimplemented\n");
878 fprintf (stderr
, "WARNING: wait unimplemented\n");
883 fprintf (stderr
, "WARNING: doze unimplemented\n");
887 cpu
.asregs
.exception
= SIGILL
; /* illegal */
890 case 0x8: /* trap 0 */
891 case 0xA: /* trap 2 */
892 case 0xB: /* trap 3 */
893 cpu
.asregs
.exception
= SIGTRAP
;
896 case 0xC: /* trap 4 */
897 case 0xD: /* trap 5 */
898 case 0xE: /* trap 6 */
899 cpu
.asregs
.exception
= SIGILL
; /* illegal */
902 case 0xF: /* trap 7 */
903 cpu
.asregs
.exception
= SIGTRAP
; /* integer div-by-0 */
906 case 0x9: /* trap 1 */
913 cpu
.asregs
.exception
= SIGILL
; /* illegal */
917 cpu
.gr
[RD
] = C_VALUE();
920 cpu
.gr
[RD
] = C_OFF();
924 char *addr
= (char *)cpu
.gr
[RD
];
925 int regno
= 4; /* always r4-r7 */
931 cpu
.gr
[regno
] = rlat(addr
);
935 while ((regno
&0x3) != 0);
940 char *addr
= (char *)cpu
.gr
[RD
];
941 int regno
= 4; /* always r4-r7 */
947 wlat(addr
, cpu
.gr
[regno
]);
951 while ((regno
& 0x3) != 0);
956 char *addr
= (char *)cpu
.gr
[0];
959 /* bonus cycle is really only needed if
960 the next insn shifts the last reg loaded.
967 cpu
.gr
[regno
] = rlat(addr
);
975 char *addr
= (char *)cpu
.gr
[0];
978 /* this should be removed! */
979 /* bonus_cycles ++; */
981 memops
+= 16 - regno
;
984 wlat(addr
, cpu
.gr
[regno
]);
992 cpu
.gr
[RD
] -= C_VALUE();
995 cpu
.gr
[RD
] -= C_OFF();
998 cpu
.gr
[RD
] += C_VALUE();
1000 case 0xB: /* incf */
1001 cpu
.gr
[RD
] += C_OFF();
1005 if (tracing
&& RD
== 15)
1006 fprintf (stderr
, "Func return, r2 = %x, r3 = %x\n",
1007 cpu
.gr
[2], cpu
.gr
[3]);
1021 for (i
= 0; !(tmp
& 0x80000000) && i
< 32; i
++)
1026 case 0xF: /* brev */
1030 tmp
= ((tmp
& 0xaaaaaaaa) >> 1) | ((tmp
& 0x55555555) << 1);
1031 tmp
= ((tmp
& 0xcccccccc) >> 2) | ((tmp
& 0x33333333) << 2);
1032 tmp
= ((tmp
& 0xf0f0f0f0) >> 4) | ((tmp
& 0x0f0f0f0f) << 4);
1033 tmp
= ((tmp
& 0xff00ff00) >> 8) | ((tmp
& 0x00ff00ff) << 8);
1034 cpu
.gr
[RD
] = ((tmp
& 0xffff0000) >> 16) | ((tmp
& 0x0000ffff) << 16);
1042 case 0x0: /* xtrb3 */
1043 cpu
.gr
[1] = (cpu
.gr
[RD
]) & 0xFF;
1044 NEW_C (cpu
.gr
[RD
] != 0);
1046 case 0x1: /* xtrb2 */
1047 cpu
.gr
[1] = (cpu
.gr
[RD
]>>8) & 0xFF;
1048 NEW_C (cpu
.gr
[RD
] != 0);
1050 case 0x2: /* xtrb1 */
1051 cpu
.gr
[1] = (cpu
.gr
[RD
]>>16) & 0xFF;
1052 NEW_C (cpu
.gr
[RD
] != 0);
1054 case 0x3: /* xtrb0 */
1055 cpu
.gr
[1] = (cpu
.gr
[RD
]>>24) & 0xFF;
1056 NEW_C (cpu
.gr
[RD
] != 0);
1058 case 0x4: /* zextb */
1059 cpu
.gr
[RD
] &= 0x000000FF;
1061 case 0x5: /* sextb */
1070 case 0x6: /* zexth */
1071 cpu
.gr
[RD
] &= 0x0000FFFF;
1073 case 0x7: /* sexth */
1082 case 0x8: /* declt */
1084 NEW_C ((long)cpu
.gr
[RD
] < 0);
1086 case 0x9: /* tstnbz */
1088 word tmp
= cpu
.gr
[RD
];
1089 NEW_C ((tmp
& 0xFF000000) != 0 &&
1090 (tmp
& 0x00FF0000) != 0 && (tmp
& 0x0000FF00) != 0 &&
1091 (tmp
& 0x000000FF) != 0);
1094 case 0xA: /* decgt */
1096 NEW_C ((long)cpu
.gr
[RD
] > 0);
1098 case 0xB: /* decne */
1100 NEW_C ((long)cpu
.gr
[RD
] != 0);
1102 case 0xC: /* clrt */
1106 case 0xD: /* clrf */
1111 if (cpu
.gr
[RD
] & 0x80000000)
1112 cpu
.gr
[RD
] = ~cpu
.gr
[RD
] + 1;
1115 cpu
.gr
[RD
] = ~cpu
.gr
[RD
];
1119 case 0x02: /* movt */
1121 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1123 case 0x03: /* mult */
1124 /* consume 2 bits per cycle from rs, until rs is 0 */
1126 unsigned int t
= cpu
.gr
[RS
];
1128 for (ticks
= 0; t
!= 0 ; t
>>= 2)
1130 bonus_cycles
+= ticks
;
1132 bonus_cycles
+= 2; /* min. is 3, so add 2, plus ticks above */
1134 fprintf (stderr
, " mult %x by %x to give %x",
1135 cpu
.gr
[RD
], cpu
.gr
[RS
], cpu
.gr
[RD
] * cpu
.gr
[RS
]);
1136 cpu
.gr
[RD
] = cpu
.gr
[RD
] * cpu
.gr
[RS
];
1138 case 0x04: /* loopt */
1141 pc
+= (IMM4
<< 1) - 32;
1145 --cpu
.gr
[RS
]; /* not RD! */
1146 NEW_C (((long)cpu
.gr
[RS
]) > 0);
1148 case 0x05: /* subu */
1149 cpu
.gr
[RD
] -= cpu
.gr
[RS
];
1151 case 0x06: /* addc */
1153 unsigned long tmp
, a
, b
;
1156 cpu
.gr
[RD
] = a
+ b
+ C_VALUE ();
1157 tmp
= iu_carry (a
, b
, C_VALUE ());
1161 case 0x07: /* subc */
1163 unsigned long tmp
, a
, b
;
1166 cpu
.gr
[RD
] = a
- b
+ C_VALUE () - 1;
1167 tmp
= iu_carry (a
,~b
, C_VALUE ());
1171 case 0x08: /* illegal */
1172 case 0x09: /* illegal*/
1173 cpu
.asregs
.exception
= SIGILL
;
1175 case 0x0A: /* movf */
1177 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1179 case 0x0B: /* lsr */
1181 unsigned long dst
, src
;
1184 /* We must not rely solely upon the native shift operations, since they
1185 may not match the M*Core's behaviour on boundary conditions. */
1186 dst
= src
> 31 ? 0 : dst
>> src
;
1190 case 0x0C: /* cmphs */
1191 NEW_C ((unsigned long )cpu
.gr
[RD
] >=
1192 (unsigned long)cpu
.gr
[RS
]);
1194 case 0x0D: /* cmplt */
1195 NEW_C ((long)cpu
.gr
[RD
] < (long)cpu
.gr
[RS
]);
1197 case 0x0E: /* tst */
1198 NEW_C ((cpu
.gr
[RD
] & cpu
.gr
[RS
]) != 0);
1200 case 0x0F: /* cmpne */
1201 NEW_C (cpu
.gr
[RD
] != cpu
.gr
[RS
]);
1203 case 0x10: case 0x11: /* mfcr */
1207 if (r
<= LAST_VALID_CREG
)
1208 cpu
.gr
[RD
] = cpu
.cr
[r
];
1210 cpu
.asregs
.exception
= SIGILL
;
1214 case 0x12: /* mov */
1215 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1217 fprintf (stderr
, "MOV %x into reg %d", cpu
.gr
[RD
], RD
);
1220 case 0x13: /* bgenr */
1221 if (cpu
.gr
[RS
] & 0x20)
1224 cpu
.gr
[RD
] = 1 << (cpu
.gr
[RS
] & 0x1F);
1227 case 0x14: /* rsub */
1228 cpu
.gr
[RD
] = cpu
.gr
[RS
] - cpu
.gr
[RD
];
1231 case 0x15: /* ixw */
1232 cpu
.gr
[RD
] += cpu
.gr
[RS
]<<2;
1235 case 0x16: /* and */
1236 cpu
.gr
[RD
] &= cpu
.gr
[RS
];
1239 case 0x17: /* xor */
1240 cpu
.gr
[RD
] ^= cpu
.gr
[RS
];
1243 case 0x18: case 0x19: /* mtcr */
1247 if (r
<= LAST_VALID_CREG
)
1248 cpu
.cr
[r
] = cpu
.gr
[RD
];
1250 cpu
.asregs
.exception
= SIGILL
;
1252 /* we might have changed register sets... */
1254 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
1256 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
1260 case 0x1A: /* asr */
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 if (cpu
.gr
[RS
] > 30)
1264 cpu
.gr
[RD
] = ((long) cpu
.gr
[RD
]) < 0 ? -1 : 0;
1266 cpu
.gr
[RD
] = (long) cpu
.gr
[RD
] >> cpu
.gr
[RS
];
1269 case 0x1B: /* lsl */
1270 /* We must not rely solely upon the native shift operations, since they
1271 may not match the M*Core's behaviour on boundary conditions. */
1272 cpu
.gr
[RD
] = cpu
.gr
[RS
] > 31 ? 0 : cpu
.gr
[RD
] << cpu
.gr
[RS
];
1275 case 0x1C: /* addu */
1276 cpu
.gr
[RD
] += cpu
.gr
[RS
];
1279 case 0x1D: /* ixh */
1280 cpu
.gr
[RD
] += cpu
.gr
[RS
] << 1;
1284 cpu
.gr
[RD
] |= cpu
.gr
[RS
];
1287 case 0x1F: /* andn */
1288 cpu
.gr
[RD
] &= ~cpu
.gr
[RS
];
1290 case 0x20: case 0x21: /* addi */
1292 cpu
.gr
[RD
] + (IMM5
+ 1);
1294 case 0x22: case 0x23: /* cmplti */
1296 int tmp
= (IMM5
+ 1);
1297 if (cpu
.gr
[RD
] < tmp
)
1307 case 0x24: case 0x25: /* subi */
1309 cpu
.gr
[RD
] - (IMM5
+ 1);
1311 case 0x26: case 0x27: /* illegal */
1312 cpu
.asregs
.exception
= SIGILL
;
1314 case 0x28: case 0x29: /* rsubi */
1318 case 0x2A: case 0x2B: /* cmpnei */
1319 if (cpu
.gr
[RD
] != IMM5
)
1329 case 0x2C: case 0x2D: /* bmaski, divu */
1331 unsigned imm
= IMM5
;
1337 unsigned int rx
, r1
;
1343 /* unsigned divide */
1344 cpu
.gr
[RD
] = (word
) ((unsigned int) cpu
.gr
[RD
] / (unsigned int)cpu
.gr
[1] );
1346 /* compute bonus_cycles for divu */
1347 for (r1nlz
= 0; ((r1
& 0x80000000) == 0) && (r1nlz
< 32); r1nlz
++)
1350 for (rxnlz
= 0; ((rx
& 0x80000000) == 0) && (rxnlz
< 32); rxnlz
++)
1356 exe
+= 5 + r1nlz
- rxnlz
;
1358 if (exe
>= (2 * memcycles
- 1))
1360 bonus_cycles
+= exe
- (2 * memcycles
) + 1;
1363 else if (imm
== 0 || imm
>= 8)
1369 cpu
.gr
[RD
] = (1 << imm
) - 1;
1374 cpu
.asregs
.exception
= SIGILL
;
1378 case 0x2E: case 0x2F: /* andi */
1379 cpu
.gr
[RD
] = cpu
.gr
[RD
] & IMM5
;
1381 case 0x30: case 0x31: /* bclri */
1382 cpu
.gr
[RD
] = cpu
.gr
[RD
] & ~(1<<IMM5
);
1384 case 0x32: case 0x33: /* bgeni, divs */
1386 unsigned imm
= IMM5
;
1393 /* compute bonus_cycles for divu */
1398 if (((rx
< 0) && (r1
> 0)) || ((rx
>= 0) && (r1
< 0)))
1406 /* signed divide, general registers are of type int, so / op is OK */
1407 cpu
.gr
[RD
] = cpu
.gr
[RD
] / cpu
.gr
[1];
1409 for (r1nlz
= 0; ((r1
& 0x80000000) == 0) && (r1nlz
< 32) ; r1nlz
++ )
1412 for (rxnlz
= 0; ((rx
& 0x80000000) == 0) && (rxnlz
< 32) ; rxnlz
++ )
1418 exe
+= 6 + r1nlz
- rxnlz
+ sc
;
1420 if (exe
>= (2 * memcycles
- 1))
1422 bonus_cycles
+= exe
- (2 * memcycles
) + 1;
1428 cpu
.gr
[RD
] = (1 << IMM5
);
1433 cpu
.asregs
.exception
= SIGILL
;
1437 case 0x34: case 0x35: /* bseti */
1438 cpu
.gr
[RD
] = cpu
.gr
[RD
] | (1 << IMM5
);
1440 case 0x36: case 0x37: /* btsti */
1441 NEW_C (cpu
.gr
[RD
] >> IMM5
);
1443 case 0x38: case 0x39: /* xsr, rotli */
1445 unsigned imm
= IMM5
;
1446 unsigned long tmp
= cpu
.gr
[RD
];
1452 cpu
.gr
[RD
] = (cbit
<< 31) | (tmp
>> 1);
1455 cpu
.gr
[RD
] = (tmp
<< imm
) | (tmp
>> (32 - imm
));
1458 case 0x3A: case 0x3B: /* asrc, asri */
1460 unsigned imm
= IMM5
;
1461 long tmp
= cpu
.gr
[RD
];
1465 cpu
.gr
[RD
] = tmp
>> 1;
1468 cpu
.gr
[RD
] = tmp
>> imm
;
1471 case 0x3C: case 0x3D: /* lslc, lsli */
1473 unsigned imm
= IMM5
;
1474 unsigned long tmp
= cpu
.gr
[RD
];
1478 cpu
.gr
[RD
] = tmp
<< 1;
1481 cpu
.gr
[RD
] = tmp
<< imm
;
1484 case 0x3E: case 0x3F: /* lsrc, lsri */
1486 unsigned imm
= IMM5
;
1487 unsigned long tmp
= cpu
.gr
[RD
];
1491 cpu
.gr
[RD
] = tmp
>> 1;
1494 cpu
.gr
[RD
] = tmp
>> imm
;
1497 case 0x40: case 0x41: case 0x42: case 0x43:
1498 case 0x44: case 0x45: case 0x46: case 0x47:
1499 case 0x48: case 0x49: case 0x4A: case 0x4B:
1500 case 0x4C: case 0x4D: case 0x4E: case 0x4F:
1501 cpu
.asregs
.exception
= SIGILL
;
1506 case 0x51: case 0x52: case 0x53:
1507 case 0x54: case 0x55: case 0x56: case 0x57:
1508 case 0x58: case 0x59: case 0x5A: case 0x5B:
1509 case 0x5C: case 0x5D: case 0x5E: case 0x5F:
1510 cpu
.asregs
.exception
= SIGILL
;
1512 case 0x60: case 0x61: case 0x62: case 0x63: /* movi */
1513 case 0x64: case 0x65: case 0x66: case 0x67:
1514 cpu
.gr
[RD
] = (inst
>> 4) & 0x7F;
1516 case 0x68: case 0x69: case 0x6A: case 0x6B:
1517 case 0x6C: case 0x6D: case 0x6E: case 0x6F: /* illegal */
1518 cpu
.asregs
.exception
= SIGILL
;
1520 case 0x71: case 0x72: case 0x73:
1521 case 0x74: case 0x75: case 0x76: case 0x77:
1522 case 0x78: case 0x79: case 0x7A: case 0x7B:
1523 case 0x7C: case 0x7D: case 0x7E: /* lrw */
1524 cpu
.gr
[RX
] = rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC);
1526 fprintf (stderr
, "LRW of 0x%x from 0x%x to reg %d",
1527 rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC),
1528 (pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC, RX
);
1531 case 0x7F: /* jsri */
1534 fprintf (stderr
, "func call: r2 = %x r3 = %x r4 = %x r5 = %x r6 = %x r7 = %x\n",
1535 cpu
.gr
[2], cpu
.gr
[3], cpu
.gr
[4], cpu
.gr
[5], cpu
.gr
[6], cpu
.gr
[7]);
1536 case 0x70: /* jmpi */
1537 pc
= rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC);
1543 case 0x80: case 0x81: case 0x82: case 0x83:
1544 case 0x84: case 0x85: case 0x86: case 0x87:
1545 case 0x88: case 0x89: case 0x8A: case 0x8B:
1546 case 0x8C: case 0x8D: case 0x8E: case 0x8F: /* ld */
1547 cpu
.gr
[RX
] = rlat (cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C));
1549 fprintf (stderr
, "load reg %d from 0x%x with 0x%x",
1551 cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C), cpu
.gr
[RX
]);
1554 case 0x90: case 0x91: case 0x92: case 0x93:
1555 case 0x94: case 0x95: case 0x96: case 0x97:
1556 case 0x98: case 0x99: case 0x9A: case 0x9B:
1557 case 0x9C: case 0x9D: case 0x9E: case 0x9F: /* st */
1558 wlat (cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C), cpu
.gr
[RX
]);
1560 fprintf (stderr
, "store reg %d (containing 0x%x) to 0x%x",
1562 cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C));
1565 case 0xA0: case 0xA1: case 0xA2: case 0xA3:
1566 case 0xA4: case 0xA5: case 0xA6: case 0xA7:
1567 case 0xA8: case 0xA9: case 0xAA: case 0xAB:
1568 case 0xAC: case 0xAD: case 0xAE: case 0xAF: /* ld.b */
1569 cpu
.gr
[RX
] = rbat (cpu
.gr
[RD
] + RS
);
1572 case 0xB0: case 0xB1: case 0xB2: case 0xB3:
1573 case 0xB4: case 0xB5: case 0xB6: case 0xB7:
1574 case 0xB8: case 0xB9: case 0xBA: case 0xBB:
1575 case 0xBC: case 0xBD: case 0xBE: case 0xBF: /* st.b */
1576 wbat (cpu
.gr
[RD
] + RS
, cpu
.gr
[RX
]);
1579 case 0xC0: case 0xC1: case 0xC2: case 0xC3:
1580 case 0xC4: case 0xC5: case 0xC6: case 0xC7:
1581 case 0xC8: case 0xC9: case 0xCA: case 0xCB:
1582 case 0xCC: case 0xCD: case 0xCE: case 0xCF: /* ld.h */
1583 cpu
.gr
[RX
] = rhat (cpu
.gr
[RD
] + ((inst
>> 3) & 0x001E));
1586 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
1587 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
1588 case 0xD8: case 0xD9: case 0xDA: case 0xDB:
1589 case 0xDC: case 0xDD: case 0xDE: case 0xDF: /* st.h */
1590 what (cpu
.gr
[RD
] + ((inst
>> 3) & 0x001E), cpu
.gr
[RX
]);
1593 case 0xE8: case 0xE9: case 0xEA: case 0xEB:
1594 case 0xEC: case 0xED: case 0xEE: case 0xEF: /* bf */
1598 disp
= inst
& 0x03FF;
1606 case 0xE0: case 0xE1: case 0xE2: case 0xE3:
1607 case 0xE4: case 0xE5: case 0xE6: case 0xE7: /* bt */
1611 disp
= inst
& 0x03FF;
1620 case 0xF8: case 0xF9: case 0xFA: case 0xFB:
1621 case 0xFC: case 0xFD: case 0xFE: case 0xFF: /* bsr */
1623 case 0xF0: case 0xF1: case 0xF2: case 0xF3:
1624 case 0xF4: case 0xF5: case 0xF6: case 0xF7: /* br */
1627 disp
= inst
& 0x03FF;
1639 fprintf (stderr
, "\n");
1643 /* Do not let him fetch from a bad address! */
1644 if (((uword
)pc
) >= cpu
.asregs
.msize
)
1647 fprintf (stderr
, "PC loaded at 0x%x is outside of available memory! (0x%x)\n", oldpc
, pc
);
1649 cpu
.asregs
.exception
= SIGSEGV
;
1653 ibuf
= rlat (pc
& 0xFFFFFFFC);
1658 while (!cpu
.asregs
.exception
);
1660 /* Hide away the things we've cached while executing. */
1662 cpu
.asregs
.insts
+= insts
; /* instructions done ... */
1663 cpu
.asregs
.cycles
+= insts
; /* and each takes a cycle */
1664 cpu
.asregs
.cycles
+= bonus_cycles
; /* and extra cycles for branches */
1665 cpu
.asregs
.cycles
+= memops
* memcycles
; /* and memop cycle delays */
1667 signal (SIGINT
, sigsave
);
1672 sim_write (sd
, addr
, buffer
, size
)
1675 unsigned char * buffer
;
1681 memcpy (& cpu
.mem
[addr
], buffer
, size
);
1687 sim_read (sd
, addr
, buffer
, size
)
1690 unsigned char * buffer
;
1696 memcpy (buffer
, & cpu
.mem
[addr
], size
);
1703 sim_store_register (sd
, rn
, memory
, length
)
1706 unsigned char * memory
;
1711 if (rn
< NUM_MCORE_REGS
&& rn
>= 0)
1717 /* misalignment safe */
1718 ival
= mcore_extract_unsigned_integer (memory
, 4);
1719 cpu
.asints
[rn
] = ival
;
1729 sim_fetch_register (sd
, rn
, memory
, length
)
1732 unsigned char * memory
;
1737 if (rn
< NUM_MCORE_REGS
&& rn
>= 0)
1741 long ival
= cpu
.asints
[rn
];
1743 /* misalignment-safe */
1744 mcore_store_unsigned_integer (memory
, 4, ival
);
1760 sim_resume (sd
, 0, 0);
1768 sim_stop_reason (sd
, reason
, sigrc
)
1770 enum sim_stop
* reason
;
1773 if (cpu
.asregs
.exception
== SIGQUIT
)
1775 * reason
= sim_exited
;
1776 * sigrc
= cpu
.gr
[PARM1
];
1780 * reason
= sim_stopped
;
1781 * sigrc
= cpu
.asregs
.exception
;
1790 cpu
.asregs
.exception
= SIGINT
;
1796 sim_info (sd
, verbose
)
1800 #ifdef WATCHFUNCTIONS
1803 double virttime
= cpu
.asregs
.cycles
/ 36.0e6
;
1805 callback
->printf_filtered (callback
, "\n\n# instructions executed %10d\n",
1807 callback
->printf_filtered (callback
, "# cycles %10d\n",
1809 callback
->printf_filtered (callback
, "# pipeline stalls %10d\n",
1811 callback
->printf_filtered (callback
, "# virtual time taken %10.4f\n",
1814 #ifdef WATCHFUNCTIONS
1815 callback
->printf_filtered (callback
, "\nNumber of watched functions: %d\n",
1820 for (w
= 1; w
<= ENDWL
; w
++)
1822 callback
->printf_filtered (callback
, "WL = %s %8x\n",WLstr
[w
],WL
[w
]);
1823 callback
->printf_filtered (callback
, " calls = %d, cycles = %d\n",
1824 WLcnts
[w
],WLcyc
[w
]);
1827 callback
->printf_filtered (callback
,
1828 " maxcpc = %d, mincpc = %d, avecpc = %d\n",
1829 WLmax
[w
],WLmin
[w
],WLcyc
[w
]/WLcnts
[w
]);
1833 callback
->printf_filtered (callback
,
1834 "Total cycles for watched functions: %d\n",wcyc
);
1840 unsigned char sa_machtype
[2];
1841 unsigned char sa_magic
[2];
1842 unsigned char sa_tsize
[4];
1843 unsigned char sa_dsize
[4];
1844 unsigned char sa_bsize
[4];
1845 unsigned char sa_syms
[4];
1846 unsigned char sa_entry
[4];
1847 unsigned char sa_trelo
[4];
1848 unsigned char sa_drelo
[4];
1851 #define LONG(x) (((x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
1852 #define SHORT(x) (((x)[0]<<8)|(x)[1])
1855 sim_open (kind
, cb
, abfd
, argv
)
1861 int osize
= sim_memory_size
;
1865 if (kind
== SIM_OPEN_STANDALONE
)
1868 /* Discard and reacquire memory -- start with a clean slate. */
1869 sim_size (1); /* small */
1870 sim_size (osize
); /* and back again */
1872 set_initial_gprs (); /* Reset the GPR registers. */
1874 /* Fudge our descriptor for now. */
1875 return (SIM_DESC
) 1;
1879 sim_close (sd
, quitting
)
1887 sim_load (sd
, prog
, abfd
, from_tty
)
1893 /* Do the right thing for ELF executables; this turns out to be
1894 just about the right thing for any object format that:
1895 - we crack using BFD routines
1896 - follows the traditional UNIX text/data/bss layout
1897 - calls the bss section ".bss". */
1899 extern bfd
* sim_load_file (); /* ??? Don't know where this should live. */
1905 handle
= bfd_openr (prog
, 0); /* could be "mcore" */
1909 printf("``%s'' could not be opened.\n", prog
);
1913 /* Makes sure that we have an object file, also cleans gets the
1914 section headers in place. */
1915 if (!bfd_check_format (handle
, bfd_object
))
1917 /* wasn't an object file */
1919 printf ("``%s'' is not appropriate object file.\n", prog
);
1923 /* Look for that bss section. */
1924 s_bss
= bfd_get_section_by_name (handle
, ".bss");
1928 printf("``%s'' has no bss section.\n", prog
);
1932 /* Appropriately paranoid would check that we have
1933 a traditional text/data/bss ordering within memory. */
1935 /* figure the end of the bss section */
1937 printf ("bss section at 0x%08x for 0x%08x bytes\n",
1938 (unsigned long) s_bss
->vma
, (unsigned long) s_bss
->_cooked_size
);
1940 heap_ptr
= (unsigned long) s_bss
->vma
+ (unsigned long) s_bss
->_cooked_size
;
1942 /* Clean up after ourselves. */
1945 /* XXX: do we need to free the s_bss and handle structures? */
1948 /* from sh -- dac */
1949 prog_bfd
= sim_load_file (sd
, myname
, callback
, prog
, abfd
,
1950 sim_kind
== SIM_OPEN_DEBUG
,
1952 if (prog_bfd
== NULL
)
1957 bfd_close (prog_bfd
);
1963 sim_create_inferior (sd
, prog_bfd
, argv
, env
)
1965 struct _bfd
* prog_bfd
;
1974 unsigned long strings
;
1975 unsigned long pointers
;
1976 unsigned long hi_stack
;
1979 /* Set the initial register set. */
1982 set_initial_gprs ();
1985 hi_stack
= cpu
.asregs
.msize
- 4;
1986 cpu
.asregs
.pc
= bfd_get_start_address (prog_bfd
);
1988 /* Calculate the argument and environment strings. */
1994 l
= strlen (*avp
) + 1; /* include the null */
1995 s_length
+= (l
+ 3) & ~3; /* make it a 4 byte boundary */
2003 l
= strlen (*avp
) + 1; /* include the null */
2004 s_length
+= (l
+ 3) & ~ 3;/* make it a 4 byte boundary */
2008 /* Claim some memory for the pointers and strings. */
2009 pointers
= hi_stack
- sizeof(word
) * (nenv
+1+nargs
+1);
2010 pointers
&= ~3; /* must be 4-byte aligned */
2011 cpu
.gr
[0] = pointers
;
2013 strings
= cpu
.gr
[0] - s_length
;
2014 strings
&= ~3; /* want to make it 4-byte aligned */
2015 cpu
.gr
[0] = strings
;
2016 /* dac fix, the stack address must be 8-byte aligned! */
2017 cpu
.gr
[0] = cpu
.gr
[0] - cpu
.gr
[0] % 8;
2019 /* Loop through the arguments and fill them in. */
2020 cpu
.gr
[PARM1
] = nargs
;
2023 /* No strings to fill in. */
2028 cpu
.gr
[PARM2
] = 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. */
2050 /* Now do the environment pointers. */
2053 /* No strings to fill in. */
2058 cpu
.gr
[PARM3
] = pointers
;
2063 /* Save where we're putting it. */
2064 wlat (pointers
, strings
);
2066 /* Copy the string. */
2067 l
= strlen (* avp
) + 1;
2068 strcpy ((char *)(cpu
.mem
+ strings
), *avp
);
2070 /* Bump the pointers. */
2076 /* A null to finish the list. */
2092 sim_do_command (sd
, cmd
)
2096 /* Nothing there yet; it's all an error. */
2100 char ** simargv
= buildargv (cmd
);
2102 if (strcmp (simargv
[0], "watch") == 0)
2104 if ((simargv
[1] == NULL
) || (simargv
[2] == NULL
))
2106 fprintf (stderr
, "Error: missing argument to watch cmd.\n");
2112 WL
[ENDWL
] = strtol (simargv
[2], NULL
, 0);
2113 WLstr
[ENDWL
] = strdup (simargv
[1]);
2114 fprintf (stderr
, "Added %s (%x) to watchlist, #%d\n",WLstr
[ENDWL
],
2118 else if (strcmp (simargv
[0], "dumpmem") == 0)
2123 if (simargv
[1] == NULL
)
2124 fprintf (stderr
, "Error: missing argument to dumpmem cmd.\n");
2126 fprintf (stderr
, "Writing dumpfile %s...",simargv
[1]);
2128 dumpfile
= fopen (simargv
[1], "w");
2130 fwrite (p
, cpu
.asregs
.msize
-1, 1, dumpfile
);
2133 fprintf (stderr
, "done.\n");
2135 else if (strcmp (simargv
[0], "clearstats") == 0)
2137 cpu
.asregs
.cycles
= 0;
2138 cpu
.asregs
.insts
= 0;
2139 cpu
.asregs
.stalls
= 0;
2142 else if (strcmp (simargv
[0], "verbose") == 0)
2148 fprintf (stderr
,"Error: \"%s\" is not a valid M.CORE simulator command.\n",
2154 fprintf (stderr
, "M.CORE sim commands: \n");
2155 fprintf (stderr
, " watch <funcname> <addr>\n");
2156 fprintf (stderr
, " dumpmem <filename>\n");
2157 fprintf (stderr
, " clearstats\n");
2158 fprintf (stderr
, " verbose\n");
2163 sim_set_callbacks (ptr
)
2164 host_callback
* ptr
;
This page took 0.370063 seconds and 5 git commands to generate.