1 /* Simulator for Motorola's MCore processor
2 Copyright (C) 1999, 2000, 2002, 2003, 2007, 2008
3 Free Software Foundation, Inc.
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/>. */
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];
478 cpu
.asregs
.exception
= SIGINT
;
481 /* Functions so that trapped open/close don't interfere with the
482 parent's functions. We say that we can't close the descriptors
483 that we didn't open. exit() and cleanup() get in trouble here,
484 to some extent. That's the price of emulation. */
486 unsigned char opened
[100];
492 if (fd
< 0 || fd
> NUM_ELEM (opened
))
502 if (fd
< 0 || fd
> NUM_ELEM (opened
))
512 if (fd
< 0 || fd
> NUM_ELEM (opened
))
523 switch ((unsigned long) (cpu
.gr
[TRAPCODE
]))
526 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
527 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
528 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
529 cpu
.gr
[RET1
] = callback
->read (callback
, a
[0], (char *) a
[1], a
[2]);
533 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
534 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
535 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
536 cpu
.gr
[RET1
] = (int)callback
->write (callback
, a
[0], (char *) a
[1], a
[2]);
540 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
541 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
542 /* a[2] = (unsigned long) (cpu.gr[PARM3]); */
543 cpu
.gr
[RET1
] = callback
->open (callback
, (char *) a
[0], a
[1]);
544 log_open (cpu
.gr
[RET1
]);
548 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
549 /* Watch out for debugger's files. */
550 if (is_opened (a
[0]))
553 cpu
.gr
[RET1
] = callback
->close (callback
, a
[0]);
557 /* Don't let him close it. */
563 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
564 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
565 cpu
.gr
[RET1
] = link ((char *) a
[0], (char *) a
[1]);
569 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
570 cpu
.gr
[RET1
] = callback
->unlink (callback
, (char *) a
[0]);
574 /* handle time(0) vs time(&var) */
575 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
577 a
[0] += (unsigned long) cpu
.mem
;
578 cpu
.gr
[RET1
] = callback
->time (callback
, (time_t *) a
[0]);
582 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
583 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
584 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
585 cpu
.gr
[RET1
] = callback
->lseek (callback
, a
[0], a
[1], a
[2]);
589 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
590 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
591 cpu
.gr
[RET1
] = access ((char *) a
[0], a
[1]);
595 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
597 cpu
.gr
[RET1
] = times ((char *)a
[0]);
600 /* Give him simulated cycles for utime
601 and an instruction count for stime. */
610 t
.tms_utime
= cpu
.asregs
.cycles
;
611 t
.tms_stime
= cpu
.asregs
.insts
;
612 t
.tms_cutime
= t
.tms_utime
;
613 t
.tms_cstime
= t
.tms_stime
;
615 memcpy ((struct tms
*)(a
[0]), &t
, sizeof (t
));
617 cpu
.gr
[RET1
] = cpu
.asregs
.cycles
;
623 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
624 cpu
.gr
[RET1
] = int_sbrk (a
[0]);
629 fprintf (stderr
, "WARNING: sys call %d unimplemented\n",
639 /* These values should match those in libgloss/mcore/syscalls.s. */
646 case 10: /* _unlink */
647 case 19: /* _lseek */
648 case 43: /* _times */
649 cpu
.gr
[TRAPCODE
] = what
;
655 fprintf (stderr
, "Unhandled stub opcode: %d\n", what
);
667 cpu
.asregs
.exception
= SIGQUIT
;
676 a
[0] = (unsigned long)(cpu
.mem
+ cpu
.gr
[PARM1
]);
678 for (s
= (unsigned char *)a
[0], i
= 1 ; *s
&& i
< 6 ; s
++)
683 a
[i
] = (unsigned long)(cpu
.mem
+ cpu
.gr
[PARM1
+i
]);
685 a
[i
] = cpu
.gr
[i
+PARM1
];
690 cpu
.gr
[RET1
] = printf ((char *)a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
696 fprintf (stderr
, "WARNING: scanf unimplemented\n");
700 cpu
.gr
[RET1
] = cpu
.asregs
.insts
;
704 process_stub (cpu
.gr
[1]);
709 fprintf (stderr
, "Unhandled util code: %x\n", what
);
714 /* For figuring out whether we carried; addc/subc use this. */
723 x
= (a
& 0xffff) + (b
& 0xffff) + cin
;
724 x
= (x
>> 16) + (a
>> 16) + (b
>> 16);
730 #define WATCHFUNCTIONS 1
731 #ifdef WATCHFUNCTIONS
748 #define RD (inst & 0xF)
749 #define RS ((inst >> 4) & 0xF)
750 #define RX ((inst >> 8) & 0xF)
751 #define IMM5 ((inst >> 4) & 0x1F)
752 #define IMM4 ((inst) & 0xF)
754 static int tracing
= 0;
757 sim_resume (sd
, step
, siggnal
)
773 sigsave
= signal (SIGINT
, interrupt
);
774 cpu
.asregs
.exception
= step
? SIGTRAP
: 0;
777 /* Fetch the initial instructions that we'll decode. */
778 ibuf
= rlat (pc
& 0xFFFFFFFC);
785 /* make our register set point to the right place */
787 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
789 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
791 /* make a hash to speed exec loop, hope it's nonzero */
794 for (w
= 1; w
<= ENDWL
; w
++)
795 WLhash
= WLhash
& WL
[w
];
805 if (! target_big_endian
)
808 inst
= ibuf
& 0xFFFF;
813 if (! target_big_endian
)
814 inst
= ibuf
& 0xFFFF;
819 #ifdef WATCHFUNCTIONS
820 /* now scan list of watch addresses, if match, count it and
821 note return address and count cycles until pc=return address */
823 if ((WLincyc
== 1) && (pc
== WLendpc
))
825 cycs
= (cpu
.asregs
.cycles
+ (insts
+ bonus_cycles
+
826 (memops
* memcycles
)) - WLbcyc
);
828 if (WLcnts
[WLW
] == 1)
835 if (cycs
> WLmax
[WLW
])
840 if (cycs
< WLmin
[WLW
])
850 /* Optimize with a hash to speed loop. */
853 if ((WLhash
== 0) || ((WLhash
& pc
) != 0))
855 for (w
=1; w
<= ENDWL
; w
++)
860 WLbcyc
= cpu
.asregs
.cycles
+ insts
861 + bonus_cycles
+ (memops
* memcycles
);
862 WLendpc
= cpu
.gr
[15];
873 fprintf (stderr
, "%.4x: inst = %.4x ", pc
, inst
);
888 cpu
.asregs
.exception
= SIGTRAP
;
901 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
903 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
912 cpu
.asregs
.active_gregs
= &cpu
.asregs
.alt_gregs
[0];
914 cpu
.asregs
.active_gregs
= &cpu
.asregs
.gregs
[0];
919 fprintf (stderr
, "WARNING: stop unimplemented\n");
924 fprintf (stderr
, "WARNING: wait unimplemented\n");
929 fprintf (stderr
, "WARNING: doze unimplemented\n");
933 cpu
.asregs
.exception
= SIGILL
; /* illegal */
936 case 0x8: /* trap 0 */
937 case 0xA: /* trap 2 */
938 case 0xB: /* trap 3 */
939 cpu
.asregs
.exception
= SIGTRAP
;
942 case 0xC: /* trap 4 */
943 case 0xD: /* trap 5 */
944 case 0xE: /* trap 6 */
945 cpu
.asregs
.exception
= SIGILL
; /* illegal */
948 case 0xF: /* trap 7 */
949 cpu
.asregs
.exception
= SIGTRAP
; /* integer div-by-0 */
952 case 0x9: /* trap 1 */
959 cpu
.asregs
.exception
= SIGILL
; /* illegal */
963 cpu
.gr
[RD
] = C_VALUE();
966 cpu
.gr
[RD
] = C_OFF();
970 char *addr
= (char *)cpu
.gr
[RD
];
971 int regno
= 4; /* always r4-r7 */
977 cpu
.gr
[regno
] = rlat(addr
);
981 while ((regno
&0x3) != 0);
986 char *addr
= (char *)cpu
.gr
[RD
];
987 int regno
= 4; /* always r4-r7 */
993 wlat(addr
, cpu
.gr
[regno
]);
997 while ((regno
& 0x3) != 0);
1002 char *addr
= (char *)cpu
.gr
[0];
1005 /* bonus cycle is really only needed if
1006 the next insn shifts the last reg loaded.
1011 while (regno
<= 0xF)
1013 cpu
.gr
[regno
] = rlat(addr
);
1021 char *addr
= (char *)cpu
.gr
[0];
1024 /* this should be removed! */
1025 /* bonus_cycles ++; */
1027 memops
+= 16 - regno
;
1028 while (regno
<= 0xF)
1030 wlat(addr
, cpu
.gr
[regno
]);
1037 case 0x8: /* dect */
1038 cpu
.gr
[RD
] -= C_VALUE();
1040 case 0x9: /* decf */
1041 cpu
.gr
[RD
] -= C_OFF();
1043 case 0xA: /* inct */
1044 cpu
.gr
[RD
] += C_VALUE();
1046 case 0xB: /* incf */
1047 cpu
.gr
[RD
] += C_OFF();
1051 if (tracing
&& RD
== 15)
1052 fprintf (stderr
, "Func return, r2 = %x, r3 = %x\n",
1053 cpu
.gr
[2], cpu
.gr
[3]);
1067 for (i
= 0; !(tmp
& 0x80000000) && i
< 32; i
++)
1072 case 0xF: /* brev */
1076 tmp
= ((tmp
& 0xaaaaaaaa) >> 1) | ((tmp
& 0x55555555) << 1);
1077 tmp
= ((tmp
& 0xcccccccc) >> 2) | ((tmp
& 0x33333333) << 2);
1078 tmp
= ((tmp
& 0xf0f0f0f0) >> 4) | ((tmp
& 0x0f0f0f0f) << 4);
1079 tmp
= ((tmp
& 0xff00ff00) >> 8) | ((tmp
& 0x00ff00ff) << 8);
1080 cpu
.gr
[RD
] = ((tmp
& 0xffff0000) >> 16) | ((tmp
& 0x0000ffff) << 16);
1088 case 0x0: /* xtrb3 */
1089 cpu
.gr
[1] = (cpu
.gr
[RD
]) & 0xFF;
1090 NEW_C (cpu
.gr
[RD
] != 0);
1092 case 0x1: /* xtrb2 */
1093 cpu
.gr
[1] = (cpu
.gr
[RD
]>>8) & 0xFF;
1094 NEW_C (cpu
.gr
[RD
] != 0);
1096 case 0x2: /* xtrb1 */
1097 cpu
.gr
[1] = (cpu
.gr
[RD
]>>16) & 0xFF;
1098 NEW_C (cpu
.gr
[RD
] != 0);
1100 case 0x3: /* xtrb0 */
1101 cpu
.gr
[1] = (cpu
.gr
[RD
]>>24) & 0xFF;
1102 NEW_C (cpu
.gr
[RD
] != 0);
1104 case 0x4: /* zextb */
1105 cpu
.gr
[RD
] &= 0x000000FF;
1107 case 0x5: /* sextb */
1116 case 0x6: /* zexth */
1117 cpu
.gr
[RD
] &= 0x0000FFFF;
1119 case 0x7: /* sexth */
1128 case 0x8: /* declt */
1130 NEW_C ((long)cpu
.gr
[RD
] < 0);
1132 case 0x9: /* tstnbz */
1134 word tmp
= cpu
.gr
[RD
];
1135 NEW_C ((tmp
& 0xFF000000) != 0 &&
1136 (tmp
& 0x00FF0000) != 0 && (tmp
& 0x0000FF00) != 0 &&
1137 (tmp
& 0x000000FF) != 0);
1140 case 0xA: /* decgt */
1142 NEW_C ((long)cpu
.gr
[RD
] > 0);
1144 case 0xB: /* decne */
1146 NEW_C ((long)cpu
.gr
[RD
] != 0);
1148 case 0xC: /* clrt */
1152 case 0xD: /* clrf */
1157 if (cpu
.gr
[RD
] & 0x80000000)
1158 cpu
.gr
[RD
] = ~cpu
.gr
[RD
] + 1;
1161 cpu
.gr
[RD
] = ~cpu
.gr
[RD
];
1165 case 0x02: /* movt */
1167 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1169 case 0x03: /* mult */
1170 /* consume 2 bits per cycle from rs, until rs is 0 */
1172 unsigned int t
= cpu
.gr
[RS
];
1174 for (ticks
= 0; t
!= 0 ; t
>>= 2)
1176 bonus_cycles
+= ticks
;
1178 bonus_cycles
+= 2; /* min. is 3, so add 2, plus ticks above */
1180 fprintf (stderr
, " mult %x by %x to give %x",
1181 cpu
.gr
[RD
], cpu
.gr
[RS
], cpu
.gr
[RD
] * cpu
.gr
[RS
]);
1182 cpu
.gr
[RD
] = cpu
.gr
[RD
] * cpu
.gr
[RS
];
1184 case 0x04: /* loopt */
1187 pc
+= (IMM4
<< 1) - 32;
1191 --cpu
.gr
[RS
]; /* not RD! */
1192 NEW_C (((long)cpu
.gr
[RS
]) > 0);
1194 case 0x05: /* subu */
1195 cpu
.gr
[RD
] -= cpu
.gr
[RS
];
1197 case 0x06: /* addc */
1199 unsigned long tmp
, a
, b
;
1202 cpu
.gr
[RD
] = a
+ b
+ C_VALUE ();
1203 tmp
= iu_carry (a
, b
, C_VALUE ());
1207 case 0x07: /* subc */
1209 unsigned long tmp
, a
, b
;
1212 cpu
.gr
[RD
] = a
- b
+ C_VALUE () - 1;
1213 tmp
= iu_carry (a
,~b
, C_VALUE ());
1217 case 0x08: /* illegal */
1218 case 0x09: /* illegal*/
1219 cpu
.asregs
.exception
= SIGILL
;
1221 case 0x0A: /* movf */
1223 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1225 case 0x0B: /* lsr */
1227 unsigned long dst
, src
;
1230 /* We must not rely solely upon the native shift operations, since they
1231 may not match the M*Core's behaviour on boundary conditions. */
1232 dst
= src
> 31 ? 0 : dst
>> src
;
1236 case 0x0C: /* cmphs */
1237 NEW_C ((unsigned long )cpu
.gr
[RD
] >=
1238 (unsigned long)cpu
.gr
[RS
]);
1240 case 0x0D: /* cmplt */
1241 NEW_C ((long)cpu
.gr
[RD
] < (long)cpu
.gr
[RS
]);
1243 case 0x0E: /* tst */
1244 NEW_C ((cpu
.gr
[RD
] & cpu
.gr
[RS
]) != 0);
1246 case 0x0F: /* cmpne */
1247 NEW_C (cpu
.gr
[RD
] != cpu
.gr
[RS
]);
1249 case 0x10: case 0x11: /* mfcr */
1253 if (r
<= LAST_VALID_CREG
)
1254 cpu
.gr
[RD
] = cpu
.cr
[r
];
1256 cpu
.asregs
.exception
= SIGILL
;
1260 case 0x12: /* mov */
1261 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1263 fprintf (stderr
, "MOV %x into reg %d", cpu
.gr
[RD
], RD
);
1266 case 0x13: /* bgenr */
1267 if (cpu
.gr
[RS
] & 0x20)
1270 cpu
.gr
[RD
] = 1 << (cpu
.gr
[RS
] & 0x1F);
1273 case 0x14: /* rsub */
1274 cpu
.gr
[RD
] = cpu
.gr
[RS
] - cpu
.gr
[RD
];
1277 case 0x15: /* ixw */
1278 cpu
.gr
[RD
] += cpu
.gr
[RS
]<<2;
1281 case 0x16: /* and */
1282 cpu
.gr
[RD
] &= cpu
.gr
[RS
];
1285 case 0x17: /* xor */
1286 cpu
.gr
[RD
] ^= cpu
.gr
[RS
];
1289 case 0x18: case 0x19: /* mtcr */
1293 if (r
<= LAST_VALID_CREG
)
1294 cpu
.cr
[r
] = cpu
.gr
[RD
];
1296 cpu
.asregs
.exception
= SIGILL
;
1298 /* we might have changed register sets... */
1300 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
1302 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
1306 case 0x1A: /* asr */
1307 /* We must not rely solely upon the native shift operations, since they
1308 may not match the M*Core's behaviour on boundary conditions. */
1309 if (cpu
.gr
[RS
] > 30)
1310 cpu
.gr
[RD
] = ((long) cpu
.gr
[RD
]) < 0 ? -1 : 0;
1312 cpu
.gr
[RD
] = (long) cpu
.gr
[RD
] >> cpu
.gr
[RS
];
1315 case 0x1B: /* lsl */
1316 /* We must not rely solely upon the native shift operations, since they
1317 may not match the M*Core's behaviour on boundary conditions. */
1318 cpu
.gr
[RD
] = cpu
.gr
[RS
] > 31 ? 0 : cpu
.gr
[RD
] << cpu
.gr
[RS
];
1321 case 0x1C: /* addu */
1322 cpu
.gr
[RD
] += cpu
.gr
[RS
];
1325 case 0x1D: /* ixh */
1326 cpu
.gr
[RD
] += cpu
.gr
[RS
] << 1;
1330 cpu
.gr
[RD
] |= cpu
.gr
[RS
];
1333 case 0x1F: /* andn */
1334 cpu
.gr
[RD
] &= ~cpu
.gr
[RS
];
1336 case 0x20: case 0x21: /* addi */
1338 cpu
.gr
[RD
] + (IMM5
+ 1);
1340 case 0x22: case 0x23: /* cmplti */
1342 int tmp
= (IMM5
+ 1);
1343 if (cpu
.gr
[RD
] < tmp
)
1353 case 0x24: case 0x25: /* subi */
1355 cpu
.gr
[RD
] - (IMM5
+ 1);
1357 case 0x26: case 0x27: /* illegal */
1358 cpu
.asregs
.exception
= SIGILL
;
1360 case 0x28: case 0x29: /* rsubi */
1364 case 0x2A: case 0x2B: /* cmpnei */
1365 if (cpu
.gr
[RD
] != IMM5
)
1375 case 0x2C: case 0x2D: /* bmaski, divu */
1377 unsigned imm
= IMM5
;
1383 unsigned int rx
, r1
;
1389 /* unsigned divide */
1390 cpu
.gr
[RD
] = (word
) ((unsigned int) cpu
.gr
[RD
] / (unsigned int)cpu
.gr
[1] );
1392 /* compute bonus_cycles for divu */
1393 for (r1nlz
= 0; ((r1
& 0x80000000) == 0) && (r1nlz
< 32); r1nlz
++)
1396 for (rxnlz
= 0; ((rx
& 0x80000000) == 0) && (rxnlz
< 32); rxnlz
++)
1402 exe
+= 5 + r1nlz
- rxnlz
;
1404 if (exe
>= (2 * memcycles
- 1))
1406 bonus_cycles
+= exe
- (2 * memcycles
) + 1;
1409 else if (imm
== 0 || imm
>= 8)
1415 cpu
.gr
[RD
] = (1 << imm
) - 1;
1420 cpu
.asregs
.exception
= SIGILL
;
1424 case 0x2E: case 0x2F: /* andi */
1425 cpu
.gr
[RD
] = cpu
.gr
[RD
] & IMM5
;
1427 case 0x30: case 0x31: /* bclri */
1428 cpu
.gr
[RD
] = cpu
.gr
[RD
] & ~(1<<IMM5
);
1430 case 0x32: case 0x33: /* bgeni, divs */
1432 unsigned imm
= IMM5
;
1439 /* compute bonus_cycles for divu */
1444 if (((rx
< 0) && (r1
> 0)) || ((rx
>= 0) && (r1
< 0)))
1452 /* signed divide, general registers are of type int, so / op is OK */
1453 cpu
.gr
[RD
] = cpu
.gr
[RD
] / cpu
.gr
[1];
1455 for (r1nlz
= 0; ((r1
& 0x80000000) == 0) && (r1nlz
< 32) ; r1nlz
++ )
1458 for (rxnlz
= 0; ((rx
& 0x80000000) == 0) && (rxnlz
< 32) ; rxnlz
++ )
1464 exe
+= 6 + r1nlz
- rxnlz
+ sc
;
1466 if (exe
>= (2 * memcycles
- 1))
1468 bonus_cycles
+= exe
- (2 * memcycles
) + 1;
1474 cpu
.gr
[RD
] = (1 << IMM5
);
1479 cpu
.asregs
.exception
= SIGILL
;
1483 case 0x34: case 0x35: /* bseti */
1484 cpu
.gr
[RD
] = cpu
.gr
[RD
] | (1 << IMM5
);
1486 case 0x36: case 0x37: /* btsti */
1487 NEW_C (cpu
.gr
[RD
] >> IMM5
);
1489 case 0x38: case 0x39: /* xsr, rotli */
1491 unsigned imm
= IMM5
;
1492 unsigned long tmp
= cpu
.gr
[RD
];
1498 cpu
.gr
[RD
] = (cbit
<< 31) | (tmp
>> 1);
1501 cpu
.gr
[RD
] = (tmp
<< imm
) | (tmp
>> (32 - imm
));
1504 case 0x3A: case 0x3B: /* asrc, asri */
1506 unsigned imm
= IMM5
;
1507 long tmp
= cpu
.gr
[RD
];
1511 cpu
.gr
[RD
] = tmp
>> 1;
1514 cpu
.gr
[RD
] = tmp
>> imm
;
1517 case 0x3C: case 0x3D: /* lslc, lsli */
1519 unsigned imm
= IMM5
;
1520 unsigned long tmp
= cpu
.gr
[RD
];
1524 cpu
.gr
[RD
] = tmp
<< 1;
1527 cpu
.gr
[RD
] = tmp
<< imm
;
1530 case 0x3E: case 0x3F: /* lsrc, lsri */
1532 unsigned imm
= IMM5
;
1533 unsigned long tmp
= cpu
.gr
[RD
];
1537 cpu
.gr
[RD
] = tmp
>> 1;
1540 cpu
.gr
[RD
] = tmp
>> imm
;
1543 case 0x40: case 0x41: case 0x42: case 0x43:
1544 case 0x44: case 0x45: case 0x46: case 0x47:
1545 case 0x48: case 0x49: case 0x4A: case 0x4B:
1546 case 0x4C: case 0x4D: case 0x4E: case 0x4F:
1547 cpu
.asregs
.exception
= SIGILL
;
1552 case 0x51: case 0x52: case 0x53:
1553 case 0x54: case 0x55: case 0x56: case 0x57:
1554 case 0x58: case 0x59: case 0x5A: case 0x5B:
1555 case 0x5C: case 0x5D: case 0x5E: case 0x5F:
1556 cpu
.asregs
.exception
= SIGILL
;
1558 case 0x60: case 0x61: case 0x62: case 0x63: /* movi */
1559 case 0x64: case 0x65: case 0x66: case 0x67:
1560 cpu
.gr
[RD
] = (inst
>> 4) & 0x7F;
1562 case 0x68: case 0x69: case 0x6A: case 0x6B:
1563 case 0x6C: case 0x6D: case 0x6E: case 0x6F: /* illegal */
1564 cpu
.asregs
.exception
= SIGILL
;
1566 case 0x71: case 0x72: case 0x73:
1567 case 0x74: case 0x75: case 0x76: case 0x77:
1568 case 0x78: case 0x79: case 0x7A: case 0x7B:
1569 case 0x7C: case 0x7D: case 0x7E: /* lrw */
1570 cpu
.gr
[RX
] = rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC);
1572 fprintf (stderr
, "LRW of 0x%x from 0x%x to reg %d",
1573 rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC),
1574 (pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC, RX
);
1577 case 0x7F: /* jsri */
1580 fprintf (stderr
, "func call: r2 = %x r3 = %x r4 = %x r5 = %x r6 = %x r7 = %x\n",
1581 cpu
.gr
[2], cpu
.gr
[3], cpu
.gr
[4], cpu
.gr
[5], cpu
.gr
[6], cpu
.gr
[7]);
1582 case 0x70: /* jmpi */
1583 pc
= rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC);
1589 case 0x80: case 0x81: case 0x82: case 0x83:
1590 case 0x84: case 0x85: case 0x86: case 0x87:
1591 case 0x88: case 0x89: case 0x8A: case 0x8B:
1592 case 0x8C: case 0x8D: case 0x8E: case 0x8F: /* ld */
1593 cpu
.gr
[RX
] = rlat (cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C));
1595 fprintf (stderr
, "load reg %d from 0x%x with 0x%x",
1597 cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C), cpu
.gr
[RX
]);
1600 case 0x90: case 0x91: case 0x92: case 0x93:
1601 case 0x94: case 0x95: case 0x96: case 0x97:
1602 case 0x98: case 0x99: case 0x9A: case 0x9B:
1603 case 0x9C: case 0x9D: case 0x9E: case 0x9F: /* st */
1604 wlat (cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C), cpu
.gr
[RX
]);
1606 fprintf (stderr
, "store reg %d (containing 0x%x) to 0x%x",
1608 cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C));
1611 case 0xA0: case 0xA1: case 0xA2: case 0xA3:
1612 case 0xA4: case 0xA5: case 0xA6: case 0xA7:
1613 case 0xA8: case 0xA9: case 0xAA: case 0xAB:
1614 case 0xAC: case 0xAD: case 0xAE: case 0xAF: /* ld.b */
1615 cpu
.gr
[RX
] = rbat (cpu
.gr
[RD
] + RS
);
1618 case 0xB0: case 0xB1: case 0xB2: case 0xB3:
1619 case 0xB4: case 0xB5: case 0xB6: case 0xB7:
1620 case 0xB8: case 0xB9: case 0xBA: case 0xBB:
1621 case 0xBC: case 0xBD: case 0xBE: case 0xBF: /* st.b */
1622 wbat (cpu
.gr
[RD
] + RS
, cpu
.gr
[RX
]);
1625 case 0xC0: case 0xC1: case 0xC2: case 0xC3:
1626 case 0xC4: case 0xC5: case 0xC6: case 0xC7:
1627 case 0xC8: case 0xC9: case 0xCA: case 0xCB:
1628 case 0xCC: case 0xCD: case 0xCE: case 0xCF: /* ld.h */
1629 cpu
.gr
[RX
] = rhat (cpu
.gr
[RD
] + ((inst
>> 3) & 0x001E));
1632 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
1633 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
1634 case 0xD8: case 0xD9: case 0xDA: case 0xDB:
1635 case 0xDC: case 0xDD: case 0xDE: case 0xDF: /* st.h */
1636 what (cpu
.gr
[RD
] + ((inst
>> 3) & 0x001E), cpu
.gr
[RX
]);
1639 case 0xE8: case 0xE9: case 0xEA: case 0xEB:
1640 case 0xEC: case 0xED: case 0xEE: case 0xEF: /* bf */
1644 disp
= inst
& 0x03FF;
1652 case 0xE0: case 0xE1: case 0xE2: case 0xE3:
1653 case 0xE4: case 0xE5: case 0xE6: case 0xE7: /* bt */
1657 disp
= inst
& 0x03FF;
1666 case 0xF8: case 0xF9: case 0xFA: case 0xFB:
1667 case 0xFC: case 0xFD: case 0xFE: case 0xFF: /* bsr */
1669 case 0xF0: case 0xF1: case 0xF2: case 0xF3:
1670 case 0xF4: case 0xF5: case 0xF6: case 0xF7: /* br */
1673 disp
= inst
& 0x03FF;
1685 fprintf (stderr
, "\n");
1689 /* Do not let him fetch from a bad address! */
1690 if (((uword
)pc
) >= cpu
.asregs
.msize
)
1693 fprintf (stderr
, "PC loaded at 0x%x is outside of available memory! (0x%x)\n", oldpc
, pc
);
1695 cpu
.asregs
.exception
= SIGSEGV
;
1699 ibuf
= rlat (pc
& 0xFFFFFFFC);
1704 while (!cpu
.asregs
.exception
);
1706 /* Hide away the things we've cached while executing. */
1708 cpu
.asregs
.insts
+= insts
; /* instructions done ... */
1709 cpu
.asregs
.cycles
+= insts
; /* and each takes a cycle */
1710 cpu
.asregs
.cycles
+= bonus_cycles
; /* and extra cycles for branches */
1711 cpu
.asregs
.cycles
+= memops
* memcycles
; /* and memop cycle delays */
1713 signal (SIGINT
, sigsave
);
1718 sim_write (sd
, addr
, buffer
, size
)
1721 unsigned char * buffer
;
1727 memcpy (& cpu
.mem
[addr
], buffer
, size
);
1733 sim_read (sd
, addr
, buffer
, size
)
1736 unsigned char * buffer
;
1742 memcpy (buffer
, & cpu
.mem
[addr
], size
);
1749 sim_store_register (sd
, rn
, memory
, length
)
1752 unsigned char * memory
;
1757 if (rn
< NUM_MCORE_REGS
&& rn
>= 0)
1763 /* misalignment safe */
1764 ival
= mcore_extract_unsigned_integer (memory
, 4);
1765 cpu
.asints
[rn
] = ival
;
1775 sim_fetch_register (sd
, rn
, memory
, length
)
1778 unsigned char * memory
;
1783 if (rn
< NUM_MCORE_REGS
&& rn
>= 0)
1787 long ival
= cpu
.asints
[rn
];
1789 /* misalignment-safe */
1790 mcore_store_unsigned_integer (memory
, 4, ival
);
1806 sim_resume (sd
, 0, 0);
1814 sim_stop_reason (sd
, reason
, sigrc
)
1816 enum sim_stop
* reason
;
1819 if (cpu
.asregs
.exception
== SIGQUIT
)
1821 * reason
= sim_exited
;
1822 * sigrc
= cpu
.gr
[PARM1
];
1826 * reason
= sim_stopped
;
1827 * sigrc
= cpu
.asregs
.exception
;
1836 cpu
.asregs
.exception
= SIGINT
;
1842 sim_info (sd
, verbose
)
1846 #ifdef WATCHFUNCTIONS
1849 double virttime
= cpu
.asregs
.cycles
/ 36.0e6
;
1851 callback
->printf_filtered (callback
, "\n\n# instructions executed %10d\n",
1853 callback
->printf_filtered (callback
, "# cycles %10d\n",
1855 callback
->printf_filtered (callback
, "# pipeline stalls %10d\n",
1857 callback
->printf_filtered (callback
, "# virtual time taken %10.4f\n",
1860 #ifdef WATCHFUNCTIONS
1861 callback
->printf_filtered (callback
, "\nNumber of watched functions: %d\n",
1866 for (w
= 1; w
<= ENDWL
; w
++)
1868 callback
->printf_filtered (callback
, "WL = %s %8x\n",WLstr
[w
],WL
[w
]);
1869 callback
->printf_filtered (callback
, " calls = %d, cycles = %d\n",
1870 WLcnts
[w
],WLcyc
[w
]);
1873 callback
->printf_filtered (callback
,
1874 " maxcpc = %d, mincpc = %d, avecpc = %d\n",
1875 WLmax
[w
],WLmin
[w
],WLcyc
[w
]/WLcnts
[w
]);
1879 callback
->printf_filtered (callback
,
1880 "Total cycles for watched functions: %d\n",wcyc
);
1886 unsigned char sa_machtype
[2];
1887 unsigned char sa_magic
[2];
1888 unsigned char sa_tsize
[4];
1889 unsigned char sa_dsize
[4];
1890 unsigned char sa_bsize
[4];
1891 unsigned char sa_syms
[4];
1892 unsigned char sa_entry
[4];
1893 unsigned char sa_trelo
[4];
1894 unsigned char sa_drelo
[4];
1897 #define LONG(x) (((x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
1898 #define SHORT(x) (((x)[0]<<8)|(x)[1])
1901 sim_open (kind
, cb
, abfd
, argv
)
1907 int osize
= sim_memory_size
;
1911 if (kind
== SIM_OPEN_STANDALONE
)
1914 /* Discard and reacquire memory -- start with a clean slate. */
1915 sim_size (1); /* small */
1916 sim_size (osize
); /* and back again */
1918 set_initial_gprs (); /* Reset the GPR registers. */
1920 /* Fudge our descriptor for now. */
1921 return (SIM_DESC
) 1;
1925 sim_close (sd
, quitting
)
1933 sim_load (sd
, prog
, abfd
, from_tty
)
1939 /* Do the right thing for ELF executables; this turns out to be
1940 just about the right thing for any object format that:
1941 - we crack using BFD routines
1942 - follows the traditional UNIX text/data/bss layout
1943 - calls the bss section ".bss". */
1945 extern bfd
* sim_load_file (); /* ??? Don't know where this should live. */
1951 handle
= bfd_openr (prog
, 0); /* could be "mcore" */
1955 printf("``%s'' could not be opened.\n", prog
);
1959 /* Makes sure that we have an object file, also cleans gets the
1960 section headers in place. */
1961 if (!bfd_check_format (handle
, bfd_object
))
1963 /* wasn't an object file */
1965 printf ("``%s'' is not appropriate object file.\n", prog
);
1969 /* Look for that bss section. */
1970 s_bss
= bfd_get_section_by_name (handle
, ".bss");
1974 printf("``%s'' has no bss section.\n", prog
);
1978 /* Appropriately paranoid would check that we have
1979 a traditional text/data/bss ordering within memory. */
1981 /* figure the end of the bss section */
1983 printf ("bss section at 0x%08x for 0x%08x bytes\n",
1984 (unsigned long) bfd_get_section_vma (handle
, s_bss
),
1985 (unsigned long) bfd_section_size (handle
, s_bss
));
1987 heap_ptr
= ((unsigned long) bfd_get_section_vma (handle
, s_bss
)
1988 + (unsigned long) bfd_section_size (handle
, s_bss
));
1990 /* Clean up after ourselves. */
1993 /* XXX: do we need to free the s_bss and handle structures? */
1996 /* from sh -- dac */
1997 prog_bfd
= sim_load_file (sd
, myname
, callback
, prog
, abfd
,
1998 sim_kind
== SIM_OPEN_DEBUG
,
2000 if (prog_bfd
== NULL
)
2003 target_big_endian
= bfd_big_endian (prog_bfd
);
2006 bfd_close (prog_bfd
);
2012 sim_create_inferior (sd
, prog_bfd
, argv
, env
)
2014 struct bfd
* prog_bfd
;
2023 unsigned long strings
;
2024 unsigned long pointers
;
2025 unsigned long hi_stack
;
2028 /* Set the initial register set. */
2031 set_initial_gprs ();
2034 hi_stack
= cpu
.asregs
.msize
- 4;
2035 cpu
.asregs
.pc
= bfd_get_start_address (prog_bfd
);
2037 /* Calculate the argument and environment strings. */
2043 l
= strlen (*avp
) + 1; /* include the null */
2044 s_length
+= (l
+ 3) & ~3; /* make it a 4 byte boundary */
2052 l
= strlen (*avp
) + 1; /* include the null */
2053 s_length
+= (l
+ 3) & ~ 3;/* make it a 4 byte boundary */
2057 /* Claim some memory for the pointers and strings. */
2058 pointers
= hi_stack
- sizeof(word
) * (nenv
+1+nargs
+1);
2059 pointers
&= ~3; /* must be 4-byte aligned */
2060 cpu
.gr
[0] = pointers
;
2062 strings
= cpu
.gr
[0] - s_length
;
2063 strings
&= ~3; /* want to make it 4-byte aligned */
2064 cpu
.gr
[0] = strings
;
2065 /* dac fix, the stack address must be 8-byte aligned! */
2066 cpu
.gr
[0] = cpu
.gr
[0] - cpu
.gr
[0] % 8;
2068 /* Loop through the arguments and fill them in. */
2069 cpu
.gr
[PARM1
] = nargs
;
2072 /* No strings to fill in. */
2077 cpu
.gr
[PARM2
] = pointers
;
2081 /* Save where we're putting it. */
2082 wlat (pointers
, strings
);
2084 /* Copy the string. */
2085 l
= strlen (* avp
) + 1;
2086 strcpy ((char *)(cpu
.mem
+ strings
), *avp
);
2088 /* Bump the pointers. */
2094 /* A null to finish the list. */
2099 /* Now do the environment pointers. */
2102 /* No strings to fill in. */
2107 cpu
.gr
[PARM3
] = pointers
;
2112 /* Save where we're putting it. */
2113 wlat (pointers
, strings
);
2115 /* Copy the string. */
2116 l
= strlen (* avp
) + 1;
2117 strcpy ((char *)(cpu
.mem
+ strings
), *avp
);
2119 /* Bump the pointers. */
2125 /* A null to finish the list. */
2141 sim_do_command (sd
, cmd
)
2145 /* Nothing there yet; it's all an error. */
2149 char ** simargv
= buildargv (cmd
);
2151 if (strcmp (simargv
[0], "watch") == 0)
2153 if ((simargv
[1] == NULL
) || (simargv
[2] == NULL
))
2155 fprintf (stderr
, "Error: missing argument to watch cmd.\n");
2161 WL
[ENDWL
] = strtol (simargv
[2], NULL
, 0);
2162 WLstr
[ENDWL
] = strdup (simargv
[1]);
2163 fprintf (stderr
, "Added %s (%x) to watchlist, #%d\n",WLstr
[ENDWL
],
2167 else if (strcmp (simargv
[0], "dumpmem") == 0)
2172 if (simargv
[1] == NULL
)
2173 fprintf (stderr
, "Error: missing argument to dumpmem cmd.\n");
2175 fprintf (stderr
, "Writing dumpfile %s...",simargv
[1]);
2177 dumpfile
= fopen (simargv
[1], "w");
2179 fwrite (p
, cpu
.asregs
.msize
-1, 1, dumpfile
);
2182 fprintf (stderr
, "done.\n");
2184 else if (strcmp (simargv
[0], "clearstats") == 0)
2186 cpu
.asregs
.cycles
= 0;
2187 cpu
.asregs
.insts
= 0;
2188 cpu
.asregs
.stalls
= 0;
2191 else if (strcmp (simargv
[0], "verbose") == 0)
2197 fprintf (stderr
,"Error: \"%s\" is not a valid M.CORE simulator command.\n",
2203 fprintf (stderr
, "M.CORE sim commands: \n");
2204 fprintf (stderr
, " watch <funcname> <addr>\n");
2205 fprintf (stderr
, " dumpmem <filename>\n");
2206 fprintf (stderr
, " clearstats\n");
2207 fprintf (stderr
, " verbose\n");
2212 sim_set_callbacks (ptr
)
2213 host_callback
* ptr
;
This page took 0.094077 seconds and 4 git commands to generate.