1 /* Simulator for Motorola's MCore processor
2 Copyright (C) 1999-2014 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/>. */
23 #include <sys/times.h>
24 #include <sys/param.h>
25 #include <netinet/in.h> /* for byte ordering macros */
27 #include "gdb/callback.h"
28 #include "libiberty.h"
29 #include "gdb/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 int target_big_endian
= 0;
40 static unsigned long heap_ptr
= 0;
41 host_callback
* callback
;
45 mcore_extract_unsigned_integer (addr
, len
)
51 unsigned char * startaddr
= (unsigned char *)addr
;
52 unsigned char * endaddr
= startaddr
+ len
;
54 if (len
> (int) sizeof (unsigned long))
55 printf ("That operation is not available on integers of more than %d bytes.",
56 sizeof (unsigned long));
58 /* Start at the most significant end of the integer, and work towards
59 the least significant. */
62 if (! target_big_endian
)
64 for (p
= endaddr
; p
> startaddr
;)
65 retval
= (retval
<< 8) | * -- p
;
69 for (p
= startaddr
; p
< endaddr
;)
70 retval
= (retval
<< 8) | * p
++;
77 mcore_store_unsigned_integer (addr
, len
, val
)
83 unsigned char * startaddr
= (unsigned char *)addr
;
84 unsigned char * endaddr
= startaddr
+ len
;
86 if (! target_big_endian
)
88 for (p
= startaddr
; p
< endaddr
;)
96 for (p
= endaddr
; p
> startaddr
;)
104 /* The machine state.
105 This state is maintained in host byte order. The
106 fetch/store register functions must translate between host
107 byte order and the target processor byte order.
108 Keeping this data in target byte order simplifies the register
109 read/write functions. Keeping this data in native order improves
110 the performance of the simulator. Simulation speed is deemed more
113 /* The ordering of the mcore_regset structure is matched in the
114 gdb/config/mcore/tm-mcore.h file in the REGISTER_NAMES macro. */
117 word gregs
[16]; /* primary registers */
118 word alt_gregs
[16]; /* alt register file */
119 word cregs
[32]; /* control registers */
120 word pc
; /* the pc */
127 unsigned char * memory
;
133 struct mcore_regset asregs
;
134 word asints
[1]; /* but accessed larger... */
137 #define LAST_VALID_CREG 32 /* only 0..12 implemented */
138 #define NUM_MCORE_REGS (16 + 16 + LAST_VALID_CREG + 1)
142 static SIM_OPEN_KIND sim_kind
;
143 static char * myname
;
145 static int issue_messages
= 0;
147 #define gr asregs.active_gregs
148 #define cr asregs.cregs
149 #define sr asregs.cregs[0]
150 #define vbr asregs.cregs[1]
151 #define esr asregs.cregs[2]
152 #define fsr asregs.cregs[3]
153 #define epc asregs.cregs[4]
154 #define fpc asregs.cregs[5]
155 #define ss0 asregs.cregs[6]
156 #define ss1 asregs.cregs[7]
157 #define ss2 asregs.cregs[8]
158 #define ss3 asregs.cregs[9]
159 #define ss4 asregs.cregs[10]
160 #define gcr asregs.cregs[11]
161 #define gsr asregs.cregs[12]
162 #define mem asregs.memory
164 /* maniuplate the carry bit */
165 #define C_ON() (cpu.sr & 1)
166 #define C_VALUE() (cpu.sr & 1)
167 #define C_OFF() ((cpu.sr & 1) == 0)
168 #define SET_C() {cpu.sr |= 1;}
169 #define CLR_C() {cpu.sr &= 0xfffffffe;}
170 #define NEW_C(v) {CLR_C(); cpu.sr |= ((v) & 1);}
172 #define SR_AF() ((cpu.sr >> 1) & 1)
174 #define TRAPCODE 1 /* r1 holds which function we want */
175 #define PARM1 2 /* first parameter */
179 #define RET1 2 /* register for return values. */
189 heap_ptr
+= inc_bytes
;
191 if (issue_messages
&& heap_ptr
>cpu
.gr
[0])
192 fprintf (stderr
, "Warning: heap_ptr overlaps stack!\n");
201 if (((uword
)x
) >= cpu
.asregs
.msize
)
204 fprintf (stderr
, "byte write to 0x%x outside memory range\n", x
);
206 cpu
.asregs
.exception
= SIGSEGV
;
210 unsigned char *p
= cpu
.mem
+ x
;
219 if (((uword
)x
) >= cpu
.asregs
.msize
)
222 fprintf (stderr
, "word write to 0x%x outside memory range\n", x
);
224 cpu
.asregs
.exception
= SIGSEGV
;
231 fprintf (stderr
, "word write to unaligned memory address: 0x%x\n", x
);
233 cpu
.asregs
.exception
= SIGBUS
;
235 else if (! target_big_endian
)
237 unsigned char * p
= cpu
.mem
+ x
;
245 unsigned char * p
= cpu
.mem
+ x
;
258 if (((uword
)x
) >= cpu
.asregs
.msize
)
261 fprintf (stderr
, "short write to 0x%x outside memory range\n", x
);
263 cpu
.asregs
.exception
= SIGSEGV
;
270 fprintf (stderr
, "short write to unaligned memory address: 0x%x\n",
273 cpu
.asregs
.exception
= SIGBUS
;
275 else if (! target_big_endian
)
277 unsigned char * p
= cpu
.mem
+ x
;
283 unsigned char * p
= cpu
.mem
+ x
;
290 /* Read functions. */
295 if (((uword
)x
) >= cpu
.asregs
.msize
)
298 fprintf (stderr
, "byte read from 0x%x outside memory range\n", x
);
300 cpu
.asregs
.exception
= SIGSEGV
;
305 unsigned char * p
= cpu
.mem
+ x
;
314 if (((uword
) x
) >= cpu
.asregs
.msize
)
317 fprintf (stderr
, "word read from 0x%x outside memory range\n", x
);
319 cpu
.asregs
.exception
= SIGSEGV
;
327 fprintf (stderr
, "word read from unaligned address: 0x%x\n", x
);
329 cpu
.asregs
.exception
= SIGBUS
;
332 else if (! target_big_endian
)
334 unsigned char * p
= cpu
.mem
+ x
;
335 return (p
[3] << 24) | (p
[2] << 16) | (p
[1] << 8) | p
[0];
339 unsigned char * p
= cpu
.mem
+ x
;
340 return (p
[0] << 24) | (p
[1] << 16) | (p
[2] << 8) | p
[3];
349 if (((uword
)x
) >= cpu
.asregs
.msize
)
352 fprintf (stderr
, "short read from 0x%x outside memory range\n", x
);
354 cpu
.asregs
.exception
= SIGSEGV
;
362 fprintf (stderr
, "short read from unaligned address: 0x%x\n", x
);
364 cpu
.asregs
.exception
= SIGBUS
;
367 else if (! target_big_endian
)
369 unsigned char * p
= cpu
.mem
+ x
;
370 return (p
[1] << 8) | p
[0];
374 unsigned char * p
= cpu
.mem
+ x
;
375 return (p
[0] << 8) | p
[1];
381 #define SEXTB(x) (((x & 0xff) ^ (~ 0x7f)) + 0x80)
382 #define SEXTW(y) ((int)((short)y))
385 IOMEM (addr
, write
, value
)
392 /* Default to a 8 Mbyte (== 2^23) memory space. */
393 static int sim_memory_size
= 23;
395 #define MEM_SIZE_FLOOR 64
400 sim_memory_size
= power
;
401 cpu
.asregs
.msize
= 1 << sim_memory_size
;
406 /* Watch out for the '0 count' problem. There's probably a better
407 way.. e.g., why do we use 64 here? */
408 if (cpu
.asregs
.msize
< 64) /* Ensure a boundary. */
409 cpu
.mem
= (unsigned char *) calloc (64, (64 + cpu
.asregs
.msize
) / 64);
411 cpu
.mem
= (unsigned char *) calloc (64, cpu
.asregs
.msize
/ 64);
417 "Not enough VM for simulation of %d bytes of RAM\n",
420 cpu
.asregs
.msize
= 1;
421 cpu
.mem
= (unsigned char *) calloc (1, 1);
428 if (cpu
.asregs
.msize
!= (1 << sim_memory_size
))
429 sim_size (sim_memory_size
);
437 unsigned long memsize
;
441 /* Set up machine just out of reset. */
445 memsize
= cpu
.asregs
.msize
/ (1024 * 1024);
447 if (issue_messages
> 1)
448 fprintf (stderr
, "Simulated memory of %d Mbytes (0x0 .. 0x%08x)\n",
449 memsize
, cpu
.asregs
.msize
- 1);
451 /* Clean out the GPRs and alternate GPRs. */
452 for (i
= 0; i
< 16; i
++)
454 cpu
.asregs
.gregs
[i
] = 0;
455 cpu
.asregs
.alt_gregs
[i
] = 0;
458 /* Make our register set point to the right place. */
460 cpu
.asregs
.active_gregs
= &cpu
.asregs
.alt_gregs
[0];
462 cpu
.asregs
.active_gregs
= &cpu
.asregs
.gregs
[0];
464 /* ABI specifies initial values for these registers. */
465 cpu
.gr
[0] = cpu
.asregs
.msize
- 4;
467 /* dac fix, the stack address must be 8-byte aligned! */
468 cpu
.gr
[0] = cpu
.gr
[0] - cpu
.gr
[0] % 8;
472 cpu
.gr
[PARM4
] = cpu
.gr
[0];
475 /* Functions so that trapped open/close don't interfere with the
476 parent's functions. We say that we can't close the descriptors
477 that we didn't open. exit() and cleanup() get in trouble here,
478 to some extent. That's the price of emulation. */
480 unsigned char opened
[100];
486 if (fd
< 0 || fd
> NUM_ELEM (opened
))
496 if (fd
< 0 || fd
> NUM_ELEM (opened
))
506 if (fd
< 0 || fd
> NUM_ELEM (opened
))
517 switch ((unsigned long) (cpu
.gr
[TRAPCODE
]))
520 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
521 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
522 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
523 cpu
.gr
[RET1
] = callback
->read (callback
, a
[0], (char *) a
[1], a
[2]);
527 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
528 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
529 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
530 cpu
.gr
[RET1
] = (int)callback
->write (callback
, a
[0], (char *) a
[1], a
[2]);
534 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
535 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
536 /* a[2] = (unsigned long) (cpu.gr[PARM3]); */
537 cpu
.gr
[RET1
] = callback
->open (callback
, (char *) a
[0], a
[1]);
538 log_open (cpu
.gr
[RET1
]);
542 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
543 /* Watch out for debugger's files. */
544 if (is_opened (a
[0]))
547 cpu
.gr
[RET1
] = callback
->close (callback
, a
[0]);
551 /* Don't let him close it. */
557 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
558 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
559 cpu
.gr
[RET1
] = link ((char *) a
[0], (char *) a
[1]);
563 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
564 cpu
.gr
[RET1
] = callback
->unlink (callback
, (char *) a
[0]);
568 /* handle time(0) vs time(&var) */
569 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
571 a
[0] += (unsigned long) cpu
.mem
;
572 cpu
.gr
[RET1
] = callback
->time (callback
, (time_t *) a
[0]);
576 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
577 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
578 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
579 cpu
.gr
[RET1
] = callback
->lseek (callback
, a
[0], a
[1], a
[2]);
583 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
584 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
585 cpu
.gr
[RET1
] = access ((char *) a
[0], a
[1]);
589 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
591 cpu
.gr
[RET1
] = times ((char *)a
[0]);
594 /* Give him simulated cycles for utime
595 and an instruction count for stime. */
604 t
.tms_utime
= cpu
.asregs
.cycles
;
605 t
.tms_stime
= cpu
.asregs
.insts
;
606 t
.tms_cutime
= t
.tms_utime
;
607 t
.tms_cstime
= t
.tms_stime
;
609 memcpy ((struct tms
*)(a
[0]), &t
, sizeof (t
));
611 cpu
.gr
[RET1
] = cpu
.asregs
.cycles
;
617 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
618 cpu
.gr
[RET1
] = int_sbrk (a
[0]);
623 fprintf (stderr
, "WARNING: sys call %d unimplemented\n",
633 /* These values should match those in libgloss/mcore/syscalls.s. */
640 case 10: /* _unlink */
641 case 19: /* _lseek */
642 case 43: /* _times */
643 cpu
.gr
[TRAPCODE
] = what
;
649 fprintf (stderr
, "Unhandled stub opcode: %d\n", what
);
661 cpu
.asregs
.exception
= SIGQUIT
;
670 a
[0] = (unsigned long)(cpu
.mem
+ cpu
.gr
[PARM1
]);
672 for (s
= (unsigned char *)a
[0], i
= 1 ; *s
&& i
< 6 ; s
++)
677 a
[i
] = (unsigned long)(cpu
.mem
+ cpu
.gr
[PARM1
+i
]);
679 a
[i
] = cpu
.gr
[i
+PARM1
];
684 cpu
.gr
[RET1
] = printf ((char *)a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
690 fprintf (stderr
, "WARNING: scanf unimplemented\n");
694 cpu
.gr
[RET1
] = cpu
.asregs
.insts
;
698 process_stub (cpu
.gr
[1]);
703 fprintf (stderr
, "Unhandled util code: %x\n", what
);
708 /* For figuring out whether we carried; addc/subc use this. */
717 x
= (a
& 0xffff) + (b
& 0xffff) + cin
;
718 x
= (x
>> 16) + (a
>> 16) + (b
>> 16);
724 #define WATCHFUNCTIONS 1
725 #ifdef WATCHFUNCTIONS
742 #define RD (inst & 0xF)
743 #define RS ((inst >> 4) & 0xF)
744 #define RX ((inst >> 8) & 0xF)
745 #define IMM5 ((inst >> 4) & 0x1F)
746 #define IMM4 ((inst) & 0xF)
748 static int tracing
= 0;
751 sim_resume (sd
, step
, siggnal
)
766 cpu
.asregs
.exception
= step
? SIGTRAP
: 0;
769 /* Fetch the initial instructions that we'll decode. */
770 ibuf
= rlat (pc
& 0xFFFFFFFC);
777 /* make our register set point to the right place */
779 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
781 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
783 /* make a hash to speed exec loop, hope it's nonzero */
786 for (w
= 1; w
<= ENDWL
; w
++)
787 WLhash
= WLhash
& WL
[w
];
797 if (! target_big_endian
)
800 inst
= ibuf
& 0xFFFF;
805 if (! target_big_endian
)
806 inst
= ibuf
& 0xFFFF;
811 #ifdef WATCHFUNCTIONS
812 /* now scan list of watch addresses, if match, count it and
813 note return address and count cycles until pc=return address */
815 if ((WLincyc
== 1) && (pc
== WLendpc
))
817 cycs
= (cpu
.asregs
.cycles
+ (insts
+ bonus_cycles
+
818 (memops
* memcycles
)) - WLbcyc
);
820 if (WLcnts
[WLW
] == 1)
827 if (cycs
> WLmax
[WLW
])
832 if (cycs
< WLmin
[WLW
])
842 /* Optimize with a hash to speed loop. */
845 if ((WLhash
== 0) || ((WLhash
& pc
) != 0))
847 for (w
=1; w
<= ENDWL
; w
++)
852 WLbcyc
= cpu
.asregs
.cycles
+ insts
853 + bonus_cycles
+ (memops
* memcycles
);
854 WLendpc
= cpu
.gr
[15];
865 fprintf (stderr
, "%.4x: inst = %.4x ", pc
, inst
);
880 cpu
.asregs
.exception
= SIGTRAP
;
893 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
895 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
904 cpu
.asregs
.active_gregs
= &cpu
.asregs
.alt_gregs
[0];
906 cpu
.asregs
.active_gregs
= &cpu
.asregs
.gregs
[0];
911 fprintf (stderr
, "WARNING: stop unimplemented\n");
916 fprintf (stderr
, "WARNING: wait unimplemented\n");
921 fprintf (stderr
, "WARNING: doze unimplemented\n");
925 cpu
.asregs
.exception
= SIGILL
; /* illegal */
928 case 0x8: /* trap 0 */
929 case 0xA: /* trap 2 */
930 case 0xB: /* trap 3 */
931 cpu
.asregs
.exception
= SIGTRAP
;
934 case 0xC: /* trap 4 */
935 case 0xD: /* trap 5 */
936 case 0xE: /* trap 6 */
937 cpu
.asregs
.exception
= SIGILL
; /* illegal */
940 case 0xF: /* trap 7 */
941 cpu
.asregs
.exception
= SIGTRAP
; /* integer div-by-0 */
944 case 0x9: /* trap 1 */
951 cpu
.asregs
.exception
= SIGILL
; /* illegal */
955 cpu
.gr
[RD
] = C_VALUE();
958 cpu
.gr
[RD
] = C_OFF();
962 char *addr
= (char *)cpu
.gr
[RD
];
963 int regno
= 4; /* always r4-r7 */
969 cpu
.gr
[regno
] = rlat(addr
);
973 while ((regno
&0x3) != 0);
978 char *addr
= (char *)cpu
.gr
[RD
];
979 int regno
= 4; /* always r4-r7 */
985 wlat(addr
, cpu
.gr
[regno
]);
989 while ((regno
& 0x3) != 0);
994 char *addr
= (char *)cpu
.gr
[0];
997 /* bonus cycle is really only needed if
998 the next insn shifts the last reg loaded.
1003 while (regno
<= 0xF)
1005 cpu
.gr
[regno
] = rlat(addr
);
1013 char *addr
= (char *)cpu
.gr
[0];
1016 /* this should be removed! */
1017 /* bonus_cycles ++; */
1019 memops
+= 16 - regno
;
1020 while (regno
<= 0xF)
1022 wlat(addr
, cpu
.gr
[regno
]);
1029 case 0x8: /* dect */
1030 cpu
.gr
[RD
] -= C_VALUE();
1032 case 0x9: /* decf */
1033 cpu
.gr
[RD
] -= C_OFF();
1035 case 0xA: /* inct */
1036 cpu
.gr
[RD
] += C_VALUE();
1038 case 0xB: /* incf */
1039 cpu
.gr
[RD
] += C_OFF();
1043 if (tracing
&& RD
== 15)
1044 fprintf (stderr
, "Func return, r2 = %x, r3 = %x\n",
1045 cpu
.gr
[2], cpu
.gr
[3]);
1059 for (i
= 0; !(tmp
& 0x80000000) && i
< 32; i
++)
1064 case 0xF: /* brev */
1068 tmp
= ((tmp
& 0xaaaaaaaa) >> 1) | ((tmp
& 0x55555555) << 1);
1069 tmp
= ((tmp
& 0xcccccccc) >> 2) | ((tmp
& 0x33333333) << 2);
1070 tmp
= ((tmp
& 0xf0f0f0f0) >> 4) | ((tmp
& 0x0f0f0f0f) << 4);
1071 tmp
= ((tmp
& 0xff00ff00) >> 8) | ((tmp
& 0x00ff00ff) << 8);
1072 cpu
.gr
[RD
] = ((tmp
& 0xffff0000) >> 16) | ((tmp
& 0x0000ffff) << 16);
1080 case 0x0: /* xtrb3 */
1081 cpu
.gr
[1] = (cpu
.gr
[RD
]) & 0xFF;
1082 NEW_C (cpu
.gr
[RD
] != 0);
1084 case 0x1: /* xtrb2 */
1085 cpu
.gr
[1] = (cpu
.gr
[RD
]>>8) & 0xFF;
1086 NEW_C (cpu
.gr
[RD
] != 0);
1088 case 0x2: /* xtrb1 */
1089 cpu
.gr
[1] = (cpu
.gr
[RD
]>>16) & 0xFF;
1090 NEW_C (cpu
.gr
[RD
] != 0);
1092 case 0x3: /* xtrb0 */
1093 cpu
.gr
[1] = (cpu
.gr
[RD
]>>24) & 0xFF;
1094 NEW_C (cpu
.gr
[RD
] != 0);
1096 case 0x4: /* zextb */
1097 cpu
.gr
[RD
] &= 0x000000FF;
1099 case 0x5: /* sextb */
1108 case 0x6: /* zexth */
1109 cpu
.gr
[RD
] &= 0x0000FFFF;
1111 case 0x7: /* sexth */
1120 case 0x8: /* declt */
1122 NEW_C ((long)cpu
.gr
[RD
] < 0);
1124 case 0x9: /* tstnbz */
1126 word tmp
= cpu
.gr
[RD
];
1127 NEW_C ((tmp
& 0xFF000000) != 0 &&
1128 (tmp
& 0x00FF0000) != 0 && (tmp
& 0x0000FF00) != 0 &&
1129 (tmp
& 0x000000FF) != 0);
1132 case 0xA: /* decgt */
1134 NEW_C ((long)cpu
.gr
[RD
] > 0);
1136 case 0xB: /* decne */
1138 NEW_C ((long)cpu
.gr
[RD
] != 0);
1140 case 0xC: /* clrt */
1144 case 0xD: /* clrf */
1149 if (cpu
.gr
[RD
] & 0x80000000)
1150 cpu
.gr
[RD
] = ~cpu
.gr
[RD
] + 1;
1153 cpu
.gr
[RD
] = ~cpu
.gr
[RD
];
1157 case 0x02: /* movt */
1159 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1161 case 0x03: /* mult */
1162 /* consume 2 bits per cycle from rs, until rs is 0 */
1164 unsigned int t
= cpu
.gr
[RS
];
1166 for (ticks
= 0; t
!= 0 ; t
>>= 2)
1168 bonus_cycles
+= ticks
;
1170 bonus_cycles
+= 2; /* min. is 3, so add 2, plus ticks above */
1172 fprintf (stderr
, " mult %x by %x to give %x",
1173 cpu
.gr
[RD
], cpu
.gr
[RS
], cpu
.gr
[RD
] * cpu
.gr
[RS
]);
1174 cpu
.gr
[RD
] = cpu
.gr
[RD
] * cpu
.gr
[RS
];
1176 case 0x04: /* loopt */
1179 pc
+= (IMM4
<< 1) - 32;
1183 --cpu
.gr
[RS
]; /* not RD! */
1184 NEW_C (((long)cpu
.gr
[RS
]) > 0);
1186 case 0x05: /* subu */
1187 cpu
.gr
[RD
] -= cpu
.gr
[RS
];
1189 case 0x06: /* addc */
1191 unsigned long tmp
, a
, b
;
1194 cpu
.gr
[RD
] = a
+ b
+ C_VALUE ();
1195 tmp
= iu_carry (a
, b
, C_VALUE ());
1199 case 0x07: /* subc */
1201 unsigned long tmp
, a
, b
;
1204 cpu
.gr
[RD
] = a
- b
+ C_VALUE () - 1;
1205 tmp
= iu_carry (a
,~b
, C_VALUE ());
1209 case 0x08: /* illegal */
1210 case 0x09: /* illegal*/
1211 cpu
.asregs
.exception
= SIGILL
;
1213 case 0x0A: /* movf */
1215 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1217 case 0x0B: /* lsr */
1219 unsigned long dst
, src
;
1222 /* We must not rely solely upon the native shift operations, since they
1223 may not match the M*Core's behaviour on boundary conditions. */
1224 dst
= src
> 31 ? 0 : dst
>> src
;
1228 case 0x0C: /* cmphs */
1229 NEW_C ((unsigned long )cpu
.gr
[RD
] >=
1230 (unsigned long)cpu
.gr
[RS
]);
1232 case 0x0D: /* cmplt */
1233 NEW_C ((long)cpu
.gr
[RD
] < (long)cpu
.gr
[RS
]);
1235 case 0x0E: /* tst */
1236 NEW_C ((cpu
.gr
[RD
] & cpu
.gr
[RS
]) != 0);
1238 case 0x0F: /* cmpne */
1239 NEW_C (cpu
.gr
[RD
] != cpu
.gr
[RS
]);
1241 case 0x10: case 0x11: /* mfcr */
1245 if (r
<= LAST_VALID_CREG
)
1246 cpu
.gr
[RD
] = cpu
.cr
[r
];
1248 cpu
.asregs
.exception
= SIGILL
;
1252 case 0x12: /* mov */
1253 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1255 fprintf (stderr
, "MOV %x into reg %d", cpu
.gr
[RD
], RD
);
1258 case 0x13: /* bgenr */
1259 if (cpu
.gr
[RS
] & 0x20)
1262 cpu
.gr
[RD
] = 1 << (cpu
.gr
[RS
] & 0x1F);
1265 case 0x14: /* rsub */
1266 cpu
.gr
[RD
] = cpu
.gr
[RS
] - cpu
.gr
[RD
];
1269 case 0x15: /* ixw */
1270 cpu
.gr
[RD
] += cpu
.gr
[RS
]<<2;
1273 case 0x16: /* and */
1274 cpu
.gr
[RD
] &= cpu
.gr
[RS
];
1277 case 0x17: /* xor */
1278 cpu
.gr
[RD
] ^= cpu
.gr
[RS
];
1281 case 0x18: case 0x19: /* mtcr */
1285 if (r
<= LAST_VALID_CREG
)
1286 cpu
.cr
[r
] = cpu
.gr
[RD
];
1288 cpu
.asregs
.exception
= SIGILL
;
1290 /* we might have changed register sets... */
1292 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
1294 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
1298 case 0x1A: /* asr */
1299 /* We must not rely solely upon the native shift operations, since they
1300 may not match the M*Core's behaviour on boundary conditions. */
1301 if (cpu
.gr
[RS
] > 30)
1302 cpu
.gr
[RD
] = ((long) cpu
.gr
[RD
]) < 0 ? -1 : 0;
1304 cpu
.gr
[RD
] = (long) cpu
.gr
[RD
] >> cpu
.gr
[RS
];
1307 case 0x1B: /* lsl */
1308 /* We must not rely solely upon the native shift operations, since they
1309 may not match the M*Core's behaviour on boundary conditions. */
1310 cpu
.gr
[RD
] = cpu
.gr
[RS
] > 31 ? 0 : cpu
.gr
[RD
] << cpu
.gr
[RS
];
1313 case 0x1C: /* addu */
1314 cpu
.gr
[RD
] += cpu
.gr
[RS
];
1317 case 0x1D: /* ixh */
1318 cpu
.gr
[RD
] += cpu
.gr
[RS
] << 1;
1322 cpu
.gr
[RD
] |= cpu
.gr
[RS
];
1325 case 0x1F: /* andn */
1326 cpu
.gr
[RD
] &= ~cpu
.gr
[RS
];
1328 case 0x20: case 0x21: /* addi */
1330 cpu
.gr
[RD
] + (IMM5
+ 1);
1332 case 0x22: case 0x23: /* cmplti */
1334 int tmp
= (IMM5
+ 1);
1335 if (cpu
.gr
[RD
] < tmp
)
1345 case 0x24: case 0x25: /* subi */
1347 cpu
.gr
[RD
] - (IMM5
+ 1);
1349 case 0x26: case 0x27: /* illegal */
1350 cpu
.asregs
.exception
= SIGILL
;
1352 case 0x28: case 0x29: /* rsubi */
1356 case 0x2A: case 0x2B: /* cmpnei */
1357 if (cpu
.gr
[RD
] != IMM5
)
1367 case 0x2C: case 0x2D: /* bmaski, divu */
1369 unsigned imm
= IMM5
;
1375 unsigned int rx
, r1
;
1381 /* unsigned divide */
1382 cpu
.gr
[RD
] = (word
) ((unsigned int) cpu
.gr
[RD
] / (unsigned int)cpu
.gr
[1] );
1384 /* compute bonus_cycles for divu */
1385 for (r1nlz
= 0; ((r1
& 0x80000000) == 0) && (r1nlz
< 32); r1nlz
++)
1388 for (rxnlz
= 0; ((rx
& 0x80000000) == 0) && (rxnlz
< 32); rxnlz
++)
1394 exe
+= 5 + r1nlz
- rxnlz
;
1396 if (exe
>= (2 * memcycles
- 1))
1398 bonus_cycles
+= exe
- (2 * memcycles
) + 1;
1401 else if (imm
== 0 || imm
>= 8)
1407 cpu
.gr
[RD
] = (1 << imm
) - 1;
1412 cpu
.asregs
.exception
= SIGILL
;
1416 case 0x2E: case 0x2F: /* andi */
1417 cpu
.gr
[RD
] = cpu
.gr
[RD
] & IMM5
;
1419 case 0x30: case 0x31: /* bclri */
1420 cpu
.gr
[RD
] = cpu
.gr
[RD
] & ~(1<<IMM5
);
1422 case 0x32: case 0x33: /* bgeni, divs */
1424 unsigned imm
= IMM5
;
1431 /* compute bonus_cycles for divu */
1436 if (((rx
< 0) && (r1
> 0)) || ((rx
>= 0) && (r1
< 0)))
1444 /* signed divide, general registers are of type int, so / op is OK */
1445 cpu
.gr
[RD
] = cpu
.gr
[RD
] / cpu
.gr
[1];
1447 for (r1nlz
= 0; ((r1
& 0x80000000) == 0) && (r1nlz
< 32) ; r1nlz
++ )
1450 for (rxnlz
= 0; ((rx
& 0x80000000) == 0) && (rxnlz
< 32) ; rxnlz
++ )
1456 exe
+= 6 + r1nlz
- rxnlz
+ sc
;
1458 if (exe
>= (2 * memcycles
- 1))
1460 bonus_cycles
+= exe
- (2 * memcycles
) + 1;
1466 cpu
.gr
[RD
] = (1 << IMM5
);
1471 cpu
.asregs
.exception
= SIGILL
;
1475 case 0x34: case 0x35: /* bseti */
1476 cpu
.gr
[RD
] = cpu
.gr
[RD
] | (1 << IMM5
);
1478 case 0x36: case 0x37: /* btsti */
1479 NEW_C (cpu
.gr
[RD
] >> IMM5
);
1481 case 0x38: case 0x39: /* xsr, rotli */
1483 unsigned imm
= IMM5
;
1484 unsigned long tmp
= cpu
.gr
[RD
];
1490 cpu
.gr
[RD
] = (cbit
<< 31) | (tmp
>> 1);
1493 cpu
.gr
[RD
] = (tmp
<< imm
) | (tmp
>> (32 - imm
));
1496 case 0x3A: case 0x3B: /* asrc, asri */
1498 unsigned imm
= IMM5
;
1499 long tmp
= cpu
.gr
[RD
];
1503 cpu
.gr
[RD
] = tmp
>> 1;
1506 cpu
.gr
[RD
] = tmp
>> imm
;
1509 case 0x3C: case 0x3D: /* lslc, lsli */
1511 unsigned imm
= IMM5
;
1512 unsigned long tmp
= cpu
.gr
[RD
];
1516 cpu
.gr
[RD
] = tmp
<< 1;
1519 cpu
.gr
[RD
] = tmp
<< imm
;
1522 case 0x3E: case 0x3F: /* lsrc, lsri */
1524 unsigned imm
= IMM5
;
1525 unsigned long tmp
= cpu
.gr
[RD
];
1529 cpu
.gr
[RD
] = tmp
>> 1;
1532 cpu
.gr
[RD
] = tmp
>> imm
;
1535 case 0x40: case 0x41: case 0x42: case 0x43:
1536 case 0x44: case 0x45: case 0x46: case 0x47:
1537 case 0x48: case 0x49: case 0x4A: case 0x4B:
1538 case 0x4C: case 0x4D: case 0x4E: case 0x4F:
1539 cpu
.asregs
.exception
= SIGILL
;
1544 case 0x51: case 0x52: case 0x53:
1545 case 0x54: case 0x55: case 0x56: case 0x57:
1546 case 0x58: case 0x59: case 0x5A: case 0x5B:
1547 case 0x5C: case 0x5D: case 0x5E: case 0x5F:
1548 cpu
.asregs
.exception
= SIGILL
;
1550 case 0x60: case 0x61: case 0x62: case 0x63: /* movi */
1551 case 0x64: case 0x65: case 0x66: case 0x67:
1552 cpu
.gr
[RD
] = (inst
>> 4) & 0x7F;
1554 case 0x68: case 0x69: case 0x6A: case 0x6B:
1555 case 0x6C: case 0x6D: case 0x6E: case 0x6F: /* illegal */
1556 cpu
.asregs
.exception
= SIGILL
;
1558 case 0x71: case 0x72: case 0x73:
1559 case 0x74: case 0x75: case 0x76: case 0x77:
1560 case 0x78: case 0x79: case 0x7A: case 0x7B:
1561 case 0x7C: case 0x7D: case 0x7E: /* lrw */
1562 cpu
.gr
[RX
] = rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC);
1564 fprintf (stderr
, "LRW of 0x%x from 0x%x to reg %d",
1565 rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC),
1566 (pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC, RX
);
1569 case 0x7F: /* jsri */
1572 fprintf (stderr
, "func call: r2 = %x r3 = %x r4 = %x r5 = %x r6 = %x r7 = %x\n",
1573 cpu
.gr
[2], cpu
.gr
[3], cpu
.gr
[4], cpu
.gr
[5], cpu
.gr
[6], cpu
.gr
[7]);
1574 case 0x70: /* jmpi */
1575 pc
= rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC);
1581 case 0x80: case 0x81: case 0x82: case 0x83:
1582 case 0x84: case 0x85: case 0x86: case 0x87:
1583 case 0x88: case 0x89: case 0x8A: case 0x8B:
1584 case 0x8C: case 0x8D: case 0x8E: case 0x8F: /* ld */
1585 cpu
.gr
[RX
] = rlat (cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C));
1587 fprintf (stderr
, "load reg %d from 0x%x with 0x%x",
1589 cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C), cpu
.gr
[RX
]);
1592 case 0x90: case 0x91: case 0x92: case 0x93:
1593 case 0x94: case 0x95: case 0x96: case 0x97:
1594 case 0x98: case 0x99: case 0x9A: case 0x9B:
1595 case 0x9C: case 0x9D: case 0x9E: case 0x9F: /* st */
1596 wlat (cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C), cpu
.gr
[RX
]);
1598 fprintf (stderr
, "store reg %d (containing 0x%x) to 0x%x",
1600 cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C));
1603 case 0xA0: case 0xA1: case 0xA2: case 0xA3:
1604 case 0xA4: case 0xA5: case 0xA6: case 0xA7:
1605 case 0xA8: case 0xA9: case 0xAA: case 0xAB:
1606 case 0xAC: case 0xAD: case 0xAE: case 0xAF: /* ld.b */
1607 cpu
.gr
[RX
] = rbat (cpu
.gr
[RD
] + RS
);
1610 case 0xB0: case 0xB1: case 0xB2: case 0xB3:
1611 case 0xB4: case 0xB5: case 0xB6: case 0xB7:
1612 case 0xB8: case 0xB9: case 0xBA: case 0xBB:
1613 case 0xBC: case 0xBD: case 0xBE: case 0xBF: /* st.b */
1614 wbat (cpu
.gr
[RD
] + RS
, cpu
.gr
[RX
]);
1617 case 0xC0: case 0xC1: case 0xC2: case 0xC3:
1618 case 0xC4: case 0xC5: case 0xC6: case 0xC7:
1619 case 0xC8: case 0xC9: case 0xCA: case 0xCB:
1620 case 0xCC: case 0xCD: case 0xCE: case 0xCF: /* ld.h */
1621 cpu
.gr
[RX
] = rhat (cpu
.gr
[RD
] + ((inst
>> 3) & 0x001E));
1624 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
1625 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
1626 case 0xD8: case 0xD9: case 0xDA: case 0xDB:
1627 case 0xDC: case 0xDD: case 0xDE: case 0xDF: /* st.h */
1628 what (cpu
.gr
[RD
] + ((inst
>> 3) & 0x001E), cpu
.gr
[RX
]);
1631 case 0xE8: case 0xE9: case 0xEA: case 0xEB:
1632 case 0xEC: case 0xED: case 0xEE: case 0xEF: /* bf */
1636 disp
= inst
& 0x03FF;
1644 case 0xE0: case 0xE1: case 0xE2: case 0xE3:
1645 case 0xE4: case 0xE5: case 0xE6: case 0xE7: /* bt */
1649 disp
= inst
& 0x03FF;
1658 case 0xF8: case 0xF9: case 0xFA: case 0xFB:
1659 case 0xFC: case 0xFD: case 0xFE: case 0xFF: /* bsr */
1661 case 0xF0: case 0xF1: case 0xF2: case 0xF3:
1662 case 0xF4: case 0xF5: case 0xF6: case 0xF7: /* br */
1665 disp
= inst
& 0x03FF;
1677 fprintf (stderr
, "\n");
1681 /* Do not let him fetch from a bad address! */
1682 if (((uword
)pc
) >= cpu
.asregs
.msize
)
1685 fprintf (stderr
, "PC loaded at 0x%x is outside of available memory! (0x%x)\n", oldpc
, pc
);
1687 cpu
.asregs
.exception
= SIGSEGV
;
1691 ibuf
= rlat (pc
& 0xFFFFFFFC);
1696 while (!cpu
.asregs
.exception
);
1698 /* Hide away the things we've cached while executing. */
1700 cpu
.asregs
.insts
+= insts
; /* instructions done ... */
1701 cpu
.asregs
.cycles
+= insts
; /* and each takes a cycle */
1702 cpu
.asregs
.cycles
+= bonus_cycles
; /* and extra cycles for branches */
1703 cpu
.asregs
.cycles
+= memops
* memcycles
; /* and memop cycle delays */
1708 sim_write (sd
, addr
, buffer
, size
)
1711 const unsigned char * buffer
;
1717 memcpy (& cpu
.mem
[addr
], buffer
, size
);
1723 sim_read (sd
, addr
, buffer
, size
)
1726 unsigned char * buffer
;
1732 memcpy (buffer
, & cpu
.mem
[addr
], size
);
1739 sim_store_register (sd
, rn
, memory
, length
)
1742 unsigned char * memory
;
1747 if (rn
< NUM_MCORE_REGS
&& rn
>= 0)
1753 /* misalignment safe */
1754 ival
= mcore_extract_unsigned_integer (memory
, 4);
1755 cpu
.asints
[rn
] = ival
;
1765 sim_fetch_register (sd
, rn
, memory
, length
)
1768 unsigned char * memory
;
1773 if (rn
< NUM_MCORE_REGS
&& rn
>= 0)
1777 long ival
= cpu
.asints
[rn
];
1779 /* misalignment-safe */
1780 mcore_store_unsigned_integer (memory
, 4, ival
);
1796 sim_resume (sd
, 0, 0);
1804 sim_stop_reason (sd
, reason
, sigrc
)
1806 enum sim_stop
* reason
;
1809 if (cpu
.asregs
.exception
== SIGQUIT
)
1811 * reason
= sim_exited
;
1812 * sigrc
= cpu
.gr
[PARM1
];
1816 * reason
= sim_stopped
;
1817 * sigrc
= cpu
.asregs
.exception
;
1826 cpu
.asregs
.exception
= SIGINT
;
1832 sim_info (sd
, verbose
)
1836 #ifdef WATCHFUNCTIONS
1839 double virttime
= cpu
.asregs
.cycles
/ 36.0e6
;
1841 callback
->printf_filtered (callback
, "\n\n# instructions executed %10d\n",
1843 callback
->printf_filtered (callback
, "# cycles %10d\n",
1845 callback
->printf_filtered (callback
, "# pipeline stalls %10d\n",
1847 callback
->printf_filtered (callback
, "# virtual time taken %10.4f\n",
1850 #ifdef WATCHFUNCTIONS
1851 callback
->printf_filtered (callback
, "\nNumber of watched functions: %d\n",
1856 for (w
= 1; w
<= ENDWL
; w
++)
1858 callback
->printf_filtered (callback
, "WL = %s %8x\n",WLstr
[w
],WL
[w
]);
1859 callback
->printf_filtered (callback
, " calls = %d, cycles = %d\n",
1860 WLcnts
[w
],WLcyc
[w
]);
1863 callback
->printf_filtered (callback
,
1864 " maxcpc = %d, mincpc = %d, avecpc = %d\n",
1865 WLmax
[w
],WLmin
[w
],WLcyc
[w
]/WLcnts
[w
]);
1869 callback
->printf_filtered (callback
,
1870 "Total cycles for watched functions: %d\n",wcyc
);
1876 unsigned char sa_machtype
[2];
1877 unsigned char sa_magic
[2];
1878 unsigned char sa_tsize
[4];
1879 unsigned char sa_dsize
[4];
1880 unsigned char sa_bsize
[4];
1881 unsigned char sa_syms
[4];
1882 unsigned char sa_entry
[4];
1883 unsigned char sa_trelo
[4];
1884 unsigned char sa_drelo
[4];
1887 #define LONG(x) (((x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
1888 #define SHORT(x) (((x)[0]<<8)|(x)[1])
1891 sim_open (kind
, cb
, abfd
, argv
)
1897 int osize
= sim_memory_size
;
1901 if (kind
== SIM_OPEN_STANDALONE
)
1904 /* Discard and reacquire memory -- start with a clean slate. */
1905 sim_size (1); /* small */
1906 sim_size (osize
); /* and back again */
1908 set_initial_gprs (); /* Reset the GPR registers. */
1910 /* Fudge our descriptor for now. */
1911 return (SIM_DESC
) 1;
1915 sim_close (sd
, quitting
)
1923 sim_load (sd
, prog
, abfd
, from_tty
)
1929 /* Do the right thing for ELF executables; this turns out to be
1930 just about the right thing for any object format that:
1931 - we crack using BFD routines
1932 - follows the traditional UNIX text/data/bss layout
1933 - calls the bss section ".bss". */
1935 extern bfd
* sim_load_file (); /* ??? Don't know where this should live. */
1941 handle
= bfd_openr (prog
, 0); /* could be "mcore" */
1945 printf("``%s'' could not be opened.\n", prog
);
1949 /* Makes sure that we have an object file, also cleans gets the
1950 section headers in place. */
1951 if (!bfd_check_format (handle
, bfd_object
))
1953 /* wasn't an object file */
1955 printf ("``%s'' is not appropriate object file.\n", prog
);
1959 /* Look for that bss section. */
1960 s_bss
= bfd_get_section_by_name (handle
, ".bss");
1964 printf("``%s'' has no bss section.\n", prog
);
1968 /* Appropriately paranoid would check that we have
1969 a traditional text/data/bss ordering within memory. */
1971 /* figure the end of the bss section */
1973 printf ("bss section at 0x%08x for 0x%08x bytes\n",
1974 (unsigned long) bfd_get_section_vma (handle
, s_bss
),
1975 (unsigned long) bfd_section_size (handle
, s_bss
));
1977 heap_ptr
= ((unsigned long) bfd_get_section_vma (handle
, s_bss
)
1978 + (unsigned long) bfd_section_size (handle
, s_bss
));
1980 /* Clean up after ourselves. */
1983 /* XXX: do we need to free the s_bss and handle structures? */
1986 /* from sh -- dac */
1987 prog_bfd
= sim_load_file (sd
, myname
, callback
, prog
, abfd
,
1988 sim_kind
== SIM_OPEN_DEBUG
,
1990 if (prog_bfd
== NULL
)
1993 target_big_endian
= bfd_big_endian (prog_bfd
);
1996 bfd_close (prog_bfd
);
2002 sim_create_inferior (sd
, prog_bfd
, argv
, env
)
2004 struct bfd
* prog_bfd
;
2013 unsigned long strings
;
2014 unsigned long pointers
;
2015 unsigned long hi_stack
;
2018 /* Set the initial register set. */
2021 set_initial_gprs ();
2024 hi_stack
= cpu
.asregs
.msize
- 4;
2025 cpu
.asregs
.pc
= bfd_get_start_address (prog_bfd
);
2027 /* Calculate the argument and environment strings. */
2033 l
= strlen (*avp
) + 1; /* include the null */
2034 s_length
+= (l
+ 3) & ~3; /* make it a 4 byte boundary */
2042 l
= strlen (*avp
) + 1; /* include the null */
2043 s_length
+= (l
+ 3) & ~ 3;/* make it a 4 byte boundary */
2047 /* Claim some memory for the pointers and strings. */
2048 pointers
= hi_stack
- sizeof(word
) * (nenv
+1+nargs
+1);
2049 pointers
&= ~3; /* must be 4-byte aligned */
2050 cpu
.gr
[0] = pointers
;
2052 strings
= cpu
.gr
[0] - s_length
;
2053 strings
&= ~3; /* want to make it 4-byte aligned */
2054 cpu
.gr
[0] = strings
;
2055 /* dac fix, the stack address must be 8-byte aligned! */
2056 cpu
.gr
[0] = cpu
.gr
[0] - cpu
.gr
[0] % 8;
2058 /* Loop through the arguments and fill them in. */
2059 cpu
.gr
[PARM1
] = nargs
;
2062 /* No strings to fill in. */
2067 cpu
.gr
[PARM2
] = pointers
;
2071 /* Save where we're putting it. */
2072 wlat (pointers
, strings
);
2074 /* Copy the string. */
2075 l
= strlen (* avp
) + 1;
2076 strcpy ((char *)(cpu
.mem
+ strings
), *avp
);
2078 /* Bump the pointers. */
2084 /* A null to finish the list. */
2089 /* Now do the environment pointers. */
2092 /* No strings to fill in. */
2097 cpu
.gr
[PARM3
] = pointers
;
2102 /* Save where we're putting it. */
2103 wlat (pointers
, strings
);
2105 /* Copy the string. */
2106 l
= strlen (* avp
) + 1;
2107 strcpy ((char *)(cpu
.mem
+ strings
), *avp
);
2109 /* Bump the pointers. */
2115 /* A null to finish the list. */
2131 sim_do_command (sd
, cmd
)
2135 /* Nothing there yet; it's all an error. */
2139 char ** simargv
= buildargv (cmd
);
2141 if (strcmp (simargv
[0], "watch") == 0)
2143 if ((simargv
[1] == NULL
) || (simargv
[2] == NULL
))
2145 fprintf (stderr
, "Error: missing argument to watch cmd.\n");
2151 WL
[ENDWL
] = strtol (simargv
[2], NULL
, 0);
2152 WLstr
[ENDWL
] = strdup (simargv
[1]);
2153 fprintf (stderr
, "Added %s (%x) to watchlist, #%d\n",WLstr
[ENDWL
],
2157 else if (strcmp (simargv
[0], "dumpmem") == 0)
2162 if (simargv
[1] == NULL
)
2163 fprintf (stderr
, "Error: missing argument to dumpmem cmd.\n");
2165 fprintf (stderr
, "Writing dumpfile %s...",simargv
[1]);
2167 dumpfile
= fopen (simargv
[1], "w");
2169 fwrite (p
, cpu
.asregs
.msize
-1, 1, dumpfile
);
2172 fprintf (stderr
, "done.\n");
2174 else if (strcmp (simargv
[0], "clearstats") == 0)
2176 cpu
.asregs
.cycles
= 0;
2177 cpu
.asregs
.insts
= 0;
2178 cpu
.asregs
.stalls
= 0;
2181 else if (strcmp (simargv
[0], "verbose") == 0)
2187 fprintf (stderr
,"Error: \"%s\" is not a valid M.CORE simulator command.\n",
2193 fprintf (stderr
, "M.CORE sim commands: \n");
2194 fprintf (stderr
, " watch <funcname> <addr>\n");
2195 fprintf (stderr
, " dumpmem <filename>\n");
2196 fprintf (stderr
, " clearstats\n");
2197 fprintf (stderr
, " verbose\n");
2202 sim_set_callbacks (ptr
)
2203 host_callback
* ptr
;
This page took 0.078402 seconds and 4 git commands to generate.