1 /* Simulator for Motorola's MCore processor
2 Copyright (C) 1999, 2000, 2002, 2003, 2007 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/>. */
22 #include <sys/times.h>
23 #include <sys/param.h>
24 #include <netinet/in.h> /* for byte ordering macros */
26 #include "gdb/callback.h"
27 #include "libiberty.h"
28 #include "gdb/remote-sim.h"
31 #define NUM_ELEM(A) (sizeof (A) / sizeof (A)[0])
35 typedef long int word;
36 typedef unsigned long int uword;
38 static int target_big_endian = 0;
39 static unsigned long heap_ptr = 0;
40 host_callback * callback;
44 mcore_extract_unsigned_integer (addr, len)
50 unsigned char * startaddr = (unsigned char *)addr;
51 unsigned char * endaddr = startaddr + len;
53 if (len > (int) sizeof (unsigned long))
54 printf ("That operation is not available on integers of more than %d bytes.",
55 sizeof (unsigned long));
57 /* Start at the most significant end of the integer, and work towards
58 the least significant. */
61 if (! target_big_endian)
63 for (p = endaddr; p > startaddr;)
64 retval = (retval << 8) | * -- p;
68 for (p = startaddr; p < endaddr;)
69 retval = (retval << 8) | * p ++;
76 mcore_store_unsigned_integer (addr, len, val)
82 unsigned char * startaddr = (unsigned char *)addr;
83 unsigned char * endaddr = startaddr + len;
85 if (! target_big_endian)
87 for (p = startaddr; p < endaddr;)
95 for (p = endaddr; p > startaddr;)
103 /* The machine state.
104 This state is maintained in host byte order. The
105 fetch/store register functions must translate between host
106 byte order and the target processor byte order.
107 Keeping this data in target byte order simplifies the register
108 read/write functions. Keeping this data in native order improves
109 the performance of the simulator. Simulation speed is deemed more
112 /* The ordering of the mcore_regset structure is matched in the
113 gdb/config/mcore/tm-mcore.h file in the REGISTER_NAMES macro. */
116 word gregs [16]; /* primary registers */
117 word alt_gregs [16]; /* alt register file */
118 word cregs [32]; /* control registers */
119 word pc; /* the pc */
126 unsigned char * memory;
132 struct mcore_regset asregs;
133 word asints [1]; /* but accessed larger... */
136 #define LAST_VALID_CREG 32 /* only 0..12 implemented */
137 #define NUM_MCORE_REGS (16 + 16 + LAST_VALID_CREG + 1)
141 static SIM_OPEN_KIND sim_kind;
142 static char * myname;
144 static int issue_messages = 0;
146 #define gr asregs.active_gregs
147 #define cr asregs.cregs
148 #define sr asregs.cregs[0]
149 #define vbr asregs.cregs[1]
150 #define esr asregs.cregs[2]
151 #define fsr asregs.cregs[3]
152 #define epc asregs.cregs[4]
153 #define fpc asregs.cregs[5]
154 #define ss0 asregs.cregs[6]
155 #define ss1 asregs.cregs[7]
156 #define ss2 asregs.cregs[8]
157 #define ss3 asregs.cregs[9]
158 #define ss4 asregs.cregs[10]
159 #define gcr asregs.cregs[11]
160 #define gsr asregs.cregs[12]
161 #define mem asregs.memory
163 /* maniuplate the carry bit */
164 #define C_ON() (cpu.sr & 1)
165 #define C_VALUE() (cpu.sr & 1)
166 #define C_OFF() ((cpu.sr & 1) == 0)
167 #define SET_C() {cpu.sr |= 1;}
168 #define CLR_C() {cpu.sr &= 0xfffffffe;}
169 #define NEW_C(v) {CLR_C(); cpu.sr |= ((v) & 1);}
171 #define SR_AF() ((cpu.sr >> 1) & 1)
173 #define TRAPCODE 1 /* r1 holds which function we want */
174 #define PARM1 2 /* first parameter */
178 #define RET1 2 /* register for return values. */
188 heap_ptr += inc_bytes;
190 if (issue_messages && heap_ptr>cpu.gr[0])
191 fprintf (stderr, "Warning: heap_ptr overlaps stack!\n");
200 if (((uword)x) >= cpu.asregs.msize)
203 fprintf (stderr, "byte write to 0x%x outside memory range\n", x);
205 cpu.asregs.exception = SIGSEGV;
209 unsigned char *p = cpu.mem + x;
218 if (((uword)x) >= cpu.asregs.msize)
221 fprintf (stderr, "word write to 0x%x outside memory range\n", x);
223 cpu.asregs.exception = SIGSEGV;
230 fprintf (stderr, "word write to unaligned memory address: 0x%x\n", x);
232 cpu.asregs.exception = SIGBUS;
234 else if (! target_big_endian)
236 unsigned char * p = cpu.mem + x;
244 unsigned char * p = cpu.mem + x;
257 if (((uword)x) >= cpu.asregs.msize)
260 fprintf (stderr, "short write to 0x%x outside memory range\n", x);
262 cpu.asregs.exception = SIGSEGV;
269 fprintf (stderr, "short write to unaligned memory address: 0x%x\n",
272 cpu.asregs.exception = SIGBUS;
274 else if (! target_big_endian)
276 unsigned char * p = cpu.mem + x;
282 unsigned char * p = cpu.mem + x;
289 /* Read functions. */
294 if (((uword)x) >= cpu.asregs.msize)
297 fprintf (stderr, "byte read from 0x%x outside memory range\n", x);
299 cpu.asregs.exception = SIGSEGV;
304 unsigned char * p = cpu.mem + x;
313 if (((uword) x) >= cpu.asregs.msize)
316 fprintf (stderr, "word read from 0x%x outside memory range\n", x);
318 cpu.asregs.exception = SIGSEGV;
326 fprintf (stderr, "word read from unaligned address: 0x%x\n", x);
328 cpu.asregs.exception = SIGBUS;
331 else if (! target_big_endian)
333 unsigned char * p = cpu.mem + x;
334 return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
338 unsigned char * p = cpu.mem + x;
339 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
348 if (((uword)x) >= cpu.asregs.msize)
351 fprintf (stderr, "short read from 0x%x outside memory range\n", x);
353 cpu.asregs.exception = SIGSEGV;
361 fprintf (stderr, "short read from unaligned address: 0x%x\n", x);
363 cpu.asregs.exception = SIGBUS;
366 else if (! target_big_endian)
368 unsigned char * p = cpu.mem + x;
369 return (p[1] << 8) | p[0];
373 unsigned char * p = cpu.mem + x;
374 return (p[0] << 8) | p[1];
380 #define SEXTB(x) (((x & 0xff) ^ (~ 0x7f)) + 0x80)
381 #define SEXTW(y) ((int)((short)y))
384 IOMEM (addr, write, value)
391 /* Default to a 8 Mbyte (== 2^23) memory space. */
392 static int sim_memory_size = 23;
394 #define MEM_SIZE_FLOOR 64
399 sim_memory_size = power;
400 cpu.asregs.msize = 1 << sim_memory_size;
405 /* Watch out for the '0 count' problem. There's probably a better
406 way.. e.g., why do we use 64 here? */
407 if (cpu.asregs.msize < 64) /* Ensure a boundary. */
408 cpu.mem = (unsigned char *) calloc (64, (64 + cpu.asregs.msize) / 64);
410 cpu.mem = (unsigned char *) calloc (64, cpu.asregs.msize / 64);
416 "Not enough VM for simulation of %d bytes of RAM\n",
419 cpu.asregs.msize = 1;
420 cpu.mem = (unsigned char *) calloc (1, 1);
427 if (cpu.asregs.msize != (1 << sim_memory_size))
428 sim_size (sim_memory_size);
436 unsigned long memsize;
440 /* Set up machine just out of reset. */
444 memsize = cpu.asregs.msize / (1024 * 1024);
446 if (issue_messages > 1)
447 fprintf (stderr, "Simulated memory of %d Mbytes (0x0 .. 0x%08x)\n",
448 memsize, cpu.asregs.msize - 1);
450 /* Clean out the GPRs and alternate GPRs. */
451 for (i = 0; i < 16; i++)
453 cpu.asregs.gregs[i] = 0;
454 cpu.asregs.alt_gregs[i] = 0;
457 /* Make our register set point to the right place. */
459 cpu.asregs.active_gregs = &cpu.asregs.alt_gregs[0];
461 cpu.asregs.active_gregs = &cpu.asregs.gregs[0];
463 /* ABI specifies initial values for these registers. */
464 cpu.gr[0] = cpu.asregs.msize - 4;
466 /* dac fix, the stack address must be 8-byte aligned! */
467 cpu.gr[0] = cpu.gr[0] - cpu.gr[0] % 8;
471 cpu.gr[PARM4] = cpu.gr[0];
477 cpu.asregs.exception = SIGINT;
480 /* Functions so that trapped open/close don't interfere with the
481 parent's functions. We say that we can't close the descriptors
482 that we didn't open. exit() and cleanup() get in trouble here,
483 to some extent. That's the price of emulation. */
485 unsigned char opened[100];
491 if (fd < 0 || fd > NUM_ELEM (opened))
501 if (fd < 0 || fd > NUM_ELEM (opened))
511 if (fd < 0 || fd > NUM_ELEM (opened))
522 switch ((unsigned long) (cpu.gr [TRAPCODE]))
525 a[0] = (unsigned long) (cpu.gr[PARM1]);
526 a[1] = (unsigned long) (cpu.mem + cpu.gr[PARM2]);
527 a[2] = (unsigned long) (cpu.gr[PARM3]);
528 cpu.gr[RET1] = callback->read (callback, a[0], (char *) a[1], a[2]);
532 a[0] = (unsigned long) (cpu.gr[PARM1]);
533 a[1] = (unsigned long) (cpu.mem + cpu.gr[PARM2]);
534 a[2] = (unsigned long) (cpu.gr[PARM3]);
535 cpu.gr[RET1] = (int)callback->write (callback, a[0], (char *) a[1], a[2]);
539 a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
540 a[1] = (unsigned long) (cpu.gr[PARM2]);
541 /* a[2] = (unsigned long) (cpu.gr[PARM3]); */
542 cpu.gr[RET1] = callback->open (callback, (char *) a[0], a[1]);
543 log_open (cpu.gr[RET1]);
547 a[0] = (unsigned long) (cpu.gr[PARM1]);
548 /* Watch out for debugger's files. */
549 if (is_opened (a[0]))
552 cpu.gr[RET1] = callback->close (callback, a[0]);
556 /* Don't let him close it. */
562 a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
563 a[1] = (unsigned long) (cpu.mem + cpu.gr[PARM2]);
564 cpu.gr[RET1] = link ((char *) a[0], (char *) a[1]);
568 a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
569 cpu.gr[RET1] = callback->unlink (callback, (char *) a[0]);
573 /* handle time(0) vs time(&var) */
574 a[0] = (unsigned long) (cpu.gr[PARM1]);
576 a[0] += (unsigned long) cpu.mem;
577 cpu.gr[RET1] = callback->time (callback, (time_t *) a[0]);
581 a[0] = (unsigned long) (cpu.gr[PARM1]);
582 a[1] = (unsigned long) (cpu.gr[PARM2]);
583 a[2] = (unsigned long) (cpu.gr[PARM3]);
584 cpu.gr[RET1] = callback->lseek (callback, a[0], a[1], a[2]);
588 a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
589 a[1] = (unsigned long) (cpu.gr[PARM2]);
590 cpu.gr[RET1] = access ((char *) a[0], a[1]);
594 a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
596 cpu.gr[RET1] = times ((char *)a[0]);
599 /* Give him simulated cycles for utime
600 and an instruction count for stime. */
609 t.tms_utime = cpu.asregs.cycles;
610 t.tms_stime = cpu.asregs.insts;
611 t.tms_cutime = t.tms_utime;
612 t.tms_cstime = t.tms_stime;
614 memcpy ((struct tms *)(a[0]), &t, sizeof (t));
616 cpu.gr[RET1] = cpu.asregs.cycles;
622 a[0] = (unsigned long) (cpu.gr[PARM1]);
623 cpu.gr[RET1] = int_sbrk (a[0]);
628 fprintf (stderr, "WARNING: sys call %d unimplemented\n",
638 /* These values should match those in libgloss/mcore/syscalls.s. */
645 case 10: /* _unlink */
646 case 19: /* _lseek */
647 case 43: /* _times */
648 cpu.gr [TRAPCODE] = what;
654 fprintf (stderr, "Unhandled stub opcode: %d\n", what);
666 cpu.asregs.exception = SIGQUIT;
675 a[0] = (unsigned long)(cpu.mem + cpu.gr[PARM1]);
677 for (s = (unsigned char *)a[0], i = 1 ; *s && i < 6 ; s++)
682 a[i] = (unsigned long)(cpu.mem + cpu.gr[PARM1+i]);
684 a[i] = cpu.gr[i+PARM1];
689 cpu.gr[RET1] = printf ((char *)a[0], a[1], a[2], a[3], a[4], a[5]);
695 fprintf (stderr, "WARNING: scanf unimplemented\n");
699 cpu.gr[RET1] = cpu.asregs.insts;
703 process_stub (cpu.gr[1]);
708 fprintf (stderr, "Unhandled util code: %x\n", what);
713 /* For figuring out whether we carried; addc/subc use this. */
722 x = (a & 0xffff) + (b & 0xffff) + cin;
723 x = (x >> 16) + (a >> 16) + (b >> 16);
729 #define WATCHFUNCTIONS 1
730 #ifdef WATCHFUNCTIONS
747 #define RD (inst & 0xF)
748 #define RS ((inst >> 4) & 0xF)
749 #define RX ((inst >> 8) & 0xF)
750 #define IMM5 ((inst >> 4) & 0x1F)
751 #define IMM4 ((inst) & 0xF)
753 static int tracing = 0;
756 sim_resume (sd, step, siggnal)
772 sigsave = signal (SIGINT, interrupt);
773 cpu.asregs.exception = step ? SIGTRAP: 0;
776 /* Fetch the initial instructions that we'll decode. */
777 ibuf = rlat (pc & 0xFFFFFFFC);
784 /* make our register set point to the right place */
786 cpu.asregs.active_gregs = & cpu.asregs.alt_gregs[0];
788 cpu.asregs.active_gregs = & cpu.asregs.gregs[0];
790 /* make a hash to speed exec loop, hope it's nonzero */
793 for (w = 1; w <= ENDWL; w++)
794 WLhash = WLhash & WL[w];
804 if (! target_big_endian)
807 inst = ibuf & 0xFFFF;
812 if (! target_big_endian)
813 inst = ibuf & 0xFFFF;
818 #ifdef WATCHFUNCTIONS
819 /* now scan list of watch addresses, if match, count it and
820 note return address and count cycles until pc=return address */
822 if ((WLincyc == 1) && (pc == WLendpc))
824 cycs = (cpu.asregs.cycles + (insts + bonus_cycles +
825 (memops * memcycles)) - WLbcyc);
827 if (WLcnts[WLW] == 1)
834 if (cycs > WLmax[WLW])
839 if (cycs < WLmin[WLW])
849 /* Optimize with a hash to speed loop. */
852 if ((WLhash == 0) || ((WLhash & pc) != 0))
854 for (w=1; w <= ENDWL; w++)
859 WLbcyc = cpu.asregs.cycles + insts
860 + bonus_cycles + (memops * memcycles);
861 WLendpc = cpu.gr[15];
872 fprintf (stderr, "%.4x: inst = %.4x ", pc, inst);
887 cpu.asregs.exception = SIGTRAP;
900 cpu.asregs.active_gregs = & cpu.asregs.alt_gregs[0];
902 cpu.asregs.active_gregs = & cpu.asregs.gregs[0];
911 cpu.asregs.active_gregs = &cpu.asregs.alt_gregs[0];
913 cpu.asregs.active_gregs = &cpu.asregs.gregs[0];
918 fprintf (stderr, "WARNING: stop unimplemented\n");
923 fprintf (stderr, "WARNING: wait unimplemented\n");
928 fprintf (stderr, "WARNING: doze unimplemented\n");
932 cpu.asregs.exception = SIGILL; /* illegal */
935 case 0x8: /* trap 0 */
936 case 0xA: /* trap 2 */
937 case 0xB: /* trap 3 */
938 cpu.asregs.exception = SIGTRAP;
941 case 0xC: /* trap 4 */
942 case 0xD: /* trap 5 */
943 case 0xE: /* trap 6 */
944 cpu.asregs.exception = SIGILL; /* illegal */
947 case 0xF: /* trap 7 */
948 cpu.asregs.exception = SIGTRAP; /* integer div-by-0 */
951 case 0x9: /* trap 1 */
958 cpu.asregs.exception = SIGILL; /* illegal */
962 cpu.gr[RD] = C_VALUE();
965 cpu.gr[RD] = C_OFF();
969 char *addr = (char *)cpu.gr[RD];
970 int regno = 4; /* always r4-r7 */
976 cpu.gr[regno] = rlat(addr);
980 while ((regno&0x3) != 0);
985 char *addr = (char *)cpu.gr[RD];
986 int regno = 4; /* always r4-r7 */
992 wlat(addr, cpu.gr[regno]);
996 while ((regno & 0x3) != 0);
1001 char *addr = (char *)cpu.gr[0];
1004 /* bonus cycle is really only needed if
1005 the next insn shifts the last reg loaded.
1010 while (regno <= 0xF)
1012 cpu.gr[regno] = rlat(addr);
1020 char *addr = (char *)cpu.gr[0];
1023 /* this should be removed! */
1024 /* bonus_cycles ++; */
1026 memops += 16 - regno;
1027 while (regno <= 0xF)
1029 wlat(addr, cpu.gr[regno]);
1036 case 0x8: /* dect */
1037 cpu.gr[RD] -= C_VALUE();
1039 case 0x9: /* decf */
1040 cpu.gr[RD] -= C_OFF();
1042 case 0xA: /* inct */
1043 cpu.gr[RD] += C_VALUE();
1045 case 0xB: /* incf */
1046 cpu.gr[RD] += C_OFF();
1050 if (tracing && RD == 15)
1051 fprintf (stderr, "Func return, r2 = %x, r3 = %x\n",
1052 cpu.gr[2], cpu.gr[3]);
1066 for (i = 0; !(tmp & 0x80000000) && i < 32; i++)
1071 case 0xF: /* brev */
1075 tmp = ((tmp & 0xaaaaaaaa) >> 1) | ((tmp & 0x55555555) << 1);
1076 tmp = ((tmp & 0xcccccccc) >> 2) | ((tmp & 0x33333333) << 2);
1077 tmp = ((tmp & 0xf0f0f0f0) >> 4) | ((tmp & 0x0f0f0f0f) << 4);
1078 tmp = ((tmp & 0xff00ff00) >> 8) | ((tmp & 0x00ff00ff) << 8);
1079 cpu.gr[RD] = ((tmp & 0xffff0000) >> 16) | ((tmp & 0x0000ffff) << 16);
1087 case 0x0: /* xtrb3 */
1088 cpu.gr[1] = (cpu.gr[RD]) & 0xFF;
1089 NEW_C (cpu.gr[RD] != 0);
1091 case 0x1: /* xtrb2 */
1092 cpu.gr[1] = (cpu.gr[RD]>>8) & 0xFF;
1093 NEW_C (cpu.gr[RD] != 0);
1095 case 0x2: /* xtrb1 */
1096 cpu.gr[1] = (cpu.gr[RD]>>16) & 0xFF;
1097 NEW_C (cpu.gr[RD] != 0);
1099 case 0x3: /* xtrb0 */
1100 cpu.gr[1] = (cpu.gr[RD]>>24) & 0xFF;
1101 NEW_C (cpu.gr[RD] != 0);
1103 case 0x4: /* zextb */
1104 cpu.gr[RD] &= 0x000000FF;
1106 case 0x5: /* sextb */
1115 case 0x6: /* zexth */
1116 cpu.gr[RD] &= 0x0000FFFF;
1118 case 0x7: /* sexth */
1127 case 0x8: /* declt */
1129 NEW_C ((long)cpu.gr[RD] < 0);
1131 case 0x9: /* tstnbz */
1133 word tmp = cpu.gr[RD];
1134 NEW_C ((tmp & 0xFF000000) != 0 &&
1135 (tmp & 0x00FF0000) != 0 && (tmp & 0x0000FF00) != 0 &&
1136 (tmp & 0x000000FF) != 0);
1139 case 0xA: /* decgt */
1141 NEW_C ((long)cpu.gr[RD] > 0);
1143 case 0xB: /* decne */
1145 NEW_C ((long)cpu.gr[RD] != 0);
1147 case 0xC: /* clrt */
1151 case 0xD: /* clrf */
1156 if (cpu.gr[RD] & 0x80000000)
1157 cpu.gr[RD] = ~cpu.gr[RD] + 1;
1160 cpu.gr[RD] = ~cpu.gr[RD];
1164 case 0x02: /* movt */
1166 cpu.gr[RD] = cpu.gr[RS];
1168 case 0x03: /* mult */
1169 /* consume 2 bits per cycle from rs, until rs is 0 */
1171 unsigned int t = cpu.gr[RS];
1173 for (ticks = 0; t != 0 ; t >>= 2)
1175 bonus_cycles += ticks;
1177 bonus_cycles += 2; /* min. is 3, so add 2, plus ticks above */
1179 fprintf (stderr, " mult %x by %x to give %x",
1180 cpu.gr[RD], cpu.gr[RS], cpu.gr[RD] * cpu.gr[RS]);
1181 cpu.gr[RD] = cpu.gr[RD] * cpu.gr[RS];
1183 case 0x04: /* loopt */
1186 pc += (IMM4 << 1) - 32;
1190 --cpu.gr[RS]; /* not RD! */
1191 NEW_C (((long)cpu.gr[RS]) > 0);
1193 case 0x05: /* subu */
1194 cpu.gr[RD] -= cpu.gr[RS];
1196 case 0x06: /* addc */
1198 unsigned long tmp, a, b;
1201 cpu.gr[RD] = a + b + C_VALUE ();
1202 tmp = iu_carry (a, b, C_VALUE ());
1206 case 0x07: /* subc */
1208 unsigned long tmp, a, b;
1211 cpu.gr[RD] = a - b + C_VALUE () - 1;
1212 tmp = iu_carry (a,~b, C_VALUE ());
1216 case 0x08: /* illegal */
1217 case 0x09: /* illegal*/
1218 cpu.asregs.exception = SIGILL;
1220 case 0x0A: /* movf */
1222 cpu.gr[RD] = cpu.gr[RS];
1224 case 0x0B: /* lsr */
1226 unsigned long dst, src;
1229 /* We must not rely solely upon the native shift operations, since they
1230 may not match the M*Core's behaviour on boundary conditions. */
1231 dst = src > 31 ? 0 : dst >> src;
1235 case 0x0C: /* cmphs */
1236 NEW_C ((unsigned long )cpu.gr[RD] >=
1237 (unsigned long)cpu.gr[RS]);
1239 case 0x0D: /* cmplt */
1240 NEW_C ((long)cpu.gr[RD] < (long)cpu.gr[RS]);
1242 case 0x0E: /* tst */
1243 NEW_C ((cpu.gr[RD] & cpu.gr[RS]) != 0);
1245 case 0x0F: /* cmpne */
1246 NEW_C (cpu.gr[RD] != cpu.gr[RS]);
1248 case 0x10: case 0x11: /* mfcr */
1252 if (r <= LAST_VALID_CREG)
1253 cpu.gr[RD] = cpu.cr[r];
1255 cpu.asregs.exception = SIGILL;
1259 case 0x12: /* mov */
1260 cpu.gr[RD] = cpu.gr[RS];
1262 fprintf (stderr, "MOV %x into reg %d", cpu.gr[RD], RD);
1265 case 0x13: /* bgenr */
1266 if (cpu.gr[RS] & 0x20)
1269 cpu.gr[RD] = 1 << (cpu.gr[RS] & 0x1F);
1272 case 0x14: /* rsub */
1273 cpu.gr[RD] = cpu.gr[RS] - cpu.gr[RD];
1276 case 0x15: /* ixw */
1277 cpu.gr[RD] += cpu.gr[RS]<<2;
1280 case 0x16: /* and */
1281 cpu.gr[RD] &= cpu.gr[RS];
1284 case 0x17: /* xor */
1285 cpu.gr[RD] ^= cpu.gr[RS];
1288 case 0x18: case 0x19: /* mtcr */
1292 if (r <= LAST_VALID_CREG)
1293 cpu.cr[r] = cpu.gr[RD];
1295 cpu.asregs.exception = SIGILL;
1297 /* we might have changed register sets... */
1299 cpu.asregs.active_gregs = & cpu.asregs.alt_gregs[0];
1301 cpu.asregs.active_gregs = & cpu.asregs.gregs[0];
1305 case 0x1A: /* asr */
1306 /* We must not rely solely upon the native shift operations, since they
1307 may not match the M*Core's behaviour on boundary conditions. */
1308 if (cpu.gr[RS] > 30)
1309 cpu.gr[RD] = ((long) cpu.gr[RD]) < 0 ? -1 : 0;
1311 cpu.gr[RD] = (long) cpu.gr[RD] >> cpu.gr[RS];
1314 case 0x1B: /* lsl */
1315 /* We must not rely solely upon the native shift operations, since they
1316 may not match the M*Core's behaviour on boundary conditions. */
1317 cpu.gr[RD] = cpu.gr[RS] > 31 ? 0 : cpu.gr[RD] << cpu.gr[RS];
1320 case 0x1C: /* addu */
1321 cpu.gr[RD] += cpu.gr[RS];
1324 case 0x1D: /* ixh */
1325 cpu.gr[RD] += cpu.gr[RS] << 1;
1329 cpu.gr[RD] |= cpu.gr[RS];
1332 case 0x1F: /* andn */
1333 cpu.gr[RD] &= ~cpu.gr[RS];
1335 case 0x20: case 0x21: /* addi */
1337 cpu.gr[RD] + (IMM5 + 1);
1339 case 0x22: case 0x23: /* cmplti */
1341 int tmp = (IMM5 + 1);
1342 if (cpu.gr[RD] < tmp)
1352 case 0x24: case 0x25: /* subi */
1354 cpu.gr[RD] - (IMM5 + 1);
1356 case 0x26: case 0x27: /* illegal */
1357 cpu.asregs.exception = SIGILL;
1359 case 0x28: case 0x29: /* rsubi */
1363 case 0x2A: case 0x2B: /* cmpnei */
1364 if (cpu.gr[RD] != IMM5)
1374 case 0x2C: case 0x2D: /* bmaski, divu */
1376 unsigned imm = IMM5;
1382 unsigned int rx, r1;
1388 /* unsigned divide */
1389 cpu.gr[RD] = (word) ((unsigned int) cpu.gr[RD] / (unsigned int)cpu.gr[1] );
1391 /* compute bonus_cycles for divu */
1392 for (r1nlz = 0; ((r1 & 0x80000000) == 0) && (r1nlz < 32); r1nlz ++)
1395 for (rxnlz = 0; ((rx & 0x80000000) == 0) && (rxnlz < 32); rxnlz ++)
1401 exe += 5 + r1nlz - rxnlz;
1403 if (exe >= (2 * memcycles - 1))
1405 bonus_cycles += exe - (2 * memcycles) + 1;
1408 else if (imm == 0 || imm >= 8)
1414 cpu.gr[RD] = (1 << imm) - 1;
1419 cpu.asregs.exception = SIGILL;
1423 case 0x2E: case 0x2F: /* andi */
1424 cpu.gr[RD] = cpu.gr[RD] & IMM5;
1426 case 0x30: case 0x31: /* bclri */
1427 cpu.gr[RD] = cpu.gr[RD] & ~(1<<IMM5);
1429 case 0x32: case 0x33: /* bgeni, divs */
1431 unsigned imm = IMM5;
1438 /* compute bonus_cycles for divu */
1443 if (((rx < 0) && (r1 > 0)) || ((rx >= 0) && (r1 < 0)))
1451 /* signed divide, general registers are of type int, so / op is OK */
1452 cpu.gr[RD] = cpu.gr[RD] / cpu.gr[1];
1454 for (r1nlz = 0; ((r1 & 0x80000000) == 0) && (r1nlz < 32) ; r1nlz ++ )
1457 for (rxnlz = 0; ((rx & 0x80000000) == 0) && (rxnlz < 32) ; rxnlz ++ )
1463 exe += 6 + r1nlz - rxnlz + sc;
1465 if (exe >= (2 * memcycles - 1))
1467 bonus_cycles += exe - (2 * memcycles) + 1;
1473 cpu.gr[RD] = (1 << IMM5);
1478 cpu.asregs.exception = SIGILL;
1482 case 0x34: case 0x35: /* bseti */
1483 cpu.gr[RD] = cpu.gr[RD] | (1 << IMM5);
1485 case 0x36: case 0x37: /* btsti */
1486 NEW_C (cpu.gr[RD] >> IMM5);
1488 case 0x38: case 0x39: /* xsr, rotli */
1490 unsigned imm = IMM5;
1491 unsigned long tmp = cpu.gr[RD];
1497 cpu.gr[RD] = (cbit << 31) | (tmp >> 1);
1500 cpu.gr[RD] = (tmp << imm) | (tmp >> (32 - imm));
1503 case 0x3A: case 0x3B: /* asrc, asri */
1505 unsigned imm = IMM5;
1506 long tmp = cpu.gr[RD];
1510 cpu.gr[RD] = tmp >> 1;
1513 cpu.gr[RD] = tmp >> imm;
1516 case 0x3C: case 0x3D: /* lslc, lsli */
1518 unsigned imm = IMM5;
1519 unsigned long tmp = cpu.gr[RD];
1523 cpu.gr[RD] = tmp << 1;
1526 cpu.gr[RD] = tmp << imm;
1529 case 0x3E: case 0x3F: /* lsrc, lsri */
1531 unsigned imm = IMM5;
1532 unsigned long tmp = cpu.gr[RD];
1536 cpu.gr[RD] = tmp >> 1;
1539 cpu.gr[RD] = tmp >> imm;
1542 case 0x40: case 0x41: case 0x42: case 0x43:
1543 case 0x44: case 0x45: case 0x46: case 0x47:
1544 case 0x48: case 0x49: case 0x4A: case 0x4B:
1545 case 0x4C: case 0x4D: case 0x4E: case 0x4F:
1546 cpu.asregs.exception = SIGILL;
1551 case 0x51: case 0x52: case 0x53:
1552 case 0x54: case 0x55: case 0x56: case 0x57:
1553 case 0x58: case 0x59: case 0x5A: case 0x5B:
1554 case 0x5C: case 0x5D: case 0x5E: case 0x5F:
1555 cpu.asregs.exception = SIGILL;
1557 case 0x60: case 0x61: case 0x62: case 0x63: /* movi */
1558 case 0x64: case 0x65: case 0x66: case 0x67:
1559 cpu.gr[RD] = (inst >> 4) & 0x7F;
1561 case 0x68: case 0x69: case 0x6A: case 0x6B:
1562 case 0x6C: case 0x6D: case 0x6E: case 0x6F: /* illegal */
1563 cpu.asregs.exception = SIGILL;
1565 case 0x71: case 0x72: case 0x73:
1566 case 0x74: case 0x75: case 0x76: case 0x77:
1567 case 0x78: case 0x79: case 0x7A: case 0x7B:
1568 case 0x7C: case 0x7D: case 0x7E: /* lrw */
1569 cpu.gr[RX] = rlat ((pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
1571 fprintf (stderr, "LRW of 0x%x from 0x%x to reg %d",
1572 rlat ((pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC),
1573 (pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC, RX);
1576 case 0x7F: /* jsri */
1579 fprintf (stderr, "func call: r2 = %x r3 = %x r4 = %x r5 = %x r6 = %x r7 = %x\n",
1580 cpu.gr[2], cpu.gr[3], cpu.gr[4], cpu.gr[5], cpu.gr[6], cpu.gr[7]);
1581 case 0x70: /* jmpi */
1582 pc = rlat ((pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
1588 case 0x80: case 0x81: case 0x82: case 0x83:
1589 case 0x84: case 0x85: case 0x86: case 0x87:
1590 case 0x88: case 0x89: case 0x8A: case 0x8B:
1591 case 0x8C: case 0x8D: case 0x8E: case 0x8F: /* ld */
1592 cpu.gr[RX] = rlat (cpu.gr[RD] + ((inst >> 2) & 0x003C));
1594 fprintf (stderr, "load reg %d from 0x%x with 0x%x",
1596 cpu.gr[RD] + ((inst >> 2) & 0x003C), cpu.gr[RX]);
1599 case 0x90: case 0x91: case 0x92: case 0x93:
1600 case 0x94: case 0x95: case 0x96: case 0x97:
1601 case 0x98: case 0x99: case 0x9A: case 0x9B:
1602 case 0x9C: case 0x9D: case 0x9E: case 0x9F: /* st */
1603 wlat (cpu.gr[RD] + ((inst >> 2) & 0x003C), cpu.gr[RX]);
1605 fprintf (stderr, "store reg %d (containing 0x%x) to 0x%x",
1607 cpu.gr[RD] + ((inst >> 2) & 0x003C));
1610 case 0xA0: case 0xA1: case 0xA2: case 0xA3:
1611 case 0xA4: case 0xA5: case 0xA6: case 0xA7:
1612 case 0xA8: case 0xA9: case 0xAA: case 0xAB:
1613 case 0xAC: case 0xAD: case 0xAE: case 0xAF: /* ld.b */
1614 cpu.gr[RX] = rbat (cpu.gr[RD] + RS);
1617 case 0xB0: case 0xB1: case 0xB2: case 0xB3:
1618 case 0xB4: case 0xB5: case 0xB6: case 0xB7:
1619 case 0xB8: case 0xB9: case 0xBA: case 0xBB:
1620 case 0xBC: case 0xBD: case 0xBE: case 0xBF: /* st.b */
1621 wbat (cpu.gr[RD] + RS, cpu.gr[RX]);
1624 case 0xC0: case 0xC1: case 0xC2: case 0xC3:
1625 case 0xC4: case 0xC5: case 0xC6: case 0xC7:
1626 case 0xC8: case 0xC9: case 0xCA: case 0xCB:
1627 case 0xCC: case 0xCD: case 0xCE: case 0xCF: /* ld.h */
1628 cpu.gr[RX] = rhat (cpu.gr[RD] + ((inst >> 3) & 0x001E));
1631 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
1632 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
1633 case 0xD8: case 0xD9: case 0xDA: case 0xDB:
1634 case 0xDC: case 0xDD: case 0xDE: case 0xDF: /* st.h */
1635 what (cpu.gr[RD] + ((inst >> 3) & 0x001E), cpu.gr[RX]);
1638 case 0xE8: case 0xE9: case 0xEA: case 0xEB:
1639 case 0xEC: case 0xED: case 0xEE: case 0xEF: /* bf */
1643 disp = inst & 0x03FF;
1651 case 0xE0: case 0xE1: case 0xE2: case 0xE3:
1652 case 0xE4: case 0xE5: case 0xE6: case 0xE7: /* bt */
1656 disp = inst & 0x03FF;
1665 case 0xF8: case 0xF9: case 0xFA: case 0xFB:
1666 case 0xFC: case 0xFD: case 0xFE: case 0xFF: /* bsr */
1668 case 0xF0: case 0xF1: case 0xF2: case 0xF3:
1669 case 0xF4: case 0xF5: case 0xF6: case 0xF7: /* br */
1672 disp = inst & 0x03FF;
1684 fprintf (stderr, "\n");
1688 /* Do not let him fetch from a bad address! */
1689 if (((uword)pc) >= cpu.asregs.msize)
1692 fprintf (stderr, "PC loaded at 0x%x is outside of available memory! (0x%x)\n", oldpc, pc);
1694 cpu.asregs.exception = SIGSEGV;
1698 ibuf = rlat (pc & 0xFFFFFFFC);
1703 while (!cpu.asregs.exception);
1705 /* Hide away the things we've cached while executing. */
1707 cpu.asregs.insts += insts; /* instructions done ... */
1708 cpu.asregs.cycles += insts; /* and each takes a cycle */
1709 cpu.asregs.cycles += bonus_cycles; /* and extra cycles for branches */
1710 cpu.asregs.cycles += memops * memcycles; /* and memop cycle delays */
1712 signal (SIGINT, sigsave);
1717 sim_write (sd, addr, buffer, size)
1720 unsigned char * buffer;
1726 memcpy (& cpu.mem[addr], buffer, size);
1732 sim_read (sd, addr, buffer, size)
1735 unsigned char * buffer;
1741 memcpy (buffer, & cpu.mem[addr], size);
1748 sim_store_register (sd, rn, memory, length)
1751 unsigned char * memory;
1756 if (rn < NUM_MCORE_REGS && rn >= 0)
1762 /* misalignment safe */
1763 ival = mcore_extract_unsigned_integer (memory, 4);
1764 cpu.asints[rn] = ival;
1774 sim_fetch_register (sd, rn, memory, length)
1777 unsigned char * memory;
1782 if (rn < NUM_MCORE_REGS && rn >= 0)
1786 long ival = cpu.asints[rn];
1788 /* misalignment-safe */
1789 mcore_store_unsigned_integer (memory, 4, ival);
1805 sim_resume (sd, 0, 0);
1813 sim_stop_reason (sd, reason, sigrc)
1815 enum sim_stop * reason;
1818 if (cpu.asregs.exception == SIGQUIT)
1820 * reason = sim_exited;
1821 * sigrc = cpu.gr[PARM1];
1825 * reason = sim_stopped;
1826 * sigrc = cpu.asregs.exception;
1835 cpu.asregs.exception = SIGINT;
1841 sim_info (sd, verbose)
1845 #ifdef WATCHFUNCTIONS
1848 double virttime = cpu.asregs.cycles / 36.0e6;
1850 callback->printf_filtered (callback, "\n\n# instructions executed %10d\n",
1852 callback->printf_filtered (callback, "# cycles %10d\n",
1854 callback->printf_filtered (callback, "# pipeline stalls %10d\n",
1856 callback->printf_filtered (callback, "# virtual time taken %10.4f\n",
1859 #ifdef WATCHFUNCTIONS
1860 callback->printf_filtered (callback, "\nNumber of watched functions: %d\n",
1865 for (w = 1; w <= ENDWL; w++)
1867 callback->printf_filtered (callback, "WL = %s %8x\n",WLstr[w],WL[w]);
1868 callback->printf_filtered (callback, " calls = %d, cycles = %d\n",
1869 WLcnts[w],WLcyc[w]);
1872 callback->printf_filtered (callback,
1873 " maxcpc = %d, mincpc = %d, avecpc = %d\n",
1874 WLmax[w],WLmin[w],WLcyc[w]/WLcnts[w]);
1878 callback->printf_filtered (callback,
1879 "Total cycles for watched functions: %d\n",wcyc);
1885 unsigned char sa_machtype[2];
1886 unsigned char sa_magic[2];
1887 unsigned char sa_tsize[4];
1888 unsigned char sa_dsize[4];
1889 unsigned char sa_bsize[4];
1890 unsigned char sa_syms[4];
1891 unsigned char sa_entry[4];
1892 unsigned char sa_trelo[4];
1893 unsigned char sa_drelo[4];
1896 #define LONG(x) (((x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
1897 #define SHORT(x) (((x)[0]<<8)|(x)[1])
1900 sim_open (kind, cb, abfd, argv)
1906 int osize = sim_memory_size;
1910 if (kind == SIM_OPEN_STANDALONE)
1913 /* Discard and reacquire memory -- start with a clean slate. */
1914 sim_size (1); /* small */
1915 sim_size (osize); /* and back again */
1917 set_initial_gprs (); /* Reset the GPR registers. */
1919 /* Fudge our descriptor for now. */
1920 return (SIM_DESC) 1;
1924 sim_close (sd, quitting)
1932 sim_load (sd, prog, abfd, from_tty)
1938 /* Do the right thing for ELF executables; this turns out to be
1939 just about the right thing for any object format that:
1940 - we crack using BFD routines
1941 - follows the traditional UNIX text/data/bss layout
1942 - calls the bss section ".bss". */
1944 extern bfd * sim_load_file (); /* ??? Don't know where this should live. */
1950 handle = bfd_openr (prog, 0); /* could be "mcore" */
1954 printf("``%s'' could not be opened.\n", prog);
1958 /* Makes sure that we have an object file, also cleans gets the
1959 section headers in place. */
1960 if (!bfd_check_format (handle, bfd_object))
1962 /* wasn't an object file */
1964 printf ("``%s'' is not appropriate object file.\n", prog);
1968 /* Look for that bss section. */
1969 s_bss = bfd_get_section_by_name (handle, ".bss");
1973 printf("``%s'' has no bss section.\n", prog);
1977 /* Appropriately paranoid would check that we have
1978 a traditional text/data/bss ordering within memory. */
1980 /* figure the end of the bss section */
1982 printf ("bss section at 0x%08x for 0x%08x bytes\n",
1983 (unsigned long) bfd_get_section_vma (handle, s_bss),
1984 (unsigned long) bfd_section_size (handle, s_bss));
1986 heap_ptr = ((unsigned long) bfd_get_section_vma (handle, s_bss)
1987 + (unsigned long) bfd_section_size (handle, s_bss));
1989 /* Clean up after ourselves. */
1992 /* XXX: do we need to free the s_bss and handle structures? */
1995 /* from sh -- dac */
1996 prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
1997 sim_kind == SIM_OPEN_DEBUG,
1999 if (prog_bfd == NULL)
2002 target_big_endian = bfd_big_endian (prog_bfd);
2005 bfd_close (prog_bfd);
2011 sim_create_inferior (sd, prog_bfd, argv, env)
2013 struct bfd * prog_bfd;
2022 unsigned long strings;
2023 unsigned long pointers;
2024 unsigned long hi_stack;
2027 /* Set the initial register set. */
2030 set_initial_gprs ();
2033 hi_stack = cpu.asregs.msize - 4;
2034 cpu.asregs.pc = bfd_get_start_address (prog_bfd);
2036 /* Calculate the argument and environment strings. */
2042 l = strlen (*avp) + 1; /* include the null */
2043 s_length += (l + 3) & ~3; /* make it a 4 byte boundary */
2051 l = strlen (*avp) + 1; /* include the null */
2052 s_length += (l + 3) & ~ 3;/* make it a 4 byte boundary */
2056 /* Claim some memory for the pointers and strings. */
2057 pointers = hi_stack - sizeof(word) * (nenv+1+nargs+1);
2058 pointers &= ~3; /* must be 4-byte aligned */
2059 cpu.gr[0] = pointers;
2061 strings = cpu.gr[0] - s_length;
2062 strings &= ~3; /* want to make it 4-byte aligned */
2063 cpu.gr[0] = strings;
2064 /* dac fix, the stack address must be 8-byte aligned! */
2065 cpu.gr[0] = cpu.gr[0] - cpu.gr[0] % 8;
2067 /* Loop through the arguments and fill them in. */
2068 cpu.gr[PARM1] = nargs;
2071 /* No strings to fill in. */
2076 cpu.gr[PARM2] = pointers;
2080 /* Save where we're putting it. */
2081 wlat (pointers, strings);
2083 /* Copy the string. */
2084 l = strlen (* avp) + 1;
2085 strcpy ((char *)(cpu.mem + strings), *avp);
2087 /* Bump the pointers. */
2093 /* A null to finish the list. */
2098 /* Now do the environment pointers. */
2101 /* No strings to fill in. */
2106 cpu.gr[PARM3] = pointers;
2111 /* Save where we're putting it. */
2112 wlat (pointers, strings);
2114 /* Copy the string. */
2115 l = strlen (* avp) + 1;
2116 strcpy ((char *)(cpu.mem + strings), *avp);
2118 /* Bump the pointers. */
2124 /* A null to finish the list. */
2140 sim_do_command (sd, cmd)
2144 /* Nothing there yet; it's all an error. */
2148 char ** simargv = buildargv (cmd);
2150 if (strcmp (simargv[0], "watch") == 0)
2152 if ((simargv[1] == NULL) || (simargv[2] == NULL))
2154 fprintf (stderr, "Error: missing argument to watch cmd.\n");
2160 WL[ENDWL] = strtol (simargv[2], NULL, 0);
2161 WLstr[ENDWL] = strdup (simargv[1]);
2162 fprintf (stderr, "Added %s (%x) to watchlist, #%d\n",WLstr[ENDWL],
2166 else if (strcmp (simargv[0], "dumpmem") == 0)
2171 if (simargv[1] == NULL)
2172 fprintf (stderr, "Error: missing argument to dumpmem cmd.\n");
2174 fprintf (stderr, "Writing dumpfile %s...",simargv[1]);
2176 dumpfile = fopen (simargv[1], "w");
2178 fwrite (p, cpu.asregs.msize-1, 1, dumpfile);
2181 fprintf (stderr, "done.\n");
2183 else if (strcmp (simargv[0], "clearstats") == 0)
2185 cpu.asregs.cycles = 0;
2186 cpu.asregs.insts = 0;
2187 cpu.asregs.stalls = 0;
2190 else if (strcmp (simargv[0], "verbose") == 0)
2196 fprintf (stderr,"Error: \"%s\" is not a valid M.CORE simulator command.\n",
2202 fprintf (stderr, "M.CORE sim commands: \n");
2203 fprintf (stderr, " watch <funcname> <addr>\n");
2204 fprintf (stderr, " dumpmem <filename>\n");
2205 fprintf (stderr, " clearstats\n");
2206 fprintf (stderr, " verbose\n");
2211 sim_set_callbacks (ptr)
2212 host_callback * ptr;