1 /* Simulator for Motorola's MCore processor
2 Copyright (C) 1999-2000, 2002-2003, 2007-2012 Free Software
4 Contributed by Cygnus Solutions.
6 This file is part of GDB, the GNU debugger.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 #include <sys/times.h>
25 #include <sys/param.h>
26 #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];
479 cpu
.asregs
.exception
= SIGINT
;
482 /* Functions so that trapped open/close don't interfere with the
483 parent's functions. We say that we can't close the descriptors
484 that we didn't open. exit() and cleanup() get in trouble here,
485 to some extent. That's the price of emulation. */
487 unsigned char opened
[100];
493 if (fd
< 0 || fd
> NUM_ELEM (opened
))
503 if (fd
< 0 || fd
> NUM_ELEM (opened
))
513 if (fd
< 0 || fd
> NUM_ELEM (opened
))
524 switch ((unsigned long) (cpu
.gr
[TRAPCODE
]))
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
] = callback
->read (callback
, a
[0], (char *) a
[1], a
[2]);
534 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
535 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
536 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
537 cpu
.gr
[RET1
] = (int)callback
->write (callback
, a
[0], (char *) a
[1], a
[2]);
541 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
542 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
543 /* a[2] = (unsigned long) (cpu.gr[PARM3]); */
544 cpu
.gr
[RET1
] = callback
->open (callback
, (char *) a
[0], a
[1]);
545 log_open (cpu
.gr
[RET1
]);
549 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
550 /* Watch out for debugger's files. */
551 if (is_opened (a
[0]))
554 cpu
.gr
[RET1
] = callback
->close (callback
, a
[0]);
558 /* Don't let him close it. */
564 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
565 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
566 cpu
.gr
[RET1
] = link ((char *) a
[0], (char *) a
[1]);
570 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
571 cpu
.gr
[RET1
] = callback
->unlink (callback
, (char *) a
[0]);
575 /* handle time(0) vs time(&var) */
576 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
578 a
[0] += (unsigned long) cpu
.mem
;
579 cpu
.gr
[RET1
] = callback
->time (callback
, (time_t *) a
[0]);
583 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
584 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
585 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
586 cpu
.gr
[RET1
] = callback
->lseek (callback
, a
[0], a
[1], a
[2]);
590 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
591 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
592 cpu
.gr
[RET1
] = access ((char *) a
[0], a
[1]);
596 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
598 cpu
.gr
[RET1
] = times ((char *)a
[0]);
601 /* Give him simulated cycles for utime
602 and an instruction count for stime. */
611 t
.tms_utime
= cpu
.asregs
.cycles
;
612 t
.tms_stime
= cpu
.asregs
.insts
;
613 t
.tms_cutime
= t
.tms_utime
;
614 t
.tms_cstime
= t
.tms_stime
;
616 memcpy ((struct tms
*)(a
[0]), &t
, sizeof (t
));
618 cpu
.gr
[RET1
] = cpu
.asregs
.cycles
;
624 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
625 cpu
.gr
[RET1
] = int_sbrk (a
[0]);
630 fprintf (stderr
, "WARNING: sys call %d unimplemented\n",
640 /* These values should match those in libgloss/mcore/syscalls.s. */
647 case 10: /* _unlink */
648 case 19: /* _lseek */
649 case 43: /* _times */
650 cpu
.gr
[TRAPCODE
] = what
;
656 fprintf (stderr
, "Unhandled stub opcode: %d\n", what
);
668 cpu
.asregs
.exception
= SIGQUIT
;
677 a
[0] = (unsigned long)(cpu
.mem
+ cpu
.gr
[PARM1
]);
679 for (s
= (unsigned char *)a
[0], i
= 1 ; *s
&& i
< 6 ; s
++)
684 a
[i
] = (unsigned long)(cpu
.mem
+ cpu
.gr
[PARM1
+i
]);
686 a
[i
] = cpu
.gr
[i
+PARM1
];
691 cpu
.gr
[RET1
] = printf ((char *)a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
697 fprintf (stderr
, "WARNING: scanf unimplemented\n");
701 cpu
.gr
[RET1
] = cpu
.asregs
.insts
;
705 process_stub (cpu
.gr
[1]);
710 fprintf (stderr
, "Unhandled util code: %x\n", what
);
715 /* For figuring out whether we carried; addc/subc use this. */
724 x
= (a
& 0xffff) + (b
& 0xffff) + cin
;
725 x
= (x
>> 16) + (a
>> 16) + (b
>> 16);
731 #define WATCHFUNCTIONS 1
732 #ifdef WATCHFUNCTIONS
749 #define RD (inst & 0xF)
750 #define RS ((inst >> 4) & 0xF)
751 #define RX ((inst >> 8) & 0xF)
752 #define IMM5 ((inst >> 4) & 0x1F)
753 #define IMM4 ((inst) & 0xF)
755 static int tracing
= 0;
758 sim_resume (sd
, step
, siggnal
)
774 sigsave
= signal (SIGINT
, interrupt
);
775 cpu
.asregs
.exception
= step
? SIGTRAP
: 0;
778 /* Fetch the initial instructions that we'll decode. */
779 ibuf
= rlat (pc
& 0xFFFFFFFC);
786 /* make our register set point to the right place */
788 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
790 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
792 /* make a hash to speed exec loop, hope it's nonzero */
795 for (w
= 1; w
<= ENDWL
; w
++)
796 WLhash
= WLhash
& WL
[w
];
806 if (! target_big_endian
)
809 inst
= ibuf
& 0xFFFF;
814 if (! target_big_endian
)
815 inst
= ibuf
& 0xFFFF;
820 #ifdef WATCHFUNCTIONS
821 /* now scan list of watch addresses, if match, count it and
822 note return address and count cycles until pc=return address */
824 if ((WLincyc
== 1) && (pc
== WLendpc
))
826 cycs
= (cpu
.asregs
.cycles
+ (insts
+ bonus_cycles
+
827 (memops
* memcycles
)) - WLbcyc
);
829 if (WLcnts
[WLW
] == 1)
836 if (cycs
> WLmax
[WLW
])
841 if (cycs
< WLmin
[WLW
])
851 /* Optimize with a hash to speed loop. */
854 if ((WLhash
== 0) || ((WLhash
& pc
) != 0))
856 for (w
=1; w
<= ENDWL
; w
++)
861 WLbcyc
= cpu
.asregs
.cycles
+ insts
862 + bonus_cycles
+ (memops
* memcycles
);
863 WLendpc
= cpu
.gr
[15];
874 fprintf (stderr
, "%.4x: inst = %.4x ", pc
, inst
);
889 cpu
.asregs
.exception
= SIGTRAP
;
902 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
904 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
913 cpu
.asregs
.active_gregs
= &cpu
.asregs
.alt_gregs
[0];
915 cpu
.asregs
.active_gregs
= &cpu
.asregs
.gregs
[0];
920 fprintf (stderr
, "WARNING: stop unimplemented\n");
925 fprintf (stderr
, "WARNING: wait unimplemented\n");
930 fprintf (stderr
, "WARNING: doze unimplemented\n");
934 cpu
.asregs
.exception
= SIGILL
; /* illegal */
937 case 0x8: /* trap 0 */
938 case 0xA: /* trap 2 */
939 case 0xB: /* trap 3 */
940 cpu
.asregs
.exception
= SIGTRAP
;
943 case 0xC: /* trap 4 */
944 case 0xD: /* trap 5 */
945 case 0xE: /* trap 6 */
946 cpu
.asregs
.exception
= SIGILL
; /* illegal */
949 case 0xF: /* trap 7 */
950 cpu
.asregs
.exception
= SIGTRAP
; /* integer div-by-0 */
953 case 0x9: /* trap 1 */
960 cpu
.asregs
.exception
= SIGILL
; /* illegal */
964 cpu
.gr
[RD
] = C_VALUE();
967 cpu
.gr
[RD
] = C_OFF();
971 char *addr
= (char *)cpu
.gr
[RD
];
972 int regno
= 4; /* always r4-r7 */
978 cpu
.gr
[regno
] = rlat(addr
);
982 while ((regno
&0x3) != 0);
987 char *addr
= (char *)cpu
.gr
[RD
];
988 int regno
= 4; /* always r4-r7 */
994 wlat(addr
, cpu
.gr
[regno
]);
998 while ((regno
& 0x3) != 0);
1003 char *addr
= (char *)cpu
.gr
[0];
1006 /* bonus cycle is really only needed if
1007 the next insn shifts the last reg loaded.
1012 while (regno
<= 0xF)
1014 cpu
.gr
[regno
] = rlat(addr
);
1022 char *addr
= (char *)cpu
.gr
[0];
1025 /* this should be removed! */
1026 /* bonus_cycles ++; */
1028 memops
+= 16 - regno
;
1029 while (regno
<= 0xF)
1031 wlat(addr
, cpu
.gr
[regno
]);
1038 case 0x8: /* dect */
1039 cpu
.gr
[RD
] -= C_VALUE();
1041 case 0x9: /* decf */
1042 cpu
.gr
[RD
] -= C_OFF();
1044 case 0xA: /* inct */
1045 cpu
.gr
[RD
] += C_VALUE();
1047 case 0xB: /* incf */
1048 cpu
.gr
[RD
] += C_OFF();
1052 if (tracing
&& RD
== 15)
1053 fprintf (stderr
, "Func return, r2 = %x, r3 = %x\n",
1054 cpu
.gr
[2], cpu
.gr
[3]);
1068 for (i
= 0; !(tmp
& 0x80000000) && i
< 32; i
++)
1073 case 0xF: /* brev */
1077 tmp
= ((tmp
& 0xaaaaaaaa) >> 1) | ((tmp
& 0x55555555) << 1);
1078 tmp
= ((tmp
& 0xcccccccc) >> 2) | ((tmp
& 0x33333333) << 2);
1079 tmp
= ((tmp
& 0xf0f0f0f0) >> 4) | ((tmp
& 0x0f0f0f0f) << 4);
1080 tmp
= ((tmp
& 0xff00ff00) >> 8) | ((tmp
& 0x00ff00ff) << 8);
1081 cpu
.gr
[RD
] = ((tmp
& 0xffff0000) >> 16) | ((tmp
& 0x0000ffff) << 16);
1089 case 0x0: /* xtrb3 */
1090 cpu
.gr
[1] = (cpu
.gr
[RD
]) & 0xFF;
1091 NEW_C (cpu
.gr
[RD
] != 0);
1093 case 0x1: /* xtrb2 */
1094 cpu
.gr
[1] = (cpu
.gr
[RD
]>>8) & 0xFF;
1095 NEW_C (cpu
.gr
[RD
] != 0);
1097 case 0x2: /* xtrb1 */
1098 cpu
.gr
[1] = (cpu
.gr
[RD
]>>16) & 0xFF;
1099 NEW_C (cpu
.gr
[RD
] != 0);
1101 case 0x3: /* xtrb0 */
1102 cpu
.gr
[1] = (cpu
.gr
[RD
]>>24) & 0xFF;
1103 NEW_C (cpu
.gr
[RD
] != 0);
1105 case 0x4: /* zextb */
1106 cpu
.gr
[RD
] &= 0x000000FF;
1108 case 0x5: /* sextb */
1117 case 0x6: /* zexth */
1118 cpu
.gr
[RD
] &= 0x0000FFFF;
1120 case 0x7: /* sexth */
1129 case 0x8: /* declt */
1131 NEW_C ((long)cpu
.gr
[RD
] < 0);
1133 case 0x9: /* tstnbz */
1135 word tmp
= cpu
.gr
[RD
];
1136 NEW_C ((tmp
& 0xFF000000) != 0 &&
1137 (tmp
& 0x00FF0000) != 0 && (tmp
& 0x0000FF00) != 0 &&
1138 (tmp
& 0x000000FF) != 0);
1141 case 0xA: /* decgt */
1143 NEW_C ((long)cpu
.gr
[RD
] > 0);
1145 case 0xB: /* decne */
1147 NEW_C ((long)cpu
.gr
[RD
] != 0);
1149 case 0xC: /* clrt */
1153 case 0xD: /* clrf */
1158 if (cpu
.gr
[RD
] & 0x80000000)
1159 cpu
.gr
[RD
] = ~cpu
.gr
[RD
] + 1;
1162 cpu
.gr
[RD
] = ~cpu
.gr
[RD
];
1166 case 0x02: /* movt */
1168 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1170 case 0x03: /* mult */
1171 /* consume 2 bits per cycle from rs, until rs is 0 */
1173 unsigned int t
= cpu
.gr
[RS
];
1175 for (ticks
= 0; t
!= 0 ; t
>>= 2)
1177 bonus_cycles
+= ticks
;
1179 bonus_cycles
+= 2; /* min. is 3, so add 2, plus ticks above */
1181 fprintf (stderr
, " mult %x by %x to give %x",
1182 cpu
.gr
[RD
], cpu
.gr
[RS
], cpu
.gr
[RD
] * cpu
.gr
[RS
]);
1183 cpu
.gr
[RD
] = cpu
.gr
[RD
] * cpu
.gr
[RS
];
1185 case 0x04: /* loopt */
1188 pc
+= (IMM4
<< 1) - 32;
1192 --cpu
.gr
[RS
]; /* not RD! */
1193 NEW_C (((long)cpu
.gr
[RS
]) > 0);
1195 case 0x05: /* subu */
1196 cpu
.gr
[RD
] -= cpu
.gr
[RS
];
1198 case 0x06: /* addc */
1200 unsigned long tmp
, a
, b
;
1203 cpu
.gr
[RD
] = a
+ b
+ C_VALUE ();
1204 tmp
= iu_carry (a
, b
, C_VALUE ());
1208 case 0x07: /* subc */
1210 unsigned long tmp
, a
, b
;
1213 cpu
.gr
[RD
] = a
- b
+ C_VALUE () - 1;
1214 tmp
= iu_carry (a
,~b
, C_VALUE ());
1218 case 0x08: /* illegal */
1219 case 0x09: /* illegal*/
1220 cpu
.asregs
.exception
= SIGILL
;
1222 case 0x0A: /* movf */
1224 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1226 case 0x0B: /* lsr */
1228 unsigned long dst
, src
;
1231 /* We must not rely solely upon the native shift operations, since they
1232 may not match the M*Core's behaviour on boundary conditions. */
1233 dst
= src
> 31 ? 0 : dst
>> src
;
1237 case 0x0C: /* cmphs */
1238 NEW_C ((unsigned long )cpu
.gr
[RD
] >=
1239 (unsigned long)cpu
.gr
[RS
]);
1241 case 0x0D: /* cmplt */
1242 NEW_C ((long)cpu
.gr
[RD
] < (long)cpu
.gr
[RS
]);
1244 case 0x0E: /* tst */
1245 NEW_C ((cpu
.gr
[RD
] & cpu
.gr
[RS
]) != 0);
1247 case 0x0F: /* cmpne */
1248 NEW_C (cpu
.gr
[RD
] != cpu
.gr
[RS
]);
1250 case 0x10: case 0x11: /* mfcr */
1254 if (r
<= LAST_VALID_CREG
)
1255 cpu
.gr
[RD
] = cpu
.cr
[r
];
1257 cpu
.asregs
.exception
= SIGILL
;
1261 case 0x12: /* mov */
1262 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1264 fprintf (stderr
, "MOV %x into reg %d", cpu
.gr
[RD
], RD
);
1267 case 0x13: /* bgenr */
1268 if (cpu
.gr
[RS
] & 0x20)
1271 cpu
.gr
[RD
] = 1 << (cpu
.gr
[RS
] & 0x1F);
1274 case 0x14: /* rsub */
1275 cpu
.gr
[RD
] = cpu
.gr
[RS
] - cpu
.gr
[RD
];
1278 case 0x15: /* ixw */
1279 cpu
.gr
[RD
] += cpu
.gr
[RS
]<<2;
1282 case 0x16: /* and */
1283 cpu
.gr
[RD
] &= cpu
.gr
[RS
];
1286 case 0x17: /* xor */
1287 cpu
.gr
[RD
] ^= cpu
.gr
[RS
];
1290 case 0x18: case 0x19: /* mtcr */
1294 if (r
<= LAST_VALID_CREG
)
1295 cpu
.cr
[r
] = cpu
.gr
[RD
];
1297 cpu
.asregs
.exception
= SIGILL
;
1299 /* we might have changed register sets... */
1301 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
1303 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
1307 case 0x1A: /* asr */
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 if (cpu
.gr
[RS
] > 30)
1311 cpu
.gr
[RD
] = ((long) cpu
.gr
[RD
]) < 0 ? -1 : 0;
1313 cpu
.gr
[RD
] = (long) cpu
.gr
[RD
] >> cpu
.gr
[RS
];
1316 case 0x1B: /* lsl */
1317 /* We must not rely solely upon the native shift operations, since they
1318 may not match the M*Core's behaviour on boundary conditions. */
1319 cpu
.gr
[RD
] = cpu
.gr
[RS
] > 31 ? 0 : cpu
.gr
[RD
] << cpu
.gr
[RS
];
1322 case 0x1C: /* addu */
1323 cpu
.gr
[RD
] += cpu
.gr
[RS
];
1326 case 0x1D: /* ixh */
1327 cpu
.gr
[RD
] += cpu
.gr
[RS
] << 1;
1331 cpu
.gr
[RD
] |= cpu
.gr
[RS
];
1334 case 0x1F: /* andn */
1335 cpu
.gr
[RD
] &= ~cpu
.gr
[RS
];
1337 case 0x20: case 0x21: /* addi */
1339 cpu
.gr
[RD
] + (IMM5
+ 1);
1341 case 0x22: case 0x23: /* cmplti */
1343 int tmp
= (IMM5
+ 1);
1344 if (cpu
.gr
[RD
] < tmp
)
1354 case 0x24: case 0x25: /* subi */
1356 cpu
.gr
[RD
] - (IMM5
+ 1);
1358 case 0x26: case 0x27: /* illegal */
1359 cpu
.asregs
.exception
= SIGILL
;
1361 case 0x28: case 0x29: /* rsubi */
1365 case 0x2A: case 0x2B: /* cmpnei */
1366 if (cpu
.gr
[RD
] != IMM5
)
1376 case 0x2C: case 0x2D: /* bmaski, divu */
1378 unsigned imm
= IMM5
;
1384 unsigned int rx
, r1
;
1390 /* unsigned divide */
1391 cpu
.gr
[RD
] = (word
) ((unsigned int) cpu
.gr
[RD
] / (unsigned int)cpu
.gr
[1] );
1393 /* compute bonus_cycles for divu */
1394 for (r1nlz
= 0; ((r1
& 0x80000000) == 0) && (r1nlz
< 32); r1nlz
++)
1397 for (rxnlz
= 0; ((rx
& 0x80000000) == 0) && (rxnlz
< 32); rxnlz
++)
1403 exe
+= 5 + r1nlz
- rxnlz
;
1405 if (exe
>= (2 * memcycles
- 1))
1407 bonus_cycles
+= exe
- (2 * memcycles
) + 1;
1410 else if (imm
== 0 || imm
>= 8)
1416 cpu
.gr
[RD
] = (1 << imm
) - 1;
1421 cpu
.asregs
.exception
= SIGILL
;
1425 case 0x2E: case 0x2F: /* andi */
1426 cpu
.gr
[RD
] = cpu
.gr
[RD
] & IMM5
;
1428 case 0x30: case 0x31: /* bclri */
1429 cpu
.gr
[RD
] = cpu
.gr
[RD
] & ~(1<<IMM5
);
1431 case 0x32: case 0x33: /* bgeni, divs */
1433 unsigned imm
= IMM5
;
1440 /* compute bonus_cycles for divu */
1445 if (((rx
< 0) && (r1
> 0)) || ((rx
>= 0) && (r1
< 0)))
1453 /* signed divide, general registers are of type int, so / op is OK */
1454 cpu
.gr
[RD
] = cpu
.gr
[RD
] / cpu
.gr
[1];
1456 for (r1nlz
= 0; ((r1
& 0x80000000) == 0) && (r1nlz
< 32) ; r1nlz
++ )
1459 for (rxnlz
= 0; ((rx
& 0x80000000) == 0) && (rxnlz
< 32) ; rxnlz
++ )
1465 exe
+= 6 + r1nlz
- rxnlz
+ sc
;
1467 if (exe
>= (2 * memcycles
- 1))
1469 bonus_cycles
+= exe
- (2 * memcycles
) + 1;
1475 cpu
.gr
[RD
] = (1 << IMM5
);
1480 cpu
.asregs
.exception
= SIGILL
;
1484 case 0x34: case 0x35: /* bseti */
1485 cpu
.gr
[RD
] = cpu
.gr
[RD
] | (1 << IMM5
);
1487 case 0x36: case 0x37: /* btsti */
1488 NEW_C (cpu
.gr
[RD
] >> IMM5
);
1490 case 0x38: case 0x39: /* xsr, rotli */
1492 unsigned imm
= IMM5
;
1493 unsigned long tmp
= cpu
.gr
[RD
];
1499 cpu
.gr
[RD
] = (cbit
<< 31) | (tmp
>> 1);
1502 cpu
.gr
[RD
] = (tmp
<< imm
) | (tmp
>> (32 - imm
));
1505 case 0x3A: case 0x3B: /* asrc, asri */
1507 unsigned imm
= IMM5
;
1508 long tmp
= cpu
.gr
[RD
];
1512 cpu
.gr
[RD
] = tmp
>> 1;
1515 cpu
.gr
[RD
] = tmp
>> imm
;
1518 case 0x3C: case 0x3D: /* lslc, lsli */
1520 unsigned imm
= IMM5
;
1521 unsigned long tmp
= cpu
.gr
[RD
];
1525 cpu
.gr
[RD
] = tmp
<< 1;
1528 cpu
.gr
[RD
] = tmp
<< imm
;
1531 case 0x3E: case 0x3F: /* lsrc, lsri */
1533 unsigned imm
= IMM5
;
1534 unsigned long tmp
= cpu
.gr
[RD
];
1538 cpu
.gr
[RD
] = tmp
>> 1;
1541 cpu
.gr
[RD
] = tmp
>> imm
;
1544 case 0x40: case 0x41: case 0x42: case 0x43:
1545 case 0x44: case 0x45: case 0x46: case 0x47:
1546 case 0x48: case 0x49: case 0x4A: case 0x4B:
1547 case 0x4C: case 0x4D: case 0x4E: case 0x4F:
1548 cpu
.asregs
.exception
= SIGILL
;
1553 case 0x51: case 0x52: case 0x53:
1554 case 0x54: case 0x55: case 0x56: case 0x57:
1555 case 0x58: case 0x59: case 0x5A: case 0x5B:
1556 case 0x5C: case 0x5D: case 0x5E: case 0x5F:
1557 cpu
.asregs
.exception
= SIGILL
;
1559 case 0x60: case 0x61: case 0x62: case 0x63: /* movi */
1560 case 0x64: case 0x65: case 0x66: case 0x67:
1561 cpu
.gr
[RD
] = (inst
>> 4) & 0x7F;
1563 case 0x68: case 0x69: case 0x6A: case 0x6B:
1564 case 0x6C: case 0x6D: case 0x6E: case 0x6F: /* illegal */
1565 cpu
.asregs
.exception
= SIGILL
;
1567 case 0x71: case 0x72: case 0x73:
1568 case 0x74: case 0x75: case 0x76: case 0x77:
1569 case 0x78: case 0x79: case 0x7A: case 0x7B:
1570 case 0x7C: case 0x7D: case 0x7E: /* lrw */
1571 cpu
.gr
[RX
] = rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC);
1573 fprintf (stderr
, "LRW of 0x%x from 0x%x to reg %d",
1574 rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC),
1575 (pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC, RX
);
1578 case 0x7F: /* jsri */
1581 fprintf (stderr
, "func call: r2 = %x r3 = %x r4 = %x r5 = %x r6 = %x r7 = %x\n",
1582 cpu
.gr
[2], cpu
.gr
[3], cpu
.gr
[4], cpu
.gr
[5], cpu
.gr
[6], cpu
.gr
[7]);
1583 case 0x70: /* jmpi */
1584 pc
= rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC);
1590 case 0x80: case 0x81: case 0x82: case 0x83:
1591 case 0x84: case 0x85: case 0x86: case 0x87:
1592 case 0x88: case 0x89: case 0x8A: case 0x8B:
1593 case 0x8C: case 0x8D: case 0x8E: case 0x8F: /* ld */
1594 cpu
.gr
[RX
] = rlat (cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C));
1596 fprintf (stderr
, "load reg %d from 0x%x with 0x%x",
1598 cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C), cpu
.gr
[RX
]);
1601 case 0x90: case 0x91: case 0x92: case 0x93:
1602 case 0x94: case 0x95: case 0x96: case 0x97:
1603 case 0x98: case 0x99: case 0x9A: case 0x9B:
1604 case 0x9C: case 0x9D: case 0x9E: case 0x9F: /* st */
1605 wlat (cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C), cpu
.gr
[RX
]);
1607 fprintf (stderr
, "store reg %d (containing 0x%x) to 0x%x",
1609 cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C));
1612 case 0xA0: case 0xA1: case 0xA2: case 0xA3:
1613 case 0xA4: case 0xA5: case 0xA6: case 0xA7:
1614 case 0xA8: case 0xA9: case 0xAA: case 0xAB:
1615 case 0xAC: case 0xAD: case 0xAE: case 0xAF: /* ld.b */
1616 cpu
.gr
[RX
] = rbat (cpu
.gr
[RD
] + RS
);
1619 case 0xB0: case 0xB1: case 0xB2: case 0xB3:
1620 case 0xB4: case 0xB5: case 0xB6: case 0xB7:
1621 case 0xB8: case 0xB9: case 0xBA: case 0xBB:
1622 case 0xBC: case 0xBD: case 0xBE: case 0xBF: /* st.b */
1623 wbat (cpu
.gr
[RD
] + RS
, cpu
.gr
[RX
]);
1626 case 0xC0: case 0xC1: case 0xC2: case 0xC3:
1627 case 0xC4: case 0xC5: case 0xC6: case 0xC7:
1628 case 0xC8: case 0xC9: case 0xCA: case 0xCB:
1629 case 0xCC: case 0xCD: case 0xCE: case 0xCF: /* ld.h */
1630 cpu
.gr
[RX
] = rhat (cpu
.gr
[RD
] + ((inst
>> 3) & 0x001E));
1633 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
1634 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
1635 case 0xD8: case 0xD9: case 0xDA: case 0xDB:
1636 case 0xDC: case 0xDD: case 0xDE: case 0xDF: /* st.h */
1637 what (cpu
.gr
[RD
] + ((inst
>> 3) & 0x001E), cpu
.gr
[RX
]);
1640 case 0xE8: case 0xE9: case 0xEA: case 0xEB:
1641 case 0xEC: case 0xED: case 0xEE: case 0xEF: /* bf */
1645 disp
= inst
& 0x03FF;
1653 case 0xE0: case 0xE1: case 0xE2: case 0xE3:
1654 case 0xE4: case 0xE5: case 0xE6: case 0xE7: /* bt */
1658 disp
= inst
& 0x03FF;
1667 case 0xF8: case 0xF9: case 0xFA: case 0xFB:
1668 case 0xFC: case 0xFD: case 0xFE: case 0xFF: /* bsr */
1670 case 0xF0: case 0xF1: case 0xF2: case 0xF3:
1671 case 0xF4: case 0xF5: case 0xF6: case 0xF7: /* br */
1674 disp
= inst
& 0x03FF;
1686 fprintf (stderr
, "\n");
1690 /* Do not let him fetch from a bad address! */
1691 if (((uword
)pc
) >= cpu
.asregs
.msize
)
1694 fprintf (stderr
, "PC loaded at 0x%x is outside of available memory! (0x%x)\n", oldpc
, pc
);
1696 cpu
.asregs
.exception
= SIGSEGV
;
1700 ibuf
= rlat (pc
& 0xFFFFFFFC);
1705 while (!cpu
.asregs
.exception
);
1707 /* Hide away the things we've cached while executing. */
1709 cpu
.asregs
.insts
+= insts
; /* instructions done ... */
1710 cpu
.asregs
.cycles
+= insts
; /* and each takes a cycle */
1711 cpu
.asregs
.cycles
+= bonus_cycles
; /* and extra cycles for branches */
1712 cpu
.asregs
.cycles
+= memops
* memcycles
; /* and memop cycle delays */
1714 signal (SIGINT
, sigsave
);
1719 sim_write (sd
, addr
, buffer
, size
)
1722 const unsigned char * buffer
;
1728 memcpy (& cpu
.mem
[addr
], buffer
, size
);
1734 sim_read (sd
, addr
, buffer
, size
)
1737 unsigned char * buffer
;
1743 memcpy (buffer
, & cpu
.mem
[addr
], size
);
1750 sim_store_register (sd
, rn
, memory
, length
)
1753 unsigned char * memory
;
1758 if (rn
< NUM_MCORE_REGS
&& rn
>= 0)
1764 /* misalignment safe */
1765 ival
= mcore_extract_unsigned_integer (memory
, 4);
1766 cpu
.asints
[rn
] = ival
;
1776 sim_fetch_register (sd
, rn
, memory
, length
)
1779 unsigned char * memory
;
1784 if (rn
< NUM_MCORE_REGS
&& rn
>= 0)
1788 long ival
= cpu
.asints
[rn
];
1790 /* misalignment-safe */
1791 mcore_store_unsigned_integer (memory
, 4, ival
);
1807 sim_resume (sd
, 0, 0);
1815 sim_stop_reason (sd
, reason
, sigrc
)
1817 enum sim_stop
* reason
;
1820 if (cpu
.asregs
.exception
== SIGQUIT
)
1822 * reason
= sim_exited
;
1823 * sigrc
= cpu
.gr
[PARM1
];
1827 * reason
= sim_stopped
;
1828 * sigrc
= cpu
.asregs
.exception
;
1837 cpu
.asregs
.exception
= SIGINT
;
1843 sim_info (sd
, verbose
)
1847 #ifdef WATCHFUNCTIONS
1850 double virttime
= cpu
.asregs
.cycles
/ 36.0e6
;
1852 callback
->printf_filtered (callback
, "\n\n# instructions executed %10d\n",
1854 callback
->printf_filtered (callback
, "# cycles %10d\n",
1856 callback
->printf_filtered (callback
, "# pipeline stalls %10d\n",
1858 callback
->printf_filtered (callback
, "# virtual time taken %10.4f\n",
1861 #ifdef WATCHFUNCTIONS
1862 callback
->printf_filtered (callback
, "\nNumber of watched functions: %d\n",
1867 for (w
= 1; w
<= ENDWL
; w
++)
1869 callback
->printf_filtered (callback
, "WL = %s %8x\n",WLstr
[w
],WL
[w
]);
1870 callback
->printf_filtered (callback
, " calls = %d, cycles = %d\n",
1871 WLcnts
[w
],WLcyc
[w
]);
1874 callback
->printf_filtered (callback
,
1875 " maxcpc = %d, mincpc = %d, avecpc = %d\n",
1876 WLmax
[w
],WLmin
[w
],WLcyc
[w
]/WLcnts
[w
]);
1880 callback
->printf_filtered (callback
,
1881 "Total cycles for watched functions: %d\n",wcyc
);
1887 unsigned char sa_machtype
[2];
1888 unsigned char sa_magic
[2];
1889 unsigned char sa_tsize
[4];
1890 unsigned char sa_dsize
[4];
1891 unsigned char sa_bsize
[4];
1892 unsigned char sa_syms
[4];
1893 unsigned char sa_entry
[4];
1894 unsigned char sa_trelo
[4];
1895 unsigned char sa_drelo
[4];
1898 #define LONG(x) (((x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
1899 #define SHORT(x) (((x)[0]<<8)|(x)[1])
1902 sim_open (kind
, cb
, abfd
, argv
)
1908 int osize
= sim_memory_size
;
1912 if (kind
== SIM_OPEN_STANDALONE
)
1915 /* Discard and reacquire memory -- start with a clean slate. */
1916 sim_size (1); /* small */
1917 sim_size (osize
); /* and back again */
1919 set_initial_gprs (); /* Reset the GPR registers. */
1921 /* Fudge our descriptor for now. */
1922 return (SIM_DESC
) 1;
1926 sim_close (sd
, quitting
)
1934 sim_load (sd
, prog
, abfd
, from_tty
)
1940 /* Do the right thing for ELF executables; this turns out to be
1941 just about the right thing for any object format that:
1942 - we crack using BFD routines
1943 - follows the traditional UNIX text/data/bss layout
1944 - calls the bss section ".bss". */
1946 extern bfd
* sim_load_file (); /* ??? Don't know where this should live. */
1952 handle
= bfd_openr (prog
, 0); /* could be "mcore" */
1956 printf("``%s'' could not be opened.\n", prog
);
1960 /* Makes sure that we have an object file, also cleans gets the
1961 section headers in place. */
1962 if (!bfd_check_format (handle
, bfd_object
))
1964 /* wasn't an object file */
1966 printf ("``%s'' is not appropriate object file.\n", prog
);
1970 /* Look for that bss section. */
1971 s_bss
= bfd_get_section_by_name (handle
, ".bss");
1975 printf("``%s'' has no bss section.\n", prog
);
1979 /* Appropriately paranoid would check that we have
1980 a traditional text/data/bss ordering within memory. */
1982 /* figure the end of the bss section */
1984 printf ("bss section at 0x%08x for 0x%08x bytes\n",
1985 (unsigned long) bfd_get_section_vma (handle
, s_bss
),
1986 (unsigned long) bfd_section_size (handle
, s_bss
));
1988 heap_ptr
= ((unsigned long) bfd_get_section_vma (handle
, s_bss
)
1989 + (unsigned long) bfd_section_size (handle
, s_bss
));
1991 /* Clean up after ourselves. */
1994 /* XXX: do we need to free the s_bss and handle structures? */
1997 /* from sh -- dac */
1998 prog_bfd
= sim_load_file (sd
, myname
, callback
, prog
, abfd
,
1999 sim_kind
== SIM_OPEN_DEBUG
,
2001 if (prog_bfd
== NULL
)
2004 target_big_endian
= bfd_big_endian (prog_bfd
);
2007 bfd_close (prog_bfd
);
2013 sim_create_inferior (sd
, prog_bfd
, argv
, env
)
2015 struct bfd
* prog_bfd
;
2024 unsigned long strings
;
2025 unsigned long pointers
;
2026 unsigned long hi_stack
;
2029 /* Set the initial register set. */
2032 set_initial_gprs ();
2035 hi_stack
= cpu
.asregs
.msize
- 4;
2036 cpu
.asregs
.pc
= bfd_get_start_address (prog_bfd
);
2038 /* Calculate the argument and environment strings. */
2044 l
= strlen (*avp
) + 1; /* include the null */
2045 s_length
+= (l
+ 3) & ~3; /* make it a 4 byte boundary */
2053 l
= strlen (*avp
) + 1; /* include the null */
2054 s_length
+= (l
+ 3) & ~ 3;/* make it a 4 byte boundary */
2058 /* Claim some memory for the pointers and strings. */
2059 pointers
= hi_stack
- sizeof(word
) * (nenv
+1+nargs
+1);
2060 pointers
&= ~3; /* must be 4-byte aligned */
2061 cpu
.gr
[0] = pointers
;
2063 strings
= cpu
.gr
[0] - s_length
;
2064 strings
&= ~3; /* want to make it 4-byte aligned */
2065 cpu
.gr
[0] = strings
;
2066 /* dac fix, the stack address must be 8-byte aligned! */
2067 cpu
.gr
[0] = cpu
.gr
[0] - cpu
.gr
[0] % 8;
2069 /* Loop through the arguments and fill them in. */
2070 cpu
.gr
[PARM1
] = nargs
;
2073 /* No strings to fill in. */
2078 cpu
.gr
[PARM2
] = pointers
;
2082 /* Save where we're putting it. */
2083 wlat (pointers
, strings
);
2085 /* Copy the string. */
2086 l
= strlen (* avp
) + 1;
2087 strcpy ((char *)(cpu
.mem
+ strings
), *avp
);
2089 /* Bump the pointers. */
2095 /* A null to finish the list. */
2100 /* Now do the environment pointers. */
2103 /* No strings to fill in. */
2108 cpu
.gr
[PARM3
] = pointers
;
2113 /* Save where we're putting it. */
2114 wlat (pointers
, strings
);
2116 /* Copy the string. */
2117 l
= strlen (* avp
) + 1;
2118 strcpy ((char *)(cpu
.mem
+ strings
), *avp
);
2120 /* Bump the pointers. */
2126 /* A null to finish the list. */
2142 sim_do_command (sd
, cmd
)
2146 /* Nothing there yet; it's all an error. */
2150 char ** simargv
= buildargv (cmd
);
2152 if (strcmp (simargv
[0], "watch") == 0)
2154 if ((simargv
[1] == NULL
) || (simargv
[2] == NULL
))
2156 fprintf (stderr
, "Error: missing argument to watch cmd.\n");
2162 WL
[ENDWL
] = strtol (simargv
[2], NULL
, 0);
2163 WLstr
[ENDWL
] = strdup (simargv
[1]);
2164 fprintf (stderr
, "Added %s (%x) to watchlist, #%d\n",WLstr
[ENDWL
],
2168 else if (strcmp (simargv
[0], "dumpmem") == 0)
2173 if (simargv
[1] == NULL
)
2174 fprintf (stderr
, "Error: missing argument to dumpmem cmd.\n");
2176 fprintf (stderr
, "Writing dumpfile %s...",simargv
[1]);
2178 dumpfile
= fopen (simargv
[1], "w");
2180 fwrite (p
, cpu
.asregs
.msize
-1, 1, dumpfile
);
2183 fprintf (stderr
, "done.\n");
2185 else if (strcmp (simargv
[0], "clearstats") == 0)
2187 cpu
.asregs
.cycles
= 0;
2188 cpu
.asregs
.insts
= 0;
2189 cpu
.asregs
.stalls
= 0;
2192 else if (strcmp (simargv
[0], "verbose") == 0)
2198 fprintf (stderr
,"Error: \"%s\" is not a valid M.CORE simulator command.\n",
2204 fprintf (stderr
, "M.CORE sim commands: \n");
2205 fprintf (stderr
, " watch <funcname> <addr>\n");
2206 fprintf (stderr
, " dumpmem <filename>\n");
2207 fprintf (stderr
, " clearstats\n");
2208 fprintf (stderr
, " verbose\n");
2213 sim_set_callbacks (ptr
)
2214 host_callback
* ptr
;
This page took 0.11591 seconds and 4 git commands to generate.