93856d4157281d2a61fc52d01898d23ded78c3d9
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/>. */
24 #include <sys/times.h>
25 #include <sys/param.h>
28 #include "gdb/callback.h"
29 #include "libiberty.h"
30 #include "gdb/remote-sim.h"
34 #include "sim-options.h"
37 #define NUM_ELEM(A) (sizeof (A) / sizeof (A)[0])
40 #define target_big_endian (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
44 mcore_extract_unsigned_integer (unsigned char *addr
, int len
)
48 unsigned char * startaddr
= (unsigned char *)addr
;
49 unsigned char * endaddr
= startaddr
+ len
;
51 if (len
> (int) sizeof (unsigned long))
52 printf ("That operation is not available on integers of more than %zu bytes.",
53 sizeof (unsigned long));
55 /* Start at the most significant end of the integer, and work towards
56 the least significant. */
59 if (! target_big_endian
)
61 for (p
= endaddr
; p
> startaddr
;)
62 retval
= (retval
<< 8) | * -- p
;
66 for (p
= startaddr
; p
< endaddr
;)
67 retval
= (retval
<< 8) | * p
++;
74 mcore_store_unsigned_integer (unsigned char *addr
, int len
, unsigned long val
)
77 unsigned char * startaddr
= (unsigned char *)addr
;
78 unsigned char * endaddr
= startaddr
+ len
;
80 if (! target_big_endian
)
82 for (p
= startaddr
; p
< endaddr
;)
90 for (p
= endaddr
; p
> startaddr
;)
99 This state is maintained in host byte order. The
100 fetch/store register functions must translate between host
101 byte order and the target processor byte order.
102 Keeping this data in target byte order simplifies the register
103 read/write functions. Keeping this data in native order improves
104 the performance of the simulator. Simulation speed is deemed more
106 /* TODO: Should be moved to sim-main.h:sim_cpu. */
108 /* The ordering of the mcore_regset structure is matched in the
109 gdb/config/mcore/tm-mcore.h file in the REGISTER_NAMES macro. */
112 word gregs
[16]; /* primary registers */
113 word alt_gregs
[16]; /* alt register file */
114 word cregs
[32]; /* control registers */
121 unsigned char * memory
;
127 struct mcore_regset asregs
;
128 word asints
[1]; /* but accessed larger... */
131 #define LAST_VALID_CREG 32 /* only 0..12 implemented */
132 #define NUM_MCORE_REGS (16 + 16 + LAST_VALID_CREG + 1)
134 static int memcycles
= 1;
136 static int issue_messages
= 0;
138 #define gr asregs.active_gregs
139 #define cr asregs.cregs
140 #define sr asregs.cregs[0]
141 #define vbr asregs.cregs[1]
142 #define esr asregs.cregs[2]
143 #define fsr asregs.cregs[3]
144 #define epc asregs.cregs[4]
145 #define fpc asregs.cregs[5]
146 #define ss0 asregs.cregs[6]
147 #define ss1 asregs.cregs[7]
148 #define ss2 asregs.cregs[8]
149 #define ss3 asregs.cregs[9]
150 #define ss4 asregs.cregs[10]
151 #define gcr asregs.cregs[11]
152 #define gsr asregs.cregs[12]
153 #define mem asregs.memory
155 /* maniuplate the carry bit */
156 #define C_ON() (cpu.sr & 1)
157 #define C_VALUE() (cpu.sr & 1)
158 #define C_OFF() ((cpu.sr & 1) == 0)
159 #define SET_C() {cpu.sr |= 1;}
160 #define CLR_C() {cpu.sr &= 0xfffffffe;}
161 #define NEW_C(v) {CLR_C(); cpu.sr |= ((v) & 1);}
163 #define SR_AF() ((cpu.sr >> 1) & 1)
165 #define TRAPCODE 1 /* r1 holds which function we want */
166 #define PARM1 2 /* first parameter */
170 #define RET1 2 /* register for return values. */
173 wbat (word x
, word v
)
175 if (((uword
)x
) >= cpu
.asregs
.msize
)
178 fprintf (stderr
, "byte write to 0x%x outside memory range\n", x
);
180 cpu
.asregs
.exception
= SIGSEGV
;
184 unsigned char *p
= cpu
.mem
+ x
;
190 wlat (word x
, word v
)
192 if (((uword
)x
) >= cpu
.asregs
.msize
)
195 fprintf (stderr
, "word write to 0x%x outside memory range\n", x
);
197 cpu
.asregs
.exception
= SIGSEGV
;
204 fprintf (stderr
, "word write to unaligned memory address: 0x%x\n", x
);
206 cpu
.asregs
.exception
= SIGBUS
;
208 else if (! target_big_endian
)
210 unsigned char * p
= cpu
.mem
+ x
;
218 unsigned char * p
= cpu
.mem
+ x
;
228 what (word x
, word v
)
230 if (((uword
)x
) >= cpu
.asregs
.msize
)
233 fprintf (stderr
, "short write to 0x%x outside memory range\n", x
);
235 cpu
.asregs
.exception
= SIGSEGV
;
242 fprintf (stderr
, "short write to unaligned memory address: 0x%x\n",
245 cpu
.asregs
.exception
= SIGBUS
;
247 else if (! target_big_endian
)
249 unsigned char * p
= cpu
.mem
+ x
;
255 unsigned char * p
= cpu
.mem
+ x
;
262 /* Read functions. */
266 if (((uword
)x
) >= cpu
.asregs
.msize
)
269 fprintf (stderr
, "byte read from 0x%x outside memory range\n", x
);
271 cpu
.asregs
.exception
= SIGSEGV
;
276 unsigned char * p
= cpu
.mem
+ x
;
284 if (((uword
) x
) >= cpu
.asregs
.msize
)
287 fprintf (stderr
, "word read from 0x%x outside memory range\n", x
);
289 cpu
.asregs
.exception
= SIGSEGV
;
297 fprintf (stderr
, "word read from unaligned address: 0x%x\n", x
);
299 cpu
.asregs
.exception
= SIGBUS
;
302 else if (! target_big_endian
)
304 unsigned char * p
= cpu
.mem
+ x
;
305 return (p
[3] << 24) | (p
[2] << 16) | (p
[1] << 8) | p
[0];
309 unsigned char * p
= cpu
.mem
+ x
;
310 return (p
[0] << 24) | (p
[1] << 16) | (p
[2] << 8) | p
[3];
318 if (((uword
)x
) >= cpu
.asregs
.msize
)
321 fprintf (stderr
, "short read from 0x%x outside memory range\n", x
);
323 cpu
.asregs
.exception
= SIGSEGV
;
331 fprintf (stderr
, "short read from unaligned address: 0x%x\n", x
);
333 cpu
.asregs
.exception
= SIGBUS
;
336 else if (! target_big_endian
)
338 unsigned char * p
= cpu
.mem
+ x
;
339 return (p
[1] << 8) | p
[0];
343 unsigned char * p
= cpu
.mem
+ x
;
344 return (p
[0] << 8) | p
[1];
350 /* Default to a 8 Mbyte (== 2^23) memory space. */
351 /* TODO: Delete all this custom memory logic and move to common sim helpers. */
352 static int sim_memory_size
= 23;
354 #define MEM_SIZE_FLOOR 64
358 sim_memory_size
= power
;
359 cpu
.asregs
.msize
= 1 << sim_memory_size
;
364 /* Watch out for the '0 count' problem. There's probably a better
365 way.. e.g., why do we use 64 here? */
366 if (cpu
.asregs
.msize
< 64) /* Ensure a boundary. */
367 cpu
.mem
= (unsigned char *) calloc (64, (64 + cpu
.asregs
.msize
) / 64);
369 cpu
.mem
= (unsigned char *) calloc (64, cpu
.asregs
.msize
/ 64);
375 "Not enough VM for simulation of %lu bytes of RAM\n",
378 cpu
.asregs
.msize
= 1;
379 cpu
.mem
= (unsigned char *) calloc (1, 1);
386 if (cpu
.asregs
.msize
!= (1 << sim_memory_size
))
387 sim_size (sim_memory_size
);
391 set_initial_gprs (SIM_CPU
*scpu
)
395 unsigned long memsize
;
399 /* Set up machine just out of reset. */
403 memsize
= cpu
.asregs
.msize
/ (1024 * 1024);
405 if (issue_messages
> 1)
406 fprintf (stderr
, "Simulated memory of %lu Mbytes (0x0 .. 0x%08lx)\n",
407 memsize
, cpu
.asregs
.msize
- 1);
409 /* Clean out the GPRs and alternate GPRs. */
410 for (i
= 0; i
< 16; i
++)
412 cpu
.asregs
.gregs
[i
] = 0;
413 cpu
.asregs
.alt_gregs
[i
] = 0;
416 /* Make our register set point to the right place. */
418 cpu
.asregs
.active_gregs
= &cpu
.asregs
.alt_gregs
[0];
420 cpu
.asregs
.active_gregs
= &cpu
.asregs
.gregs
[0];
422 /* ABI specifies initial values for these registers. */
423 cpu
.gr
[0] = cpu
.asregs
.msize
- 4;
425 /* dac fix, the stack address must be 8-byte aligned! */
426 cpu
.gr
[0] = cpu
.gr
[0] - cpu
.gr
[0] % 8;
430 cpu
.gr
[PARM4
] = cpu
.gr
[0];
433 /* Functions so that trapped open/close don't interfere with the
434 parent's functions. We say that we can't close the descriptors
435 that we didn't open. exit() and cleanup() get in trouble here,
436 to some extent. That's the price of emulation. */
438 unsigned char opened
[100];
443 if (fd
< 0 || fd
> NUM_ELEM (opened
))
452 if (fd
< 0 || fd
> NUM_ELEM (opened
))
461 if (fd
< 0 || fd
> NUM_ELEM (opened
))
468 handle_trap1 (SIM_DESC sd
)
471 host_callback
*callback
= STATE_CALLBACK (sd
);
473 switch ((unsigned long) (cpu
.gr
[TRAPCODE
]))
476 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
477 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
478 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
479 cpu
.gr
[RET1
] = callback
->read (callback
, a
[0], (char *) a
[1], a
[2]);
483 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
484 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
485 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
486 cpu
.gr
[RET1
] = (int)callback
->write (callback
, a
[0], (char *) a
[1], a
[2]);
490 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
491 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
492 /* a[2] = (unsigned long) (cpu.gr[PARM3]); */
493 cpu
.gr
[RET1
] = callback
->open (callback
, (char *) a
[0], a
[1]);
494 log_open (cpu
.gr
[RET1
]);
498 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
499 /* Watch out for debugger's files. */
500 if (is_opened (a
[0]))
503 cpu
.gr
[RET1
] = callback
->close (callback
, a
[0]);
507 /* Don't let him close it. */
513 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
514 a
[1] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM2
]);
515 cpu
.gr
[RET1
] = link ((char *) a
[0], (char *) a
[1]);
519 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
520 cpu
.gr
[RET1
] = callback
->unlink (callback
, (char *) a
[0]);
524 /* handle time(0) vs time(&var) */
525 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
527 a
[0] += (unsigned long) cpu
.mem
;
528 cpu
.gr
[RET1
] = callback
->time (callback
, (time_t *) a
[0]);
532 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
533 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
534 a
[2] = (unsigned long) (cpu
.gr
[PARM3
]);
535 cpu
.gr
[RET1
] = callback
->lseek (callback
, a
[0], a
[1], a
[2]);
539 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
540 a
[1] = (unsigned long) (cpu
.gr
[PARM2
]);
541 cpu
.gr
[RET1
] = access ((char *) a
[0], a
[1]);
545 a
[0] = (unsigned long) (cpu
.mem
+ cpu
.gr
[PARM1
]);
547 cpu
.gr
[RET1
] = times ((char *)a
[0]);
550 /* Give him simulated cycles for utime
551 and an instruction count for stime. */
560 t
.tms_utime
= cpu
.asregs
.cycles
;
561 t
.tms_stime
= cpu
.asregs
.insts
;
562 t
.tms_cutime
= t
.tms_utime
;
563 t
.tms_cstime
= t
.tms_stime
;
565 memcpy ((struct tms
*)(a
[0]), &t
, sizeof (t
));
567 cpu
.gr
[RET1
] = cpu
.asregs
.cycles
;
573 /* Historically this was sbrk(), but no one used it, and the
574 implementation didn't actually work, so it's a stub now. */
575 a
[0] = (unsigned long) (cpu
.gr
[PARM1
]);
581 fprintf (stderr
, "WARNING: sys call %d unimplemented\n",
588 process_stub (SIM_DESC sd
, int what
)
590 /* These values should match those in libgloss/mcore/syscalls.s. */
597 case 10: /* _unlink */
598 case 19: /* _lseek */
599 case 43: /* _times */
600 cpu
.gr
[TRAPCODE
] = what
;
606 fprintf (stderr
, "Unhandled stub opcode: %d\n", what
);
612 util (SIM_DESC sd
, unsigned what
)
617 cpu
.asregs
.exception
= SIGQUIT
;
626 a
[0] = (unsigned long)(cpu
.mem
+ cpu
.gr
[PARM1
]);
628 for (s
= (unsigned char *)a
[0], i
= 1 ; *s
&& i
< 6 ; s
++)
633 a
[i
] = (unsigned long)(cpu
.mem
+ cpu
.gr
[PARM1
+i
]);
635 a
[i
] = cpu
.gr
[i
+PARM1
];
640 cpu
.gr
[RET1
] = printf ((char *)a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
646 fprintf (stderr
, "WARNING: scanf unimplemented\n");
650 cpu
.gr
[RET1
] = cpu
.asregs
.insts
;
654 process_stub (sd
, cpu
.gr
[1]);
659 fprintf (stderr
, "Unhandled util code: %x\n", what
);
664 /* For figuring out whether we carried; addc/subc use this. */
666 iu_carry (unsigned long a
, unsigned long b
, int cin
)
670 x
= (a
& 0xffff) + (b
& 0xffff) + cin
;
671 x
= (x
>> 16) + (a
>> 16) + (b
>> 16);
677 #define WATCHFUNCTIONS 1
678 #ifdef WATCHFUNCTIONS
695 #define RD (inst & 0xF)
696 #define RS ((inst >> 4) & 0xF)
697 #define RX ((inst >> 8) & 0xF)
698 #define IMM5 ((inst >> 4) & 0x1F)
699 #define IMM4 ((inst) & 0xF)
701 static int tracing
= 0;
704 sim_resume (SIM_DESC sd
, int step
, int siggnal
)
706 SIM_CPU
*scpu
= STATE_CPU (sd
, 0);
718 cpu
.asregs
.exception
= step
? SIGTRAP
: 0;
721 /* Fetch the initial instructions that we'll decode. */
722 ibuf
= rlat (pc
& 0xFFFFFFFC);
729 /* make our register set point to the right place */
731 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
733 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
735 /* make a hash to speed exec loop, hope it's nonzero */
738 for (w
= 1; w
<= ENDWL
; w
++)
739 WLhash
= WLhash
& WL
[w
];
749 if (! target_big_endian
)
752 inst
= ibuf
& 0xFFFF;
757 if (! target_big_endian
)
758 inst
= ibuf
& 0xFFFF;
763 #ifdef WATCHFUNCTIONS
764 /* now scan list of watch addresses, if match, count it and
765 note return address and count cycles until pc=return address */
767 if ((WLincyc
== 1) && (pc
== WLendpc
))
769 cycs
= (cpu
.asregs
.cycles
+ (insts
+ bonus_cycles
+
770 (memops
* memcycles
)) - WLbcyc
);
772 if (WLcnts
[WLW
] == 1)
779 if (cycs
> WLmax
[WLW
])
784 if (cycs
< WLmin
[WLW
])
794 /* Optimize with a hash to speed loop. */
797 if ((WLhash
== 0) || ((WLhash
& pc
) != 0))
799 for (w
=1; w
<= ENDWL
; w
++)
804 WLbcyc
= cpu
.asregs
.cycles
+ insts
805 + bonus_cycles
+ (memops
* memcycles
);
806 WLendpc
= cpu
.gr
[15];
817 fprintf (stderr
, "%.4x: inst = %.4x ", pc
, inst
);
832 cpu
.asregs
.exception
= SIGTRAP
;
845 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
847 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
856 cpu
.asregs
.active_gregs
= &cpu
.asregs
.alt_gregs
[0];
858 cpu
.asregs
.active_gregs
= &cpu
.asregs
.gregs
[0];
863 fprintf (stderr
, "WARNING: stop unimplemented\n");
868 fprintf (stderr
, "WARNING: wait unimplemented\n");
873 fprintf (stderr
, "WARNING: doze unimplemented\n");
877 cpu
.asregs
.exception
= SIGILL
; /* illegal */
880 case 0x8: /* trap 0 */
881 case 0xA: /* trap 2 */
882 case 0xB: /* trap 3 */
883 cpu
.asregs
.exception
= SIGTRAP
;
886 case 0xC: /* trap 4 */
887 case 0xD: /* trap 5 */
888 case 0xE: /* trap 6 */
889 cpu
.asregs
.exception
= SIGILL
; /* illegal */
892 case 0xF: /* trap 7 */
893 cpu
.asregs
.exception
= SIGTRAP
; /* integer div-by-0 */
896 case 0x9: /* trap 1 */
903 cpu
.asregs
.exception
= SIGILL
; /* illegal */
907 cpu
.gr
[RD
] = C_VALUE();
910 cpu
.gr
[RD
] = C_OFF();
914 word addr
= cpu
.gr
[RD
];
915 int regno
= 4; /* always r4-r7 */
921 cpu
.gr
[regno
] = rlat(addr
);
925 while ((regno
&0x3) != 0);
930 word addr
= cpu
.gr
[RD
];
931 int regno
= 4; /* always r4-r7 */
937 wlat(addr
, cpu
.gr
[regno
]);
941 while ((regno
& 0x3) != 0);
946 word addr
= cpu
.gr
[0];
949 /* bonus cycle is really only needed if
950 the next insn shifts the last reg loaded.
957 cpu
.gr
[regno
] = rlat(addr
);
965 word addr
= cpu
.gr
[0];
968 /* this should be removed! */
969 /* bonus_cycles ++; */
971 memops
+= 16 - regno
;
974 wlat(addr
, cpu
.gr
[regno
]);
982 cpu
.gr
[RD
] -= C_VALUE();
985 cpu
.gr
[RD
] -= C_OFF();
988 cpu
.gr
[RD
] += C_VALUE();
991 cpu
.gr
[RD
] += C_OFF();
995 if (tracing
&& RD
== 15)
996 fprintf (stderr
, "Func return, r2 = %x, r3 = %x\n",
997 cpu
.gr
[2], cpu
.gr
[3]);
1011 for (i
= 0; !(tmp
& 0x80000000) && i
< 32; i
++)
1016 case 0xF: /* brev */
1020 tmp
= ((tmp
& 0xaaaaaaaa) >> 1) | ((tmp
& 0x55555555) << 1);
1021 tmp
= ((tmp
& 0xcccccccc) >> 2) | ((tmp
& 0x33333333) << 2);
1022 tmp
= ((tmp
& 0xf0f0f0f0) >> 4) | ((tmp
& 0x0f0f0f0f) << 4);
1023 tmp
= ((tmp
& 0xff00ff00) >> 8) | ((tmp
& 0x00ff00ff) << 8);
1024 cpu
.gr
[RD
] = ((tmp
& 0xffff0000) >> 16) | ((tmp
& 0x0000ffff) << 16);
1032 case 0x0: /* xtrb3 */
1033 cpu
.gr
[1] = (cpu
.gr
[RD
]) & 0xFF;
1034 NEW_C (cpu
.gr
[RD
] != 0);
1036 case 0x1: /* xtrb2 */
1037 cpu
.gr
[1] = (cpu
.gr
[RD
]>>8) & 0xFF;
1038 NEW_C (cpu
.gr
[RD
] != 0);
1040 case 0x2: /* xtrb1 */
1041 cpu
.gr
[1] = (cpu
.gr
[RD
]>>16) & 0xFF;
1042 NEW_C (cpu
.gr
[RD
] != 0);
1044 case 0x3: /* xtrb0 */
1045 cpu
.gr
[1] = (cpu
.gr
[RD
]>>24) & 0xFF;
1046 NEW_C (cpu
.gr
[RD
] != 0);
1048 case 0x4: /* zextb */
1049 cpu
.gr
[RD
] &= 0x000000FF;
1051 case 0x5: /* sextb */
1060 case 0x6: /* zexth */
1061 cpu
.gr
[RD
] &= 0x0000FFFF;
1063 case 0x7: /* sexth */
1072 case 0x8: /* declt */
1074 NEW_C ((long)cpu
.gr
[RD
] < 0);
1076 case 0x9: /* tstnbz */
1078 word tmp
= cpu
.gr
[RD
];
1079 NEW_C ((tmp
& 0xFF000000) != 0 &&
1080 (tmp
& 0x00FF0000) != 0 && (tmp
& 0x0000FF00) != 0 &&
1081 (tmp
& 0x000000FF) != 0);
1084 case 0xA: /* decgt */
1086 NEW_C ((long)cpu
.gr
[RD
] > 0);
1088 case 0xB: /* decne */
1090 NEW_C ((long)cpu
.gr
[RD
] != 0);
1092 case 0xC: /* clrt */
1096 case 0xD: /* clrf */
1101 if (cpu
.gr
[RD
] & 0x80000000)
1102 cpu
.gr
[RD
] = ~cpu
.gr
[RD
] + 1;
1105 cpu
.gr
[RD
] = ~cpu
.gr
[RD
];
1109 case 0x02: /* movt */
1111 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1113 case 0x03: /* mult */
1114 /* consume 2 bits per cycle from rs, until rs is 0 */
1116 unsigned int t
= cpu
.gr
[RS
];
1118 for (ticks
= 0; t
!= 0 ; t
>>= 2)
1120 bonus_cycles
+= ticks
;
1122 bonus_cycles
+= 2; /* min. is 3, so add 2, plus ticks above */
1124 fprintf (stderr
, " mult %x by %x to give %x",
1125 cpu
.gr
[RD
], cpu
.gr
[RS
], cpu
.gr
[RD
] * cpu
.gr
[RS
]);
1126 cpu
.gr
[RD
] = cpu
.gr
[RD
] * cpu
.gr
[RS
];
1128 case 0x04: /* loopt */
1131 pc
+= (IMM4
<< 1) - 32;
1135 --cpu
.gr
[RS
]; /* not RD! */
1136 NEW_C (((long)cpu
.gr
[RS
]) > 0);
1138 case 0x05: /* subu */
1139 cpu
.gr
[RD
] -= cpu
.gr
[RS
];
1141 case 0x06: /* addc */
1143 unsigned long tmp
, a
, b
;
1146 cpu
.gr
[RD
] = a
+ b
+ C_VALUE ();
1147 tmp
= iu_carry (a
, b
, C_VALUE ());
1151 case 0x07: /* subc */
1153 unsigned long tmp
, a
, b
;
1156 cpu
.gr
[RD
] = a
- b
+ C_VALUE () - 1;
1157 tmp
= iu_carry (a
,~b
, C_VALUE ());
1161 case 0x08: /* illegal */
1162 case 0x09: /* illegal*/
1163 cpu
.asregs
.exception
= SIGILL
;
1165 case 0x0A: /* movf */
1167 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1169 case 0x0B: /* lsr */
1171 unsigned long dst
, src
;
1174 /* We must not rely solely upon the native shift operations, since they
1175 may not match the M*Core's behaviour on boundary conditions. */
1176 dst
= src
> 31 ? 0 : dst
>> src
;
1180 case 0x0C: /* cmphs */
1181 NEW_C ((unsigned long )cpu
.gr
[RD
] >=
1182 (unsigned long)cpu
.gr
[RS
]);
1184 case 0x0D: /* cmplt */
1185 NEW_C ((long)cpu
.gr
[RD
] < (long)cpu
.gr
[RS
]);
1187 case 0x0E: /* tst */
1188 NEW_C ((cpu
.gr
[RD
] & cpu
.gr
[RS
]) != 0);
1190 case 0x0F: /* cmpne */
1191 NEW_C (cpu
.gr
[RD
] != cpu
.gr
[RS
]);
1193 case 0x10: case 0x11: /* mfcr */
1197 if (r
<= LAST_VALID_CREG
)
1198 cpu
.gr
[RD
] = cpu
.cr
[r
];
1200 cpu
.asregs
.exception
= SIGILL
;
1204 case 0x12: /* mov */
1205 cpu
.gr
[RD
] = cpu
.gr
[RS
];
1207 fprintf (stderr
, "MOV %x into reg %d", cpu
.gr
[RD
], RD
);
1210 case 0x13: /* bgenr */
1211 if (cpu
.gr
[RS
] & 0x20)
1214 cpu
.gr
[RD
] = 1 << (cpu
.gr
[RS
] & 0x1F);
1217 case 0x14: /* rsub */
1218 cpu
.gr
[RD
] = cpu
.gr
[RS
] - cpu
.gr
[RD
];
1221 case 0x15: /* ixw */
1222 cpu
.gr
[RD
] += cpu
.gr
[RS
]<<2;
1225 case 0x16: /* and */
1226 cpu
.gr
[RD
] &= cpu
.gr
[RS
];
1229 case 0x17: /* xor */
1230 cpu
.gr
[RD
] ^= cpu
.gr
[RS
];
1233 case 0x18: case 0x19: /* mtcr */
1237 if (r
<= LAST_VALID_CREG
)
1238 cpu
.cr
[r
] = cpu
.gr
[RD
];
1240 cpu
.asregs
.exception
= SIGILL
;
1242 /* we might have changed register sets... */
1244 cpu
.asregs
.active_gregs
= & cpu
.asregs
.alt_gregs
[0];
1246 cpu
.asregs
.active_gregs
= & cpu
.asregs
.gregs
[0];
1250 case 0x1A: /* asr */
1251 /* We must not rely solely upon the native shift operations, since they
1252 may not match the M*Core's behaviour on boundary conditions. */
1253 if (cpu
.gr
[RS
] > 30)
1254 cpu
.gr
[RD
] = ((long) cpu
.gr
[RD
]) < 0 ? -1 : 0;
1256 cpu
.gr
[RD
] = (long) cpu
.gr
[RD
] >> cpu
.gr
[RS
];
1259 case 0x1B: /* lsl */
1260 /* We must not rely solely upon the native shift operations, since they
1261 may not match the M*Core's behaviour on boundary conditions. */
1262 cpu
.gr
[RD
] = cpu
.gr
[RS
] > 31 ? 0 : cpu
.gr
[RD
] << cpu
.gr
[RS
];
1265 case 0x1C: /* addu */
1266 cpu
.gr
[RD
] += cpu
.gr
[RS
];
1269 case 0x1D: /* ixh */
1270 cpu
.gr
[RD
] += cpu
.gr
[RS
] << 1;
1274 cpu
.gr
[RD
] |= cpu
.gr
[RS
];
1277 case 0x1F: /* andn */
1278 cpu
.gr
[RD
] &= ~cpu
.gr
[RS
];
1280 case 0x20: case 0x21: /* addi */
1282 cpu
.gr
[RD
] + (IMM5
+ 1);
1284 case 0x22: case 0x23: /* cmplti */
1286 int tmp
= (IMM5
+ 1);
1287 if (cpu
.gr
[RD
] < tmp
)
1297 case 0x24: case 0x25: /* subi */
1299 cpu
.gr
[RD
] - (IMM5
+ 1);
1301 case 0x26: case 0x27: /* illegal */
1302 cpu
.asregs
.exception
= SIGILL
;
1304 case 0x28: case 0x29: /* rsubi */
1308 case 0x2A: case 0x2B: /* cmpnei */
1309 if (cpu
.gr
[RD
] != IMM5
)
1319 case 0x2C: case 0x2D: /* bmaski, divu */
1321 unsigned imm
= IMM5
;
1327 unsigned int rx
, r1
;
1333 /* unsigned divide */
1334 cpu
.gr
[RD
] = (word
) ((unsigned int) cpu
.gr
[RD
] / (unsigned int)cpu
.gr
[1] );
1336 /* compute bonus_cycles for divu */
1337 for (r1nlz
= 0; ((r1
& 0x80000000) == 0) && (r1nlz
< 32); r1nlz
++)
1340 for (rxnlz
= 0; ((rx
& 0x80000000) == 0) && (rxnlz
< 32); rxnlz
++)
1346 exe
+= 5 + r1nlz
- rxnlz
;
1348 if (exe
>= (2 * memcycles
- 1))
1350 bonus_cycles
+= exe
- (2 * memcycles
) + 1;
1353 else if (imm
== 0 || imm
>= 8)
1359 cpu
.gr
[RD
] = (1 << imm
) - 1;
1364 cpu
.asregs
.exception
= SIGILL
;
1368 case 0x2E: case 0x2F: /* andi */
1369 cpu
.gr
[RD
] = cpu
.gr
[RD
] & IMM5
;
1371 case 0x30: case 0x31: /* bclri */
1372 cpu
.gr
[RD
] = cpu
.gr
[RD
] & ~(1<<IMM5
);
1374 case 0x32: case 0x33: /* bgeni, divs */
1376 unsigned imm
= IMM5
;
1383 /* compute bonus_cycles for divu */
1388 if (((rx
< 0) && (r1
> 0)) || ((rx
>= 0) && (r1
< 0)))
1396 /* signed divide, general registers are of type int, so / op is OK */
1397 cpu
.gr
[RD
] = cpu
.gr
[RD
] / cpu
.gr
[1];
1399 for (r1nlz
= 0; ((r1
& 0x80000000) == 0) && (r1nlz
< 32) ; r1nlz
++ )
1402 for (rxnlz
= 0; ((rx
& 0x80000000) == 0) && (rxnlz
< 32) ; rxnlz
++ )
1408 exe
+= 6 + r1nlz
- rxnlz
+ sc
;
1410 if (exe
>= (2 * memcycles
- 1))
1412 bonus_cycles
+= exe
- (2 * memcycles
) + 1;
1418 cpu
.gr
[RD
] = (1 << IMM5
);
1423 cpu
.asregs
.exception
= SIGILL
;
1427 case 0x34: case 0x35: /* bseti */
1428 cpu
.gr
[RD
] = cpu
.gr
[RD
] | (1 << IMM5
);
1430 case 0x36: case 0x37: /* btsti */
1431 NEW_C (cpu
.gr
[RD
] >> IMM5
);
1433 case 0x38: case 0x39: /* xsr, rotli */
1435 unsigned imm
= IMM5
;
1436 unsigned long tmp
= cpu
.gr
[RD
];
1442 cpu
.gr
[RD
] = (cbit
<< 31) | (tmp
>> 1);
1445 cpu
.gr
[RD
] = (tmp
<< imm
) | (tmp
>> (32 - imm
));
1448 case 0x3A: case 0x3B: /* asrc, asri */
1450 unsigned imm
= IMM5
;
1451 long tmp
= cpu
.gr
[RD
];
1455 cpu
.gr
[RD
] = tmp
>> 1;
1458 cpu
.gr
[RD
] = tmp
>> imm
;
1461 case 0x3C: case 0x3D: /* lslc, lsli */
1463 unsigned imm
= IMM5
;
1464 unsigned long tmp
= cpu
.gr
[RD
];
1468 cpu
.gr
[RD
] = tmp
<< 1;
1471 cpu
.gr
[RD
] = tmp
<< imm
;
1474 case 0x3E: case 0x3F: /* lsrc, lsri */
1476 unsigned imm
= IMM5
;
1477 unsigned long tmp
= cpu
.gr
[RD
];
1481 cpu
.gr
[RD
] = tmp
>> 1;
1484 cpu
.gr
[RD
] = tmp
>> imm
;
1487 case 0x40: case 0x41: case 0x42: case 0x43:
1488 case 0x44: case 0x45: case 0x46: case 0x47:
1489 case 0x48: case 0x49: case 0x4A: case 0x4B:
1490 case 0x4C: case 0x4D: case 0x4E: case 0x4F:
1491 cpu
.asregs
.exception
= SIGILL
;
1494 util (sd
, inst
& 0xFF);
1496 case 0x51: case 0x52: case 0x53:
1497 case 0x54: case 0x55: case 0x56: case 0x57:
1498 case 0x58: case 0x59: case 0x5A: case 0x5B:
1499 case 0x5C: case 0x5D: case 0x5E: case 0x5F:
1500 cpu
.asregs
.exception
= SIGILL
;
1502 case 0x60: case 0x61: case 0x62: case 0x63: /* movi */
1503 case 0x64: case 0x65: case 0x66: case 0x67:
1504 cpu
.gr
[RD
] = (inst
>> 4) & 0x7F;
1506 case 0x68: case 0x69: case 0x6A: case 0x6B:
1507 case 0x6C: case 0x6D: case 0x6E: case 0x6F: /* illegal */
1508 cpu
.asregs
.exception
= SIGILL
;
1510 case 0x71: case 0x72: case 0x73:
1511 case 0x74: case 0x75: case 0x76: case 0x77:
1512 case 0x78: case 0x79: case 0x7A: case 0x7B:
1513 case 0x7C: case 0x7D: case 0x7E: /* lrw */
1514 cpu
.gr
[RX
] = rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC);
1516 fprintf (stderr
, "LRW of 0x%x from 0x%x to reg %d",
1517 rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC),
1518 (pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC, RX
);
1521 case 0x7F: /* jsri */
1524 fprintf (stderr
, "func call: r2 = %x r3 = %x r4 = %x r5 = %x r6 = %x r7 = %x\n",
1525 cpu
.gr
[2], cpu
.gr
[3], cpu
.gr
[4], cpu
.gr
[5], cpu
.gr
[6], cpu
.gr
[7]);
1526 case 0x70: /* jmpi */
1527 pc
= rlat ((pc
+ ((inst
& 0xFF) << 2)) & 0xFFFFFFFC);
1533 case 0x80: case 0x81: case 0x82: case 0x83:
1534 case 0x84: case 0x85: case 0x86: case 0x87:
1535 case 0x88: case 0x89: case 0x8A: case 0x8B:
1536 case 0x8C: case 0x8D: case 0x8E: case 0x8F: /* ld */
1537 cpu
.gr
[RX
] = rlat (cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C));
1539 fprintf (stderr
, "load reg %d from 0x%x with 0x%x",
1541 cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C), cpu
.gr
[RX
]);
1544 case 0x90: case 0x91: case 0x92: case 0x93:
1545 case 0x94: case 0x95: case 0x96: case 0x97:
1546 case 0x98: case 0x99: case 0x9A: case 0x9B:
1547 case 0x9C: case 0x9D: case 0x9E: case 0x9F: /* st */
1548 wlat (cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C), cpu
.gr
[RX
]);
1550 fprintf (stderr
, "store reg %d (containing 0x%x) to 0x%x",
1552 cpu
.gr
[RD
] + ((inst
>> 2) & 0x003C));
1555 case 0xA0: case 0xA1: case 0xA2: case 0xA3:
1556 case 0xA4: case 0xA5: case 0xA6: case 0xA7:
1557 case 0xA8: case 0xA9: case 0xAA: case 0xAB:
1558 case 0xAC: case 0xAD: case 0xAE: case 0xAF: /* ld.b */
1559 cpu
.gr
[RX
] = rbat (cpu
.gr
[RD
] + RS
);
1562 case 0xB0: case 0xB1: case 0xB2: case 0xB3:
1563 case 0xB4: case 0xB5: case 0xB6: case 0xB7:
1564 case 0xB8: case 0xB9: case 0xBA: case 0xBB:
1565 case 0xBC: case 0xBD: case 0xBE: case 0xBF: /* st.b */
1566 wbat (cpu
.gr
[RD
] + RS
, cpu
.gr
[RX
]);
1569 case 0xC0: case 0xC1: case 0xC2: case 0xC3:
1570 case 0xC4: case 0xC5: case 0xC6: case 0xC7:
1571 case 0xC8: case 0xC9: case 0xCA: case 0xCB:
1572 case 0xCC: case 0xCD: case 0xCE: case 0xCF: /* ld.h */
1573 cpu
.gr
[RX
] = rhat (cpu
.gr
[RD
] + ((inst
>> 3) & 0x001E));
1576 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
1577 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
1578 case 0xD8: case 0xD9: case 0xDA: case 0xDB:
1579 case 0xDC: case 0xDD: case 0xDE: case 0xDF: /* st.h */
1580 what (cpu
.gr
[RD
] + ((inst
>> 3) & 0x001E), cpu
.gr
[RX
]);
1583 case 0xE8: case 0xE9: case 0xEA: case 0xEB:
1584 case 0xEC: case 0xED: case 0xEE: case 0xEF: /* bf */
1588 disp
= inst
& 0x03FF;
1596 case 0xE0: case 0xE1: case 0xE2: case 0xE3:
1597 case 0xE4: case 0xE5: case 0xE6: case 0xE7: /* bt */
1601 disp
= inst
& 0x03FF;
1610 case 0xF8: case 0xF9: case 0xFA: case 0xFB:
1611 case 0xFC: case 0xFD: case 0xFE: case 0xFF: /* bsr */
1613 case 0xF0: case 0xF1: case 0xF2: case 0xF3:
1614 case 0xF4: case 0xF5: case 0xF6: case 0xF7: /* br */
1617 disp
= inst
& 0x03FF;
1629 fprintf (stderr
, "\n");
1633 /* Do not let him fetch from a bad address! */
1634 if (((uword
)pc
) >= cpu
.asregs
.msize
)
1637 fprintf (stderr
, "PC loaded at 0x%x is outside of available memory! (0x%x)\n", oldpc
, pc
);
1639 cpu
.asregs
.exception
= SIGSEGV
;
1643 ibuf
= rlat (pc
& 0xFFFFFFFC);
1648 while (!cpu
.asregs
.exception
);
1650 /* Hide away the things we've cached while executing. */
1652 cpu
.asregs
.insts
+= insts
; /* instructions done ... */
1653 cpu
.asregs
.cycles
+= insts
; /* and each takes a cycle */
1654 cpu
.asregs
.cycles
+= bonus_cycles
; /* and extra cycles for branches */
1655 cpu
.asregs
.cycles
+= memops
* memcycles
; /* and memop cycle delays */
1660 sim_write (SIM_DESC sd
, SIM_ADDR addr
, const unsigned char *buffer
, int size
)
1665 memcpy (& cpu
.mem
[addr
], buffer
, size
);
1671 sim_read (SIM_DESC sd
, SIM_ADDR addr
, unsigned char *buffer
, int size
)
1676 memcpy (buffer
, & cpu
.mem
[addr
], size
);
1683 sim_store_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
1687 if (rn
< NUM_MCORE_REGS
&& rn
>= 0)
1693 /* misalignment safe */
1694 ival
= mcore_extract_unsigned_integer (memory
, 4);
1695 cpu
.asints
[rn
] = ival
;
1705 sim_fetch_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
1709 if (rn
< NUM_MCORE_REGS
&& rn
>= 0)
1713 long ival
= cpu
.asints
[rn
];
1715 /* misalignment-safe */
1716 mcore_store_unsigned_integer (memory
, 4, ival
);
1726 sim_stop_reason (SIM_DESC sd
, enum sim_stop
*reason
, int *sigrc
)
1728 if (cpu
.asregs
.exception
== SIGQUIT
)
1730 * reason
= sim_exited
;
1731 * sigrc
= cpu
.gr
[PARM1
];
1735 * reason
= sim_stopped
;
1736 * sigrc
= cpu
.asregs
.exception
;
1741 sim_info (SIM_DESC sd
, int verbose
)
1743 #ifdef WATCHFUNCTIONS
1746 double virttime
= cpu
.asregs
.cycles
/ 36.0e6
;
1747 host_callback
*callback
= STATE_CALLBACK (sd
);
1749 callback
->printf_filtered (callback
, "\n\n# instructions executed %10d\n",
1751 callback
->printf_filtered (callback
, "# cycles %10d\n",
1753 callback
->printf_filtered (callback
, "# pipeline stalls %10d\n",
1755 callback
->printf_filtered (callback
, "# virtual time taken %10.4f\n",
1758 #ifdef WATCHFUNCTIONS
1759 callback
->printf_filtered (callback
, "\nNumber of watched functions: %d\n",
1764 for (w
= 1; w
<= ENDWL
; w
++)
1766 callback
->printf_filtered (callback
, "WL = %s %8x\n",WLstr
[w
],WL
[w
]);
1767 callback
->printf_filtered (callback
, " calls = %d, cycles = %d\n",
1768 WLcnts
[w
],WLcyc
[w
]);
1771 callback
->printf_filtered (callback
,
1772 " maxcpc = %d, mincpc = %d, avecpc = %d\n",
1773 WLmax
[w
],WLmin
[w
],WLcyc
[w
]/WLcnts
[w
]);
1777 callback
->printf_filtered (callback
,
1778 "Total cycles for watched functions: %d\n",wcyc
);
1784 unsigned char sa_machtype
[2];
1785 unsigned char sa_magic
[2];
1786 unsigned char sa_tsize
[4];
1787 unsigned char sa_dsize
[4];
1788 unsigned char sa_bsize
[4];
1789 unsigned char sa_syms
[4];
1790 unsigned char sa_entry
[4];
1791 unsigned char sa_trelo
[4];
1792 unsigned char sa_drelo
[4];
1795 #define LONG(x) (((x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
1796 #define SHORT(x) (((x)[0]<<8)|(x)[1])
1799 free_state (SIM_DESC sd
)
1801 if (STATE_MODULES (sd
) != NULL
)
1802 sim_module_uninstall (sd
);
1803 sim_cpu_free_all (sd
);
1804 sim_state_free (sd
);
1808 sim_open (SIM_OPEN_KIND kind
, host_callback
*cb
, struct bfd
*abfd
, char **argv
)
1810 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
1812 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
1814 /* The cpu data is kept in a separately allocated chunk of memory. */
1815 if (sim_cpu_alloc_all (sd
, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK
)
1821 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
1827 /* getopt will print the error message so we just have to exit if this fails.
1828 FIXME: Hmmm... in the case of gdb we need getopt to call
1830 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
1836 /* Check for/establish the a reference program image. */
1837 if (sim_analyze_program (sd
,
1838 (STATE_PROG_ARGV (sd
) != NULL
1839 ? *STATE_PROG_ARGV (sd
)
1840 : NULL
), abfd
) != SIM_RC_OK
)
1846 /* Configure/verify the target byte order and other runtime
1847 configuration options. */
1848 if (sim_config (sd
) != SIM_RC_OK
)
1850 sim_module_uninstall (sd
);
1854 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
1856 /* Uninstall the modules to avoid memory leaks,
1857 file descriptor leaks, etc. */
1858 sim_module_uninstall (sd
);
1862 osize
= sim_memory_size
;
1864 if (kind
== SIM_OPEN_STANDALONE
)
1867 /* Discard and reacquire memory -- start with a clean slate. */
1868 sim_size (1); /* small */
1869 sim_size (osize
); /* and back again */
1871 /* CPU specific initialization. */
1872 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
1874 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
1875 set_initial_gprs (cpu
); /* Reset the GPR registers. */
1882 sim_close (SIM_DESC sd
, int quitting
)
1888 sim_create_inferior (SIM_DESC sd
, struct bfd
*prog_bfd
, char **argv
, char **env
)
1890 SIM_CPU
*scpu
= STATE_CPU (sd
, 0);
1896 unsigned long strings
;
1897 unsigned long pointers
;
1898 unsigned long hi_stack
;
1901 /* Set the initial register set. */
1904 set_initial_gprs (scpu
);
1907 hi_stack
= cpu
.asregs
.msize
- 4;
1908 CIA_SET (scpu
, bfd_get_start_address (prog_bfd
));
1910 /* Calculate the argument and environment strings. */
1916 l
= strlen (*avp
) + 1; /* include the null */
1917 s_length
+= (l
+ 3) & ~3; /* make it a 4 byte boundary */
1925 l
= strlen (*avp
) + 1; /* include the null */
1926 s_length
+= (l
+ 3) & ~ 3;/* make it a 4 byte boundary */
1930 /* Claim some memory for the pointers and strings. */
1931 pointers
= hi_stack
- sizeof(word
) * (nenv
+1+nargs
+1);
1932 pointers
&= ~3; /* must be 4-byte aligned */
1933 cpu
.gr
[0] = pointers
;
1935 strings
= cpu
.gr
[0] - s_length
;
1936 strings
&= ~3; /* want to make it 4-byte aligned */
1937 cpu
.gr
[0] = strings
;
1938 /* dac fix, the stack address must be 8-byte aligned! */
1939 cpu
.gr
[0] = cpu
.gr
[0] - cpu
.gr
[0] % 8;
1941 /* Loop through the arguments and fill them in. */
1942 cpu
.gr
[PARM1
] = nargs
;
1945 /* No strings to fill in. */
1950 cpu
.gr
[PARM2
] = pointers
;
1954 /* Save where we're putting it. */
1955 wlat (pointers
, strings
);
1957 /* Copy the string. */
1958 l
= strlen (* avp
) + 1;
1959 strcpy ((char *)(cpu
.mem
+ strings
), *avp
);
1961 /* Bump the pointers. */
1967 /* A null to finish the list. */
1972 /* Now do the environment pointers. */
1975 /* No strings to fill in. */
1980 cpu
.gr
[PARM3
] = pointers
;
1985 /* Save where we're putting it. */
1986 wlat (pointers
, strings
);
1988 /* Copy the string. */
1989 l
= strlen (* avp
) + 1;
1990 strcpy ((char *)(cpu
.mem
+ strings
), *avp
);
1992 /* Bump the pointers. */
1998 /* A null to finish the list. */
2007 sim_do_command (SIM_DESC sd
, const char *cmd
)
2009 /* Nothing there yet; it's all an error. */
2013 char ** simargv
= buildargv (cmd
);
2015 if (strcmp (simargv
[0], "watch") == 0)
2017 if ((simargv
[1] == NULL
) || (simargv
[2] == NULL
))
2019 fprintf (stderr
, "Error: missing argument to watch cmd.\n");
2026 WL
[ENDWL
] = strtol (simargv
[2], NULL
, 0);
2027 WLstr
[ENDWL
] = strdup (simargv
[1]);
2028 fprintf (stderr
, "Added %s (%x) to watchlist, #%d\n",WLstr
[ENDWL
],
2032 else if (strcmp (simargv
[0], "dumpmem") == 0)
2037 if (simargv
[1] == NULL
)
2038 fprintf (stderr
, "Error: missing argument to dumpmem cmd.\n");
2040 fprintf (stderr
, "Writing dumpfile %s...",simargv
[1]);
2042 dumpfile
= fopen (simargv
[1], "w");
2044 fwrite (p
, cpu
.asregs
.msize
-1, 1, dumpfile
);
2047 fprintf (stderr
, "done.\n");
2049 else if (strcmp (simargv
[0], "clearstats") == 0)
2051 cpu
.asregs
.cycles
= 0;
2052 cpu
.asregs
.insts
= 0;
2053 cpu
.asregs
.stalls
= 0;
2056 else if (strcmp (simargv
[0], "verbose") == 0)
2062 fprintf (stderr
,"Error: \"%s\" is not a valid M.CORE simulator command.\n",
2070 fprintf (stderr
, "M.CORE sim commands: \n");
2071 fprintf (stderr
, " watch <funcname> <addr>\n");
2072 fprintf (stderr
, " dumpmem <filename>\n");
2073 fprintf (stderr
, " clearstats\n");
2074 fprintf (stderr
, " verbose\n");
This page took 0.072788 seconds and 4 git commands to generate.