7e2be0d3ff51e94e94843ec711a718d45dbeb7fd
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/>. */
23 #include <sys/times.h>
24 #include <sys/param.h>
25 #include <netinet/in.h> /* for byte ordering macros */
28 #include "gdb/callback.h"
29 #include "libiberty.h"
30 #include "gdb/remote-sim.h"
33 #define NUM_ELEM(A) (sizeof (A) / sizeof (A)[0])
37 typedef long int word
;
38 typedef unsigned long int uword
;
40 static int target_big_endian
= 0;
41 static unsigned long heap_ptr
= 0;
42 host_callback
* callback
;
46 mcore_extract_unsigned_integer (addr
, len
)
52 unsigned char * startaddr
= (unsigned char *)addr
;
53 unsigned char * endaddr
= startaddr
+ len
;
55 if (len
> (int) sizeof (unsigned long))
56 printf ("That operation is not available on integers of more than %d bytes.",
57 sizeof (unsigned long));
59 /* Start at the most significant end of the integer, and work towards
60 the least significant. */
63 if (! target_big_endian
)
65 for (p
= endaddr
; p
> startaddr
;)
66 retval
= (retval
<< 8) | * -- p
;
70 for (p
= startaddr
; p
< endaddr
;)
71 retval
= (retval
<< 8) | * p
++;
78 mcore_store_unsigned_integer (addr
, len
, val
)
84 unsigned char * startaddr
= (unsigned char *)addr
;
85 unsigned char * endaddr
= startaddr
+ len
;
87 if (! target_big_endian
)
89 for (p
= startaddr
; p
< endaddr
;)
97 for (p
= endaddr
; p
> startaddr
;)
105 /* The machine state.
106 This state is maintained in host byte order. The
107 fetch/store register functions must translate between host
108 byte order and the target processor byte order.
109 Keeping this data in target byte order simplifies the register
110 read/write functions. Keeping this data in native order improves
111 the performance of the simulator. Simulation speed is deemed more
114 /* The ordering of the mcore_regset structure is matched in the
115 gdb/config/mcore/tm-mcore.h file in the REGISTER_NAMES macro. */
118 word gregs
[16]; /* primary registers */
119 word alt_gregs
[16]; /* alt register file */
120 word cregs
[32]; /* control registers */
121 word pc
; /* the pc */
128 unsigned char * memory
;
134 struct mcore_regset asregs
;
135 word asints
[1]; /* but accessed larger... */
138 #define LAST_VALID_CREG 32 /* only 0..12 implemented */
139 #define NUM_MCORE_REGS (16 + 16 + LAST_VALID_CREG + 1)
143 static SIM_OPEN_KIND sim_kind
;
144 static char * myname
;
146 static int issue_messages
= 0;
148 #define gr asregs.active_gregs
149 #define cr asregs.cregs
150 #define sr asregs.cregs[0]
151 #define vbr asregs.cregs[1]
152 #define esr asregs.cregs[2]
153 #define fsr asregs.cregs[3]
154 #define epc asregs.cregs[4]
155 #define fpc asregs.cregs[5]
156 #define ss0 asregs.cregs[6]
157 #define ss1 asregs.cregs[7]
158 #define ss2 asregs.cregs[8]
159 #define ss3 asregs.cregs[9]
160 #define ss4 asregs.cregs[10]
161 #define gcr asregs.cregs[11]
162 #define gsr asregs.cregs[12]
163 #define mem asregs.memory
165 /* maniuplate the carry bit */
166 #define C_ON() (cpu.sr & 1)
167 #define C_VALUE() (cpu.sr & 1)
168 #define C_OFF() ((cpu.sr & 1) == 0)
169 #define SET_C() {cpu.sr |= 1;}
170 #define CLR_C() {cpu.sr &= 0xfffffffe;}
171 #define NEW_C(v) {CLR_C(); cpu.sr |= ((v) & 1);}
173 #define SR_AF() ((cpu.sr >> 1) & 1)
175 #define TRAPCODE 1 /* r1 holds which function we want */
176 #define PARM1 2 /* first parameter */
180 #define RET1 2 /* register for return values. */
190 heap_ptr
+= inc_bytes
;
192 if (issue_messages
&& heap_ptr
>cpu
.gr
[0])
193 fprintf (stderr
, "Warning: heap_ptr overlaps stack!\n");
202 if (((uword
)x
) >= cpu
.asregs
.msize
)
205 fprintf (stderr
, "byte write to 0x%x outside memory range\n", x
);
207 cpu
.asregs
.exception
= SIGSEGV
;
211 unsigned char *p
= cpu
.mem
+ x
;
220 if (((uword
)x
) >= cpu
.asregs
.msize
)
223 fprintf (stderr
, "word write to 0x%x outside memory range\n", x
);
225 cpu
.asregs
.exception
= SIGSEGV
;
232 fprintf (stderr
, "word write to unaligned memory address: 0x%x\n", x
);
234 cpu
.asregs
.exception
= SIGBUS
;
236 else if (! target_big_endian
)
238 unsigned char * p
= cpu
.mem
+ x
;
246 unsigned char * p
= cpu
.mem
+ x
;
259 if (((uword
)x
) >= cpu
.asregs
.msize
)
262 fprintf (stderr
, "short write to 0x%x outside memory range\n", x
);
264 cpu
.asregs
.exception
= SIGSEGV
;
271 fprintf (stderr
, "short write to unaligned memory address: 0x%x\n",
274 cpu
.asregs
.exception
= SIGBUS
;
276 else if (! target_big_endian
)
278 unsigned char * p
= cpu
.mem
+ x
;
284 unsigned char * p
= cpu
.mem
+ x
;
291 /* Read functions. */
296 if (((uword
)x
) >= cpu
.asregs
.msize
)
299 fprintf (stderr
, "byte read from 0x%x outside memory range\n", x
);
301 cpu
.asregs
.exception
= SIGSEGV
;
306 unsigned char * p
= cpu
.mem
+ x
;
315 if (((uword
) x
) >= cpu
.asregs
.msize
)
318 fprintf (stderr
, "word read from 0x%x outside memory range\n", x
);
320 cpu
.asregs
.exception
= SIGSEGV
;
328 fprintf (stderr
, "word read from unaligned address: 0x%x\n", x
);
330 cpu
.asregs
.exception
= SIGBUS
;
333 else if (! target_big_endian
)
335 unsigned char * p
= cpu
.mem
+ x
;
336 return (p
[3] << 24) | (p
[2] << 16) | (p
[1] << 8) | p
[0];
340 unsigned char * p
= cpu
.mem
+ x
;
341 return (p
[0] << 24) | (p
[1] << 16) | (p
[2] << 8) | p
[3];
350 if (((uword
)x
) >= cpu
.asregs
.msize
)
353 fprintf (stderr
, "short read from 0x%x outside memory range\n", x
);
355 cpu
.asregs
.exception
= SIGSEGV
;
363 fprintf (stderr
, "short read from unaligned address: 0x%x\n", x
);
365 cpu
.asregs
.exception
= SIGBUS
;
368 else if (! target_big_endian
)
370 unsigned char * p
= cpu
.mem
+ x
;
371 return (p
[1] << 8) | p
[0];
375 unsigned char * p
= cpu
.mem
+ x
;
376 return (p
[0] << 8) | p
[1];
382 #define SEXTB(x) (((x & 0xff) ^ (~ 0x7f)) + 0x80)
383 #define SEXTW(y) ((int)((short)y))
386 IOMEM (addr
, write
, value
)
393 /* Default to a 8 Mbyte (== 2^23) memory space. */
394 static int sim_memory_size
= 23;
396 #define MEM_SIZE_FLOOR 64
401 sim_memory_size
= power
;
402 cpu
.asregs
.msize
= 1 << sim_memory_size
;
407 /* Watch out for the '0 count' problem. There's probably a better
408 way.. e.g., why do we use 64 here? */
409 if (cpu
.asregs
.msize
< 64) /* Ensure a boundary. */
410 cpu
.mem
= (unsigned char *) calloc (64, (64 + cpu
.asregs
.msize
) / 64);
412 cpu
.mem
= (unsigned char *) calloc (64, cpu
.asregs
.msize
/ 64);
418 "Not enough VM for simulation of %d bytes of RAM\n",
421 cpu
.asregs
.msize
= 1;
422 cpu
.mem
= (unsigned char *) calloc (1, 1);
429 if (cpu
.asregs
.msize
!= (1 << sim_memory_size
))
430 sim_size (sim_memory_size
);
438 unsigned long memsize
;
442 /* Set up machine just out of reset. */
446 memsize
= cpu
.asregs
.msize
/ (1024 * 1024);
448 if (issue_messages
> 1)
449 fprintf (stderr
, "Simulated memory of %d Mbytes (0x0 .. 0x%08x)\n",
450 memsize
, cpu
.asregs
.msize
- 1);
452 /* Clean out the GPRs and alternate GPRs. */
453 for (i
= 0; i
< 16; i
++)
455 cpu
.asregs
.gregs
[i
] = 0;
456 cpu
.asregs
.alt_gregs
[i
] = 0;
459 /* Make our register set point to the right place. */
461 cpu
.asregs
.active_gregs
= &cpu
.asregs
.alt_gregs
[0];
463 cpu
.asregs
.active_gregs
= &cpu
.asregs
.gregs
[0];
465 /* ABI specifies initial values for these registers. */
466 cpu
.gr
[0] = cpu
.asregs
.msize
- 4;
468 /* dac fix, the stack address must be 8-byte aligned! */
469 cpu
.gr
[0] = cpu
.gr
[0] - cpu
.gr
[0] % 8;
473 cpu
.gr
[PARM4
] = cpu
.gr
[0];
476 /* Functions so that trapped open/close don't interfere with the
477 parent's functions. We say that we can't close the descriptors
478 that we didn't open. exit() and cleanup() get in trouble here,
479 to some extent. That's the price of emulation. */
481 unsigned char opened
[100];
487 if (fd
< 0 || fd
> NUM_ELEM (opened
))
497 if (fd
< 0 || fd
> NUM_ELEM (opened
))
507 if (fd
< 0 || fd
> NUM_ELEM (opened
))
518 switch ((unsigned long) (cpu
.gr
[TRAPCODE
]))
521 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
522 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
523 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
524 cpu
.gr
[RET1
] = callback
->read (callback
, a
[0], (char *) a
[1], a
[2]);
528 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
529 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
530 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
531 cpu
.gr
[RET1
] = (int)callback
->write (callback
, a
[0], (char *) a
[1], a
[2]);
535 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
536 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
537 /* a[2] = (unsigned long) (cpu.gr[PARM3]); */
538 cpu
.gr
[RET1
] = callback
->open (callback
, (char *) a
[0], a
[1]);
539 log_open (cpu
.gr
[RET1
]);
543 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
544 /* Watch out for debugger's files. */
545 if (is_opened (a
[0]))
548 cpu
.gr
[RET1
] = callback
->close (callback
, a
[0]);
552 /* Don't let him close it. */
558 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
559 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
560 cpu
.gr
[RET1
] = link ((char *) a
[0], (char *) a
[1]);
564 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
565 cpu
.gr
[RET1
] = callback
->unlink (callback
, (char *) a
[0]);
569 /* handle time(0) vs time(&var) */
570 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
572 a
[0] += (unsigned long) cpu
.mem
;
573 cpu
.gr
[RET1
] = callback
->time (callback
, (time_t *) a
[0]);
577 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
578 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
579 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
580 cpu
.gr
[RET1
] = callback
->lseek (callback
, a
[0], a
[1], a
[2]);
584 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
585 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
586 cpu
.gr
[RET1
] = access ((char *) a
[0], a
[1]);
590 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
592 cpu
.gr
[RET1
] = times ((char *)a
[0]);
595 /* Give him simulated cycles for utime
596 and an instruction count for stime. */
605 t
.tms_utime
= cpu
.asregs
.cycles
;
606 t
.tms_stime
= cpu
.asregs
.insts
;
607 t
.tms_cutime
= t
.tms_utime
;
608 t
.tms_cstime
= t
.tms_stime
;
610 memcpy ((struct tms
*)(a
[0]), &t
, sizeof (t
));
612 cpu
.gr
[RET1
] = cpu
.asregs
.cycles
;
618 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
619 cpu
.gr
[RET1
] = int_sbrk (a
[0]);
624 fprintf (stderr
, "WARNING: sys call %d unimplemented\n",
634 /* These values should match those in libgloss/mcore/syscalls.s. */
641 case 10: /* _unlink */
642 case 19: /* _lseek */
643 case 43: /* _times */
644 cpu
.gr
[TRAPCODE
] = what
;
650 fprintf (stderr
, "Unhandled stub opcode: %d\n", what
);
662 cpu
.asregs
.exception
= SIGQUIT
;
671 a
[0] = (unsigned long)(cpu
.mem
+ cpu
.gr
[PARM1
]);
673 for (s
= (unsigned char *)a
[0], i
= 1 ; *s
&& i
< 6 ; s
++)
678 a
[i
] = (unsigned long)(cpu
.mem
+ cpu
.gr
[PARM1
+i
]);
680 a
[i
] = cpu
.gr
[i
+PARM1
];
685 cpu
.gr
[RET1
] = printf ((char *)a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
691 fprintf (stderr
, "WARNING: scanf unimplemented\n");
695 cpu
.gr
[RET1
] = cpu
.asregs
.insts
;
699 process_stub (cpu
.gr
[1]);
704 fprintf (stderr
, "Unhandled util code: %x\n", what
);
709 /* For figuring out whether we carried; addc/subc use this. */
718 x
= (a
& 0xffff) + (b
& 0xffff) + cin
;
719 x
= (x
>> 16) + (a
>> 16) + (b
>> 16);
725 #define WATCHFUNCTIONS 1
726 #ifdef WATCHFUNCTIONS
743 #define RD (inst & 0xF)
744 #define RS ((inst >> 4) & 0xF)
745 #define RX ((inst >> 8) & 0xF)
746 #define IMM5 ((inst >> 4) & 0x1F)
747 #define IMM4 ((inst) & 0xF)
749 static int tracing
= 0;
752 sim_resume (sd
, step
, siggnal
)
767 cpu
.asregs
.exception
= step
? SIGTRAP
: 0;
770 /* Fetch the initial instructions that we'll decode. */
771 ibuf
= rlat (pc
& 0xFFFFFFFC);
778 /* make our register set point to the right place */
780 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
782 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
784 /* make a hash to speed exec loop, hope it's nonzero */
787 for (w
= 1; w
<= ENDWL
; w
++)
788 WLhash
= WLhash
& WL
[w
];
798 if (! target_big_endian
)
801 inst
= ibuf
& 0xFFFF;
806 if (! target_big_endian
)
807 inst
= ibuf
& 0xFFFF;
812 #ifdef WATCHFUNCTIONS
813 /* now scan list of watch addresses, if match, count it and
814 note return address and count cycles until pc=return address */
816 if ((WLincyc
== 1) && (pc
== WLendpc
))
818 cycs
= (cpu
.asregs
.cycles
+ (insts
+ bonus_cycles
+
819 (memops
* memcycles
)) - WLbcyc
);
821 if (WLcnts
[WLW
] == 1)
828 if (cycs
> WLmax
[WLW
])
833 if (cycs
< WLmin
[WLW
])
843 /* Optimize with a hash to speed loop. */
846 if ((WLhash
== 0) || ((WLhash
& pc
) != 0))
848 for (w
=1; w
<= ENDWL
; w
++)
853 WLbcyc
= cpu
.asregs
.cycles
+ insts
854 + bonus_cycles
+ (memops
* memcycles
);
855 WLendpc
= cpu
.gr
[15];
866 fprintf (stderr
, "%.4x: inst = %.4x ", pc
, inst
);
881 cpu
.asregs
.exception
= SIGTRAP
;
894 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
896 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
905 cpu
.asregs
.active_gregs
= &cpu
.asregs
.alt_gregs
[0];
907 cpu
.asregs
.active_gregs
= &cpu
.asregs
.gregs
[0];
912 fprintf (stderr
, "WARNING: stop unimplemented\n");
917 fprintf (stderr
, "WARNING: wait unimplemented\n");
922 fprintf (stderr
, "WARNING: doze unimplemented\n");
926 cpu
.asregs
.exception
= SIGILL
; /* illegal */
929 case 0x8: /* trap 0 */
930 case 0xA: /* trap 2 */
931 case 0xB: /* trap 3 */
932 cpu
.asregs
.exception
= SIGTRAP
;
935 case 0xC: /* trap 4 */
936 case 0xD: /* trap 5 */
937 case 0xE: /* trap 6 */
938 cpu
.asregs
.exception
= SIGILL
; /* illegal */
941 case 0xF: /* trap 7 */
942 cpu
.asregs
.exception
= SIGTRAP
; /* integer div-by-0 */
945 case 0x9: /* trap 1 */
952 cpu
.asregs
.exception
= SIGILL
; /* illegal */
956 cpu
.gr
[RD
] = C_VALUE();
959 cpu
.gr
[RD
] = C_OFF();
963 char *addr
= (char *)cpu
.gr
[RD
];
964 int regno
= 4; /* always r4-r7 */
970 cpu
.gr
[regno
] = rlat(addr
);
974 while ((regno
&0x3) != 0);
979 char *addr
= (char *)cpu
.gr
[RD
];
980 int regno
= 4; /* always r4-r7 */
986 wlat(addr
, cpu
.gr
[regno
]);
990 while ((regno
& 0x3) != 0);
995 char *addr
= (char *)cpu
.gr
[0];
998 /* bonus cycle is really only needed if
999 the next insn shifts the last reg loaded.
1004 while (regno
<= 0xF)
1006 cpu
.gr
[regno
] = rlat(addr
);
1014 char *addr
= (char *)cpu
.gr
[0];
1017 /* this should be removed! */
1018 /* bonus_cycles ++; */
1020 memops
+= 16 - regno
;
1021 while (regno
<= 0xF)
1023 wlat(addr
, cpu
.gr
[regno
]);
1030 case 0x8: /* dect */
1031 cpu
.gr
[RD
] -= C_VALUE();
1033 case 0x9: /* decf */
1034 cpu
.gr
[RD
] -= C_OFF();
1036 case 0xA: /* inct */
1037 cpu
.gr
[RD
] += C_VALUE();
1039 case 0xB: /* incf */
1040 cpu
.gr
[RD
] += C_OFF();
1044 if (tracing
&& RD
== 15)
1045 fprintf (stderr
, "Func return, r2 = %x, r3 = %x\n",
1046 cpu
.gr
[2], cpu
.gr
[3]);
1060 for (i
= 0; !(tmp
& 0x80000000) && i
< 32; i
++)
1065 case 0xF: /* brev */
1069 tmp
= ((tmp
& 0xaaaaaaaa) >> 1) | ((tmp
& 0x55555555) << 1);
1070 tmp
= ((tmp
& 0xcccccccc) >> 2) | ((tmp
& 0x33333333) << 2);
1071 tmp
= ((tmp
& 0xf0f0f0f0) >> 4) | ((tmp
& 0x0f0f0f0f) << 4);
1072 tmp
= ((tmp
& 0xff00ff00) >> 8) | ((tmp
& 0x00ff00ff) << 8);
1073 cpu
.gr
[RD
] = ((tmp
& 0xffff0000) >> 16) | ((tmp
& 0x0000ffff) << 16);
1081 case 0x0: /* xtrb3 */
1082 cpu
.gr
[1] = (cpu
.gr
[RD
]) & 0xFF;
1083 NEW_C (cpu
.gr
[RD
] != 0);
1085 case 0x1: /* xtrb2 */
1086 cpu
.gr
[1] = (cpu
.gr
[RD
]>>8) & 0xFF;
1087 NEW_C (cpu
.gr
[RD
] != 0);
1089 case 0x2: /* xtrb1 */
1090 cpu
.gr
[1] = (cpu
.gr
[RD
]>>16) & 0xFF;
1091 NEW_C (cpu
.gr
[RD
] != 0);
1093 case 0x3: /* xtrb0 */
1094 cpu
.gr
[1] = (cpu
.gr
[RD
]>>24) & 0xFF;
1095 NEW_C (cpu
.gr
[RD
] != 0);
1097 case 0x4: /* zextb */
1098 cpu
.gr
[RD
] &= 0x000000FF;
1100 case 0x5: /* sextb */
1109 case 0x6: /* zexth */
1110 cpu
.gr
[RD
] &= 0x0000FFFF;
1112 case 0x7: /* sexth */
1121 case 0x8: /* declt */
1123 NEW_C ((long)cpu
.gr
[RD
] < 0);
1125 case 0x9: /* tstnbz */
1127 word tmp
= cpu
.gr
[RD
];
1128 NEW_C ((tmp
& 0xFF000000) != 0 &&
1129 (tmp
& 0x00FF0000) != 0 && (tmp
& 0x0000FF00) != 0 &&
1130 (tmp
& 0x000000FF) != 0);
1133 case 0xA: /* decgt */
1135 NEW_C ((long)cpu
.gr
[RD
] > 0);
1137 case 0xB: /* decne */
1139 NEW_C ((long)cpu
.gr
[RD
] != 0);
1141 case 0xC: /* clrt */
1145 case 0xD: /* clrf */
1150 if (cpu
.gr
[RD
] & 0x80000000)
1151 cpu
.gr
[RD
] = ~cpu
.gr
[RD
] + 1;
1154 cpu
.gr
[RD
] = ~cpu
.gr
[RD
];
1158 case 0x02: /* movt */
1160 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1162 case 0x03: /* mult */
1163 /* consume 2 bits per cycle from rs, until rs is 0 */
1165 unsigned int t
= cpu
.gr
[RS
];
1167 for (ticks
= 0; t
!= 0 ; t
>>= 2)
1169 bonus_cycles
+= ticks
;
1171 bonus_cycles
+= 2; /* min. is 3, so add 2, plus ticks above */
1173 fprintf (stderr
, " mult %x by %x to give %x",
1174 cpu
.gr
[RD
], cpu
.gr
[RS
], cpu
.gr
[RD
] * cpu
.gr
[RS
]);
1175 cpu
.gr
[RD
] = cpu
.gr
[RD
] * cpu
.gr
[RS
];
1177 case 0x04: /* loopt */
1180 pc
+= (IMM4
<< 1) - 32;
1184 --cpu
.gr
[RS
]; /* not RD! */
1185 NEW_C (((long)cpu
.gr
[RS
]) > 0);
1187 case 0x05: /* subu */
1188 cpu
.gr
[RD
] -= cpu
.gr
[RS
];
1190 case 0x06: /* addc */
1192 unsigned long tmp
, a
, b
;
1195 cpu
.gr
[RD
] = a
+ b
+ C_VALUE ();
1196 tmp
= iu_carry (a
, b
, C_VALUE ());
1200 case 0x07: /* subc */
1202 unsigned long tmp
, a
, b
;
1205 cpu
.gr
[RD
] = a
- b
+ C_VALUE () - 1;
1206 tmp
= iu_carry (a
,~b
, C_VALUE ());
1210 case 0x08: /* illegal */
1211 case 0x09: /* illegal*/
1212 cpu
.asregs
.exception
= SIGILL
;
1214 case 0x0A: /* movf */
1216 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1218 case 0x0B: /* lsr */
1220 unsigned long dst
, src
;
1223 /* We must not rely solely upon the native shift operations, since they
1224 may not match the M*Core's behaviour on boundary conditions. */
1225 dst
= src
> 31 ? 0 : dst
>> src
;
1229 case 0x0C: /* cmphs */
1230 NEW_C ((unsigned long )cpu
.gr
[RD
] >=
1231 (unsigned long)cpu
.gr
[RS
]);
1233 case 0x0D: /* cmplt */
1234 NEW_C ((long)cpu
.gr
[RD
] < (long)cpu
.gr
[RS
]);
1236 case 0x0E: /* tst */
1237 NEW_C ((cpu
.gr
[RD
] & cpu
.gr
[RS
]) != 0);
1239 case 0x0F: /* cmpne */
1240 NEW_C (cpu
.gr
[RD
] != cpu
.gr
[RS
]);
1242 case 0x10: case 0x11: /* mfcr */
1246 if (r
<= LAST_VALID_CREG
)
1247 cpu
.gr
[RD
] = cpu
.cr
[r
];
1249 cpu
.asregs
.exception
= SIGILL
;
1253 case 0x12: /* mov */
1254 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1256 fprintf (stderr
, "MOV %x into reg %d", cpu
.gr
[RD
], RD
);
1259 case 0x13: /* bgenr */
1260 if (cpu
.gr
[RS
] & 0x20)
1263 cpu
.gr
[RD
] = 1 << (cpu
.gr
[RS
] & 0x1F);
1266 case 0x14: /* rsub */
1267 cpu
.gr
[RD
] = cpu
.gr
[RS
] - cpu
.gr
[RD
];
1270 case 0x15: /* ixw */
1271 cpu
.gr
[RD
] += cpu
.gr
[RS
]<<2;
1274 case 0x16: /* and */
1275 cpu
.gr
[RD
] &= cpu
.gr
[RS
];
1278 case 0x17: /* xor */
1279 cpu
.gr
[RD
] ^= cpu
.gr
[RS
];
1282 case 0x18: case 0x19: /* mtcr */
1286 if (r
<= LAST_VALID_CREG
)
1287 cpu
.cr
[r
] = cpu
.gr
[RD
];
1289 cpu
.asregs
.exception
= SIGILL
;
1291 /* we might have changed register sets... */
1293 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
1295 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
1299 case 0x1A: /* asr */
1300 /* We must not rely solely upon the native shift operations, since they
1301 may not match the M*Core's behaviour on boundary conditions. */
1302 if (cpu
.gr
[RS
] > 30)
1303 cpu
.gr
[RD
] = ((long) cpu
.gr
[RD
]) < 0 ? -1 : 0;
1305 cpu
.gr
[RD
] = (long) cpu
.gr
[RD
] >> cpu
.gr
[RS
];
1308 case 0x1B: /* lsl */
1309 /* We must not rely solely upon the native shift operations, since they
1310 may not match the M*Core's behaviour on boundary conditions. */
1311 cpu
.gr
[RD
] = cpu
.gr
[RS
] > 31 ? 0 : cpu
.gr
[RD
] << cpu
.gr
[RS
];
1314 case 0x1C: /* addu */
1315 cpu
.gr
[RD
] += cpu
.gr
[RS
];
1318 case 0x1D: /* ixh */
1319 cpu
.gr
[RD
] += cpu
.gr
[RS
] << 1;
1323 cpu
.gr
[RD
] |= cpu
.gr
[RS
];
1326 case 0x1F: /* andn */
1327 cpu
.gr
[RD
] &= ~cpu
.gr
[RS
];
1329 case 0x20: case 0x21: /* addi */
1331 cpu
.gr
[RD
] + (IMM5
+ 1);
1333 case 0x22: case 0x23: /* cmplti */
1335 int tmp
= (IMM5
+ 1);
1336 if (cpu
.gr
[RD
] < tmp
)
1346 case 0x24: case 0x25: /* subi */
1348 cpu
.gr
[RD
] - (IMM5
+ 1);
1350 case 0x26: case 0x27: /* illegal */
1351 cpu
.asregs
.exception
= SIGILL
;
1353 case 0x28: case 0x29: /* rsubi */
1357 case 0x2A: case 0x2B: /* cmpnei */
1358 if (cpu
.gr
[RD
] != IMM5
)
1368 case 0x2C: case 0x2D: /* bmaski, divu */
1370 unsigned imm
= IMM5
;
1376 unsigned int rx
, r1
;
1382 /* unsigned divide */
1383 cpu
.gr
[RD
] = (word
) ((unsigned int) cpu
.gr
[RD
] / (unsigned int)cpu
.gr
[1] );
1385 /* compute bonus_cycles for divu */
1386 for (r1nlz
= 0; ((r1
& 0x80000000) == 0) && (r1nlz
< 32); r1nlz
++)
1389 for (rxnlz
= 0; ((rx
& 0x80000000) == 0) && (rxnlz
< 32); rxnlz
++)
1395 exe
+= 5 + r1nlz
- rxnlz
;
1397 if (exe
>= (2 * memcycles
- 1))
1399 bonus_cycles
+= exe
- (2 * memcycles
) + 1;
1402 else if (imm
== 0 || imm
>= 8)
1408 cpu
.gr
[RD
] = (1 << imm
) - 1;
1413 cpu
.asregs
.exception
= SIGILL
;
1417 case 0x2E: case 0x2F: /* andi */
1418 cpu
.gr
[RD
] = cpu
.gr
[RD
] & IMM5
;
1420 case 0x30: case 0x31: /* bclri */
1421 cpu
.gr
[RD
] = cpu
.gr
[RD
] & ~(1<<IMM5
);
1423 case 0x32: case 0x33: /* bgeni, divs */
1425 unsigned imm
= IMM5
;
1432 /* compute bonus_cycles for divu */
1437 if (((rx
< 0) && (r1
> 0)) || ((rx
>= 0) && (r1
< 0)))
1445 /* signed divide, general registers are of type int, so / op is OK */
1446 cpu
.gr
[RD
] = cpu
.gr
[RD
] / cpu
.gr
[1];
1448 for (r1nlz
= 0; ((r1
& 0x80000000) == 0) && (r1nlz
< 32) ; r1nlz
++ )
1451 for (rxnlz
= 0; ((rx
& 0x80000000) == 0) && (rxnlz
< 32) ; rxnlz
++ )
1457 exe
+= 6 + r1nlz
- rxnlz
+ sc
;
1459 if (exe
>= (2 * memcycles
- 1))
1461 bonus_cycles
+= exe
- (2 * memcycles
) + 1;
1467 cpu
.gr
[RD
] = (1 << IMM5
);
1472 cpu
.asregs
.exception
= SIGILL
;
1476 case 0x34: case 0x35: /* bseti */
1477 cpu
.gr
[RD
] = cpu
.gr
[RD
] | (1 << IMM5
);
1479 case 0x36: case 0x37: /* btsti */
1480 NEW_C (cpu
.gr
[RD
] >> IMM5
);
1482 case 0x38: case 0x39: /* xsr, rotli */
1484 unsigned imm
= IMM5
;
1485 unsigned long tmp
= cpu
.gr
[RD
];
1491 cpu
.gr
[RD
] = (cbit
<< 31) | (tmp
>> 1);
1494 cpu
.gr
[RD
] = (tmp
<< imm
) | (tmp
>> (32 - imm
));
1497 case 0x3A: case 0x3B: /* asrc, asri */
1499 unsigned imm
= IMM5
;
1500 long tmp
= cpu
.gr
[RD
];
1504 cpu
.gr
[RD
] = tmp
>> 1;
1507 cpu
.gr
[RD
] = tmp
>> imm
;
1510 case 0x3C: case 0x3D: /* lslc, lsli */
1512 unsigned imm
= IMM5
;
1513 unsigned long tmp
= cpu
.gr
[RD
];
1517 cpu
.gr
[RD
] = tmp
<< 1;
1520 cpu
.gr
[RD
] = tmp
<< imm
;
1523 case 0x3E: case 0x3F: /* lsrc, lsri */
1525 unsigned imm
= IMM5
;
1526 unsigned long tmp
= cpu
.gr
[RD
];
1530 cpu
.gr
[RD
] = tmp
>> 1;
1533 cpu
.gr
[RD
] = tmp
>> imm
;
1536 case 0x40: case 0x41: case 0x42: case 0x43:
1537 case 0x44: case 0x45: case 0x46: case 0x47:
1538 case 0x48: case 0x49: case 0x4A: case 0x4B:
1539 case 0x4C: case 0x4D: case 0x4E: case 0x4F:
1540 cpu
.asregs
.exception
= SIGILL
;
1545 case 0x51: case 0x52: case 0x53:
1546 case 0x54: case 0x55: case 0x56: case 0x57:
1547 case 0x58: case 0x59: case 0x5A: case 0x5B:
1548 case 0x5C: case 0x5D: case 0x5E: case 0x5F:
1549 cpu
.asregs
.exception
= SIGILL
;
1551 case 0x60: case 0x61: case 0x62: case 0x63: /* movi */
1552 case 0x64: case 0x65: case 0x66: case 0x67:
1553 cpu
.gr
[RD
] = (inst
>> 4) & 0x7F;
1555 case 0x68: case 0x69: case 0x6A: case 0x6B:
1556 case 0x6C: case 0x6D: case 0x6E: case 0x6F: /* illegal */
1557 cpu
.asregs
.exception
= SIGILL
;
1559 case 0x71: case 0x72: case 0x73:
1560 case 0x74: case 0x75: case 0x76: case 0x77:
1561 case 0x78: case 0x79: case 0x7A: case 0x7B:
1562 case 0x7C: case 0x7D: case 0x7E: /* lrw */
1563 cpu
.gr
[RX
] = rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC);
1565 fprintf (stderr
, "LRW of 0x%x from 0x%x to reg %d",
1566 rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC),
1567 (pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC, RX
);
1570 case 0x7F: /* jsri */
1573 fprintf (stderr
, "func call: r2 = %x r3 = %x r4 = %x r5 = %x r6 = %x r7 = %x\n",
1574 cpu
.gr
[2], cpu
.gr
[3], cpu
.gr
[4], cpu
.gr
[5], cpu
.gr
[6], cpu
.gr
[7]);
1575 case 0x70: /* jmpi */
1576 pc
= rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC);
1582 case 0x80: case 0x81: case 0x82: case 0x83:
1583 case 0x84: case 0x85: case 0x86: case 0x87:
1584 case 0x88: case 0x89: case 0x8A: case 0x8B:
1585 case 0x8C: case 0x8D: case 0x8E: case 0x8F: /* ld */
1586 cpu
.gr
[RX
] = rlat (cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C));
1588 fprintf (stderr
, "load reg %d from 0x%x with 0x%x",
1590 cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C), cpu
.gr
[RX
]);
1593 case 0x90: case 0x91: case 0x92: case 0x93:
1594 case 0x94: case 0x95: case 0x96: case 0x97:
1595 case 0x98: case 0x99: case 0x9A: case 0x9B:
1596 case 0x9C: case 0x9D: case 0x9E: case 0x9F: /* st */
1597 wlat (cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C), cpu
.gr
[RX
]);
1599 fprintf (stderr
, "store reg %d (containing 0x%x) to 0x%x",
1601 cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C));
1604 case 0xA0: case 0xA1: case 0xA2: case 0xA3:
1605 case 0xA4: case 0xA5: case 0xA6: case 0xA7:
1606 case 0xA8: case 0xA9: case 0xAA: case 0xAB:
1607 case 0xAC: case 0xAD: case 0xAE: case 0xAF: /* ld.b */
1608 cpu
.gr
[RX
] = rbat (cpu
.gr
[RD
] + RS
);
1611 case 0xB0: case 0xB1: case 0xB2: case 0xB3:
1612 case 0xB4: case 0xB5: case 0xB6: case 0xB7:
1613 case 0xB8: case 0xB9: case 0xBA: case 0xBB:
1614 case 0xBC: case 0xBD: case 0xBE: case 0xBF: /* st.b */
1615 wbat (cpu
.gr
[RD
] + RS
, cpu
.gr
[RX
]);
1618 case 0xC0: case 0xC1: case 0xC2: case 0xC3:
1619 case 0xC4: case 0xC5: case 0xC6: case 0xC7:
1620 case 0xC8: case 0xC9: case 0xCA: case 0xCB:
1621 case 0xCC: case 0xCD: case 0xCE: case 0xCF: /* ld.h */
1622 cpu
.gr
[RX
] = rhat (cpu
.gr
[RD
] + ((inst
>> 3) & 0x001E));
1625 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
1626 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
1627 case 0xD8: case 0xD9: case 0xDA: case 0xDB:
1628 case 0xDC: case 0xDD: case 0xDE: case 0xDF: /* st.h */
1629 what (cpu
.gr
[RD
] + ((inst
>> 3) & 0x001E), cpu
.gr
[RX
]);
1632 case 0xE8: case 0xE9: case 0xEA: case 0xEB:
1633 case 0xEC: case 0xED: case 0xEE: case 0xEF: /* bf */
1637 disp
= inst
& 0x03FF;
1645 case 0xE0: case 0xE1: case 0xE2: case 0xE3:
1646 case 0xE4: case 0xE5: case 0xE6: case 0xE7: /* bt */
1650 disp
= inst
& 0x03FF;
1659 case 0xF8: case 0xF9: case 0xFA: case 0xFB:
1660 case 0xFC: case 0xFD: case 0xFE: case 0xFF: /* bsr */
1662 case 0xF0: case 0xF1: case 0xF2: case 0xF3:
1663 case 0xF4: case 0xF5: case 0xF6: case 0xF7: /* br */
1666 disp
= inst
& 0x03FF;
1678 fprintf (stderr
, "\n");
1682 /* Do not let him fetch from a bad address! */
1683 if (((uword
)pc
) >= cpu
.asregs
.msize
)
1686 fprintf (stderr
, "PC loaded at 0x%x is outside of available memory! (0x%x)\n", oldpc
, pc
);
1688 cpu
.asregs
.exception
= SIGSEGV
;
1692 ibuf
= rlat (pc
& 0xFFFFFFFC);
1697 while (!cpu
.asregs
.exception
);
1699 /* Hide away the things we've cached while executing. */
1701 cpu
.asregs
.insts
+= insts
; /* instructions done ... */
1702 cpu
.asregs
.cycles
+= insts
; /* and each takes a cycle */
1703 cpu
.asregs
.cycles
+= bonus_cycles
; /* and extra cycles for branches */
1704 cpu
.asregs
.cycles
+= memops
* memcycles
; /* and memop cycle delays */
1709 sim_write (sd
, addr
, buffer
, size
)
1712 const unsigned char * buffer
;
1718 memcpy (& cpu
.mem
[addr
], buffer
, size
);
1724 sim_read (sd
, addr
, buffer
, size
)
1727 unsigned char * buffer
;
1733 memcpy (buffer
, & cpu
.mem
[addr
], size
);
1740 sim_store_register (sd
, rn
, memory
, length
)
1743 unsigned char * memory
;
1748 if (rn
< NUM_MCORE_REGS
&& rn
>= 0)
1754 /* misalignment safe */
1755 ival
= mcore_extract_unsigned_integer (memory
, 4);
1756 cpu
.asints
[rn
] = ival
;
1766 sim_fetch_register (sd
, rn
, memory
, length
)
1769 unsigned char * memory
;
1774 if (rn
< NUM_MCORE_REGS
&& rn
>= 0)
1778 long ival
= cpu
.asints
[rn
];
1780 /* misalignment-safe */
1781 mcore_store_unsigned_integer (memory
, 4, ival
);
1797 sim_resume (sd
, 0, 0);
1805 sim_stop_reason (sd
, reason
, sigrc
)
1807 enum sim_stop
* reason
;
1810 if (cpu
.asregs
.exception
== SIGQUIT
)
1812 * reason
= sim_exited
;
1813 * sigrc
= cpu
.gr
[PARM1
];
1817 * reason
= sim_stopped
;
1818 * sigrc
= cpu
.asregs
.exception
;
1827 cpu
.asregs
.exception
= SIGINT
;
1833 sim_info (sd
, verbose
)
1837 #ifdef WATCHFUNCTIONS
1840 double virttime
= cpu
.asregs
.cycles
/ 36.0e6
;
1842 callback
->printf_filtered (callback
, "\n\n# instructions executed %10d\n",
1844 callback
->printf_filtered (callback
, "# cycles %10d\n",
1846 callback
->printf_filtered (callback
, "# pipeline stalls %10d\n",
1848 callback
->printf_filtered (callback
, "# virtual time taken %10.4f\n",
1851 #ifdef WATCHFUNCTIONS
1852 callback
->printf_filtered (callback
, "\nNumber of watched functions: %d\n",
1857 for (w
= 1; w
<= ENDWL
; w
++)
1859 callback
->printf_filtered (callback
, "WL = %s %8x\n",WLstr
[w
],WL
[w
]);
1860 callback
->printf_filtered (callback
, " calls = %d, cycles = %d\n",
1861 WLcnts
[w
],WLcyc
[w
]);
1864 callback
->printf_filtered (callback
,
1865 " maxcpc = %d, mincpc = %d, avecpc = %d\n",
1866 WLmax
[w
],WLmin
[w
],WLcyc
[w
]/WLcnts
[w
]);
1870 callback
->printf_filtered (callback
,
1871 "Total cycles for watched functions: %d\n",wcyc
);
1877 unsigned char sa_machtype
[2];
1878 unsigned char sa_magic
[2];
1879 unsigned char sa_tsize
[4];
1880 unsigned char sa_dsize
[4];
1881 unsigned char sa_bsize
[4];
1882 unsigned char sa_syms
[4];
1883 unsigned char sa_entry
[4];
1884 unsigned char sa_trelo
[4];
1885 unsigned char sa_drelo
[4];
1888 #define LONG(x) (((x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
1889 #define SHORT(x) (((x)[0]<<8)|(x)[1])
1892 sim_open (kind
, cb
, abfd
, argv
)
1898 int osize
= sim_memory_size
;
1902 if (kind
== SIM_OPEN_STANDALONE
)
1905 /* Discard and reacquire memory -- start with a clean slate. */
1906 sim_size (1); /* small */
1907 sim_size (osize
); /* and back again */
1909 set_initial_gprs (); /* Reset the GPR registers. */
1911 /* Fudge our descriptor for now. */
1912 return (SIM_DESC
) 1;
1916 sim_close (sd
, quitting
)
1924 sim_load (sd
, prog
, abfd
, from_tty
)
1930 /* Do the right thing for ELF executables; this turns out to be
1931 just about the right thing for any object format that:
1932 - we crack using BFD routines
1933 - follows the traditional UNIX text/data/bss layout
1934 - calls the bss section ".bss". */
1936 extern bfd
* sim_load_file (); /* ??? Don't know where this should live. */
1942 handle
= bfd_openr (prog
, 0); /* could be "mcore" */
1946 printf("``%s'' could not be opened.\n", prog
);
1950 /* Makes sure that we have an object file, also cleans gets the
1951 section headers in place. */
1952 if (!bfd_check_format (handle
, bfd_object
))
1954 /* wasn't an object file */
1956 printf ("``%s'' is not appropriate object file.\n", prog
);
1960 /* Look for that bss section. */
1961 s_bss
= bfd_get_section_by_name (handle
, ".bss");
1965 printf("``%s'' has no bss section.\n", prog
);
1969 /* Appropriately paranoid would check that we have
1970 a traditional text/data/bss ordering within memory. */
1972 /* figure the end of the bss section */
1974 printf ("bss section at 0x%08x for 0x%08x bytes\n",
1975 (unsigned long) bfd_get_section_vma (handle
, s_bss
),
1976 (unsigned long) bfd_section_size (handle
, s_bss
));
1978 heap_ptr
= ((unsigned long) bfd_get_section_vma (handle
, s_bss
)
1979 + (unsigned long) bfd_section_size (handle
, s_bss
));
1981 /* Clean up after ourselves. */
1984 /* XXX: do we need to free the s_bss and handle structures? */
1987 /* from sh -- dac */
1988 prog_bfd
= sim_load_file (sd
, myname
, callback
, prog
, abfd
,
1989 sim_kind
== SIM_OPEN_DEBUG
,
1991 if (prog_bfd
== NULL
)
1994 target_big_endian
= bfd_big_endian (prog_bfd
);
1997 bfd_close (prog_bfd
);
2003 sim_create_inferior (sd
, prog_bfd
, argv
, env
)
2005 struct bfd
* prog_bfd
;
2014 unsigned long strings
;
2015 unsigned long pointers
;
2016 unsigned long hi_stack
;
2019 /* Set the initial register set. */
2022 set_initial_gprs ();
2025 hi_stack
= cpu
.asregs
.msize
- 4;
2026 cpu
.asregs
.pc
= bfd_get_start_address (prog_bfd
);
2028 /* Calculate the argument and environment strings. */
2034 l
= strlen (*avp
) + 1; /* include the null */
2035 s_length
+= (l
+ 3) & ~3; /* make it a 4 byte boundary */
2043 l
= strlen (*avp
) + 1; /* include the null */
2044 s_length
+= (l
+ 3) & ~ 3;/* make it a 4 byte boundary */
2048 /* Claim some memory for the pointers and strings. */
2049 pointers
= hi_stack
- sizeof(word
) * (nenv
+1+nargs
+1);
2050 pointers
&= ~3; /* must be 4-byte aligned */
2051 cpu
.gr
[0] = pointers
;
2053 strings
= cpu
.gr
[0] - s_length
;
2054 strings
&= ~3; /* want to make it 4-byte aligned */
2055 cpu
.gr
[0] = strings
;
2056 /* dac fix, the stack address must be 8-byte aligned! */
2057 cpu
.gr
[0] = cpu
.gr
[0] - cpu
.gr
[0] % 8;
2059 /* Loop through the arguments and fill them in. */
2060 cpu
.gr
[PARM1
] = nargs
;
2063 /* No strings to fill in. */
2068 cpu
.gr
[PARM2
] = pointers
;
2072 /* Save where we're putting it. */
2073 wlat (pointers
, strings
);
2075 /* Copy the string. */
2076 l
= strlen (* avp
) + 1;
2077 strcpy ((char *)(cpu
.mem
+ strings
), *avp
);
2079 /* Bump the pointers. */
2085 /* A null to finish the list. */
2090 /* Now do the environment pointers. */
2093 /* No strings to fill in. */
2098 cpu
.gr
[PARM3
] = pointers
;
2103 /* Save where we're putting it. */
2104 wlat (pointers
, strings
);
2106 /* Copy the string. */
2107 l
= strlen (* avp
) + 1;
2108 strcpy ((char *)(cpu
.mem
+ strings
), *avp
);
2110 /* Bump the pointers. */
2116 /* A null to finish the list. */
2132 sim_do_command (sd
, cmd
)
2136 /* Nothing there yet; it's all an error. */
2140 char ** simargv
= buildargv (cmd
);
2142 if (strcmp (simargv
[0], "watch") == 0)
2144 if ((simargv
[1] == NULL
) || (simargv
[2] == NULL
))
2146 fprintf (stderr
, "Error: missing argument to watch cmd.\n");
2153 WL
[ENDWL
] = strtol (simargv
[2], NULL
, 0);
2154 WLstr
[ENDWL
] = strdup (simargv
[1]);
2155 fprintf (stderr
, "Added %s (%x) to watchlist, #%d\n",WLstr
[ENDWL
],
2159 else if (strcmp (simargv
[0], "dumpmem") == 0)
2164 if (simargv
[1] == NULL
)
2165 fprintf (stderr
, "Error: missing argument to dumpmem cmd.\n");
2167 fprintf (stderr
, "Writing dumpfile %s...",simargv
[1]);
2169 dumpfile
= fopen (simargv
[1], "w");
2171 fwrite (p
, cpu
.asregs
.msize
-1, 1, dumpfile
);
2174 fprintf (stderr
, "done.\n");
2176 else if (strcmp (simargv
[0], "clearstats") == 0)
2178 cpu
.asregs
.cycles
= 0;
2179 cpu
.asregs
.insts
= 0;
2180 cpu
.asregs
.stalls
= 0;
2183 else if (strcmp (simargv
[0], "verbose") == 0)
2189 fprintf (stderr
,"Error: \"%s\" is not a valid M.CORE simulator command.\n",
2197 fprintf (stderr
, "M.CORE sim commands: \n");
2198 fprintf (stderr
, " watch <funcname> <addr>\n");
2199 fprintf (stderr
, " dumpmem <filename>\n");
2200 fprintf (stderr
, " clearstats\n");
2201 fprintf (stderr
, " verbose\n");
2206 sim_set_callbacks (ptr
)
2207 host_callback
* ptr
;
This page took 0.105988 seconds and 4 git commands to generate.