1 /* Simulator for the moxie processor
2 Copyright (C) 2008, 2009 Free Software Foundation, Inc.
3 Contributed by Anthony Green
5 This file is part of GDB, the GNU debugger.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
23 #include <sys/times.h>
24 #include <sys/param.h>
25 #include <netinet/in.h> /* for byte ordering macros */
27 #include "gdb/callback.h"
28 #include "libiberty.h"
29 #include "gdb/remote-sim.h"
32 typedef unsigned int uword;
34 host_callback * callback;
38 /* Extract the signed 10-bit offset from a 16-bit branch
40 #define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
42 #define EXTRACT_WORD(addr) (((addr)[0] << 24) \
48 moxie_extract_unsigned_integer (addr, len)
54 unsigned char * startaddr = (unsigned char *)addr;
55 unsigned char * endaddr = startaddr + len;
57 if (len > (int) sizeof (unsigned long))
58 printf ("That operation is not available on integers of more than %d bytes.",
59 sizeof (unsigned long));
61 /* Start at the most significant end of the integer, and work towards
62 the least significant. */
65 for (p = endaddr; p > startaddr;)
66 retval = (retval << 8) | * -- p;
72 moxie_store_unsigned_integer (addr, len, val)
78 unsigned char * startaddr = (unsigned char *)addr;
79 unsigned char * endaddr = startaddr + len;
81 for (p = endaddr; p > startaddr;)
88 /* moxie register names. */
89 static const char *reg_names[16] =
90 { "$fp", "$sp", "$r0", "$r1", "$r2", "$r3", "$r4", "$r5",
91 "$r6", "$r7", "$r8", "$r9", "$r10", "$r11", "$r12", "$r13" };
95 This state is maintained in host byte order. The fetch/store
96 register functions must translate between host byte order and the
97 target processor byte order. Keeping this data in target byte
98 order simplifies the register read/write functions. Keeping this
99 data in native order improves the performance of the simulator.
100 Simulation speed is deemed more important. */
102 #define NUM_MOXIE_REGS 17 /* Including PC */
103 #define NUM_MOXIE_SREGS 256 /* The special registers */
106 /* The ordering of the moxie_regset structure is matched in the
107 gdb/config/moxie/tm-moxie.h file in the REGISTER_NAMES macro. */
110 word regs[NUM_MOXIE_REGS + 1]; /* primary registers */
111 word sregs[256]; /* special registers */
112 word cc; /* the condition code reg */
115 unsigned char * memory;
116 unsigned long long insts; /* instruction counter */
127 struct moxie_regset asregs;
128 word asints [1]; /* but accessed larger... */
132 static SIM_OPEN_KIND sim_kind;
133 static int issue_messages = 0;
135 /* Default to a 8 Mbyte (== 2^23) memory space. */
136 static int sim_memory_size = 23;
138 #define MEM_SIZE_FLOOR 64
143 sim_memory_size = power;
144 cpu.asregs.msize = 1 << sim_memory_size;
146 if (cpu.asregs.memory)
147 free (cpu.asregs.memory);
149 /* Watch out for the '0 count' problem. There's probably a better
150 way.. e.g., why do we use 64 here? */
151 if (cpu.asregs.msize < 64) /* Ensure a boundary. */
152 cpu.asregs.memory = (unsigned char *) calloc (64, (64 + cpu.asregs.msize) / 64);
154 cpu.asregs.memory = (unsigned char *) calloc (64, cpu.asregs.msize / 64);
156 if (!cpu.asregs.memory)
160 "Not enough VM for simulation of %d bytes of RAM\n",
163 cpu.asregs.msize = 1;
164 cpu.asregs.memory = (unsigned char *) calloc (1, 1);
171 if (cpu.asregs.msize != (1 << sim_memory_size))
172 sim_size (sim_memory_size);
181 unsigned long memsize;
185 /* Set up machine just out of reset. */
186 cpu.asregs.regs[PC_REGNO] = 0;
188 memsize = cpu.asregs.msize / (1024 * 1024);
190 if (issue_messages > 1)
191 fprintf (stderr, "Simulated memory of %d Mbytes (0x0 .. 0x%08x)\n",
192 memsize, cpu.asregs.msize - 1);
194 /* Clean out the register contents. */
195 for (i = 0; i < NUM_MOXIE_REGS; i++)
196 cpu.asregs.regs[i] = 0;
197 for (i = 0; i < NUM_MOXIE_SREGS; i++)
198 cpu.asregs.sregs[i] = 0;
204 cpu.asregs.exception = SIGINT;
207 /* Write a 1 byte value to memory. */
213 if (((uword)x) >= cpu.asregs.msize)
216 fprintf (stderr, "byte write to 0x%x outside memory range\n", x);
218 cpu.asregs.exception = SIGSEGV;
223 unsigned char * p = cpu.asregs.memory + x;
229 /* Write a 2 byte value to memory. */
235 if (((uword)x) >= cpu.asregs.msize)
238 fprintf (stderr, "short word write to 0x%x outside memory range\n", x);
240 cpu.asregs.exception = SIGSEGV;
247 fprintf (stderr, "short word write to unaligned memory address: 0x%x\n", x);
249 cpu.asregs.exception = SIGBUS;
252 unsigned char * p = cpu.asregs.memory + x;
259 /* Write a 4 byte value to memory. */
265 if (((uword)x) >= cpu.asregs.msize)
268 fprintf (stderr, "word write to 0x%x outside memory range\n", x);
270 cpu.asregs.exception = SIGSEGV;
277 fprintf (stderr, "word write to unaligned memory address: 0x%x\n", x);
279 cpu.asregs.exception = SIGBUS;
282 unsigned char * p = cpu.asregs.memory + x;
291 /* Read 2 bytes from memory. */
297 if (((uword) x) >= cpu.asregs.msize)
300 fprintf (stderr, "short word read from 0x%x outside memory range\n", x);
302 cpu.asregs.exception = SIGSEGV;
310 fprintf (stderr, "short word read from unaligned address: 0x%x\n", x);
312 cpu.asregs.exception = SIGBUS;
316 unsigned char * p = cpu.asregs.memory + x;
317 return (p[0] << 8) | p[1];
322 /* Read 1 byte from memory. */
328 if (((uword) x) >= cpu.asregs.msize)
331 fprintf (stderr, "byte read from 0x%x outside memory range\n", x);
333 cpu.asregs.exception = SIGSEGV;
338 unsigned char * p = cpu.asregs.memory + x;
343 /* Read 4 bytes from memory. */
349 if (((uword) x) >= cpu.asregs.msize)
352 fprintf (stderr, "word read from 0x%x outside memory range\n", x);
354 cpu.asregs.exception = SIGSEGV;
362 fprintf (stderr, "word read from unaligned address: 0x%x\n", x);
364 cpu.asregs.exception = SIGBUS;
368 unsigned char * p = cpu.asregs.memory + x;
369 return (EXTRACT_WORD(p));
374 #define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; }
377 convert_target_flags (unsigned int tflags)
379 unsigned int hflags = 0x0;
381 CHECK_FLAG(0x0001, O_WRONLY);
382 CHECK_FLAG(0x0002, O_RDWR);
383 CHECK_FLAG(0x0008, O_APPEND);
384 CHECK_FLAG(0x0200, O_CREAT);
385 CHECK_FLAG(0x0400, O_TRUNC);
386 CHECK_FLAG(0x0800, O_EXCL);
387 CHECK_FLAG(0x2000, O_SYNC);
391 "Simulator Error: problem converting target open flags for host. 0x%x\n",
397 #define TRACE(str) if (tracing) fprintf(tracefile,"0x%08x, %s, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", opc, str, cpu.asregs.regs[0], cpu.asregs.regs[1], cpu.asregs.regs[2], cpu.asregs.regs[3], cpu.asregs.regs[4], cpu.asregs.regs[5], cpu.asregs.regs[6], cpu.asregs.regs[7], cpu.asregs.regs[8], cpu.asregs.regs[9], cpu.asregs.regs[10], cpu.asregs.regs[11], cpu.asregs.regs[12], cpu.asregs.regs[13], cpu.asregs.regs[14], cpu.asregs.regs[15]);
399 static int tracing = 0;
402 sim_resume (sd, step, siggnal)
407 unsigned long long insts;
411 sigsave = signal (SIGINT, interrupt);
412 cpu.asregs.exception = step ? SIGTRAP: 0;
413 pc = cpu.asregs.regs[PC_REGNO];
414 insts = cpu.asregs.insts;
415 unsigned char *memory = cpu.asregs.memory;
417 /* Run instructions here. */
422 /* Fetch the instruction at pc. */
423 inst = (memory[pc] << 8) + memory[pc + 1];
425 /* Decode instruction. */
426 if (inst & (1 << 15))
428 if (inst & (1 << 14))
430 /* This is a Form 3 instruction. */
431 int opcode = (inst >> 10 & 0xf);
438 if (cpu.asregs.cc & CC_EQ)
439 pc += INST2OFFSET(inst) - 2;
445 if (! (cpu.asregs.cc & CC_EQ))
446 pc += INST2OFFSET(inst) - 2;
452 if (cpu.asregs.cc & CC_LT)
453 pc += INST2OFFSET(inst) - 2;
458 if (cpu.asregs.cc & CC_GT)
459 pc += INST2OFFSET(inst) - 2;
462 case 0x04: /* bltu */
465 if (cpu.asregs.cc & CC_LTU)
466 pc += INST2OFFSET(inst) - 2;
469 case 0x05: /* bgtu */
472 if (cpu.asregs.cc & CC_GTU)
473 pc += INST2OFFSET(inst) - 2;
479 if (cpu.asregs.cc & (CC_GT | CC_EQ))
480 pc += INST2OFFSET(inst) - 2;
486 if (cpu.asregs.cc & (CC_LT | CC_EQ))
487 pc += INST2OFFSET(inst) - 2;
490 case 0x08: /* bgeu */
493 if (cpu.asregs.cc & (CC_GTU | CC_EQ))
494 pc += INST2OFFSET(inst) - 2;
497 case 0x09: /* bleu */
500 if (cpu.asregs.cc & (CC_LTU | CC_EQ))
501 pc += INST2OFFSET(inst) - 2;
507 cpu.asregs.exception = SIGILL;
514 /* This is a Form 2 instruction. */
515 int opcode = (inst >> 12 & 0x3);
520 int a = (inst >> 8) & 0xf;
521 unsigned av = cpu.asregs.regs[a];
522 unsigned v = (inst & 0xff);
524 cpu.asregs.regs[a] = av + v;
529 int a = (inst >> 8) & 0xf;
530 unsigned av = cpu.asregs.regs[a];
531 unsigned v = (inst & 0xff);
533 cpu.asregs.regs[a] = av - v;
538 int a = (inst >> 8) & 0xf;
539 unsigned v = (inst & 0xff);
541 cpu.asregs.regs[a] = cpu.asregs.sregs[v];
546 int a = (inst >> 8) & 0xf;
547 unsigned v = (inst & 0xff);
549 cpu.asregs.sregs[v] = cpu.asregs.regs[a];
554 cpu.asregs.exception = SIGILL;
561 /* This is a Form 1 instruction. */
562 int opcode = inst >> 8;
567 case 0x01: /* ldi.l (immediate) */
569 int reg = (inst >> 4) & 0xf;
571 unsigned int val = EXTRACT_WORD(&(memory[pc + 2]));
572 cpu.asregs.regs[reg] = val;
576 case 0x02: /* mov (register-to-register) */
578 int dest = (inst >> 4) & 0xf;
579 int src = (inst ) & 0xf;
581 cpu.asregs.regs[dest] = cpu.asregs.regs[src];
584 case 0x03: /* jsra */
586 unsigned int fn = EXTRACT_WORD(&(memory[pc + 2]));
587 unsigned int sp = cpu.asregs.regs[1];
589 /* Save a slot for the static chain. */
592 /* Push the return address. */
594 wlat (opc, sp, pc + 6);
596 /* Push the current frame pointer. */
598 wlat (opc, sp, cpu.asregs.regs[0]);
600 /* Uncache the stack pointer and set the pc and $fp. */
601 cpu.asregs.regs[1] = sp;
602 cpu.asregs.regs[0] = sp;
608 unsigned int sp = cpu.asregs.regs[0];
612 /* Pop the frame pointer. */
613 cpu.asregs.regs[0] = rlat (opc, sp);
616 /* Pop the return address. */
617 pc = rlat (opc, sp) - 2;
620 /* Skip over the static chain slot. */
623 /* Uncache the stack pointer. */
624 cpu.asregs.regs[1] = sp;
627 case 0x05: /* add.l */
629 int a = (inst >> 4) & 0xf;
631 unsigned av = cpu.asregs.regs[a];
632 unsigned bv = cpu.asregs.regs[b];
634 cpu.asregs.regs[a] = av + bv;
637 case 0x06: /* push */
639 int a = (inst >> 4) & 0xf;
641 int sp = cpu.asregs.regs[a] - 4;
643 wlat (opc, sp, cpu.asregs.regs[b]);
644 cpu.asregs.regs[a] = sp;
649 int a = (inst >> 4) & 0xf;
651 int sp = cpu.asregs.regs[a];
653 cpu.asregs.regs[b] = rlat (opc, sp);
654 cpu.asregs.regs[a] = sp + 4;
657 case 0x08: /* lda.l */
659 int reg = (inst >> 4) & 0xf;
660 unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
662 cpu.asregs.regs[reg] = rlat (opc, addr);
666 case 0x09: /* sta.l */
668 int reg = (inst >> 4) & 0xf;
669 unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
671 wlat (opc, addr, cpu.asregs.regs[reg]);
675 case 0x0a: /* ld.l (register indirect) */
677 int src = inst & 0xf;
678 int dest = (inst >> 4) & 0xf;
681 xv = cpu.asregs.regs[src];
682 cpu.asregs.regs[dest] = rlat (opc, xv);
685 case 0x0b: /* st.l */
687 int dest = (inst >> 4) & 0xf;
688 int val = inst & 0xf;
690 wlat (opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
693 case 0x0c: /* ldo.l */
695 unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
696 int a = (inst >> 4) & 0xf;
699 addr += cpu.asregs.regs[b];
700 cpu.asregs.regs[a] = rlat(opc, addr);
704 case 0x0d: /* sto.l */
706 unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
707 int a = (inst >> 4) & 0xf;
710 addr += cpu.asregs.regs[a];
711 wlat(opc, addr, cpu.asregs.regs[b]);
717 int a = (inst >> 4) & 0xf;
720 int va = cpu.asregs.regs[a];
721 int vb = cpu.asregs.regs[b];
729 cc |= (va < vb ? CC_LT : 0);
730 cc |= (va > vb ? CC_GT : 0);
731 cc |= ((unsigned int) va < (unsigned int) vb ? CC_LTU : 0);
732 cc |= ((unsigned int) va > (unsigned int) vb ? CC_GTU : 0);
751 cpu.asregs.exception = SIGILL;
756 unsigned int fn = cpu.asregs.regs[(inst >> 4) & 0xf];
757 unsigned int sp = cpu.asregs.regs[1];
761 /* Save a slot for the static chain. */
764 /* Push the return address. */
766 wlat (opc, sp, pc + 2);
768 /* Push the current frame pointer. */
770 wlat (opc, sp, cpu.asregs.regs[0]);
772 /* Uncache the stack pointer and set the fp & pc. */
773 cpu.asregs.regs[1] = sp;
774 cpu.asregs.regs[0] = sp;
778 case 0x1a: /* jmpa */
780 unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
785 case 0x1b: /* ldi.b (immediate) */
787 int reg = (inst >> 4) & 0xf;
789 unsigned int val = EXTRACT_WORD(&(memory[pc + 2]));
791 cpu.asregs.regs[reg] = val;
795 case 0x1c: /* ld.b (register indirect) */
797 int src = inst & 0xf;
798 int dest = (inst >> 4) & 0xf;
801 xv = cpu.asregs.regs[src];
802 cpu.asregs.regs[dest] = rbat (opc, xv);
805 case 0x1d: /* lda.b */
807 int reg = (inst >> 4) & 0xf;
808 unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
810 cpu.asregs.regs[reg] = rbat (opc, addr);
814 case 0x1e: /* st.b */
816 int dest = (inst >> 4) & 0xf;
817 int val = inst & 0xf;
819 wbat (opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
822 case 0x1f: /* sta.b */
824 int reg = (inst >> 4) & 0xf;
825 unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
827 wbat (opc, addr, cpu.asregs.regs[reg]);
831 case 0x20: /* ldi.s (immediate) */
833 int reg = (inst >> 4) & 0xf;
835 unsigned int val = EXTRACT_WORD(&(memory[pc + 2]));
837 cpu.asregs.regs[reg] = val;
841 case 0x21: /* ld.s (register indirect) */
843 int src = inst & 0xf;
844 int dest = (inst >> 4) & 0xf;
847 xv = cpu.asregs.regs[src];
848 cpu.asregs.regs[dest] = rsat (opc, xv);
851 case 0x22: /* lda.s */
853 int reg = (inst >> 4) & 0xf;
854 unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
856 cpu.asregs.regs[reg] = rsat (opc, addr);
860 case 0x23: /* st.s */
862 int dest = (inst >> 4) & 0xf;
863 int val = inst & 0xf;
865 wsat (opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
868 case 0x24: /* sta.s */
870 int reg = (inst >> 4) & 0xf;
871 unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
873 wsat (opc, addr, cpu.asregs.regs[reg]);
879 int reg = (inst >> 4) & 0xf;
881 pc = cpu.asregs.regs[reg] - 2;
886 int a = (inst >> 4) & 0xf;
890 av = cpu.asregs.regs[a];
891 bv = cpu.asregs.regs[b];
892 cpu.asregs.regs[a] = av & bv;
895 case 0x27: /* lshr */
897 int a = (inst >> 4) & 0xf;
899 int av = cpu.asregs.regs[a];
900 int bv = cpu.asregs.regs[b];
902 cpu.asregs.regs[a] = (unsigned) ((unsigned) av >> bv);
905 case 0x28: /* ashl */
907 int a = (inst >> 4) & 0xf;
909 int av = cpu.asregs.regs[a];
910 int bv = cpu.asregs.regs[b];
912 cpu.asregs.regs[a] = av << bv;
915 case 0x29: /* sub.l */
917 int a = (inst >> 4) & 0xf;
919 unsigned av = cpu.asregs.regs[a];
920 unsigned bv = cpu.asregs.regs[b];
922 cpu.asregs.regs[a] = av - bv;
927 int a = (inst >> 4) & 0xf;
929 int bv = cpu.asregs.regs[b];
931 cpu.asregs.regs[a] = - bv;
936 int a = (inst >> 4) & 0xf;
940 av = cpu.asregs.regs[a];
941 bv = cpu.asregs.regs[b];
942 cpu.asregs.regs[a] = av | bv;
947 int a = (inst >> 4) & 0xf;
949 int bv = cpu.asregs.regs[b];
951 cpu.asregs.regs[a] = 0xffffffff ^ bv;
954 case 0x2d: /* ashr */
956 int a = (inst >> 4) & 0xf;
958 int av = cpu.asregs.regs[a];
959 int bv = cpu.asregs.regs[b];
961 cpu.asregs.regs[a] = av >> bv;
966 int a = (inst >> 4) & 0xf;
970 av = cpu.asregs.regs[a];
971 bv = cpu.asregs.regs[b];
972 cpu.asregs.regs[a] = av ^ bv;
975 case 0x2f: /* mul.l */
977 int a = (inst >> 4) & 0xf;
979 unsigned av = cpu.asregs.regs[a];
980 unsigned bv = cpu.asregs.regs[b];
982 cpu.asregs.regs[a] = av * bv;
987 unsigned int inum = EXTRACT_WORD(&memory[pc+2]);
991 case 0x1: /* SYS_exit */
993 cpu.asregs.exception = SIGQUIT;
996 case 0x2: /* SYS_open */
998 char *fname = &memory[cpu.asregs.regs[2]];
999 int mode = (int) convert_target_flags ((unsigned) cpu.asregs.regs[3]);
1000 /* Permission bits are at 0x12($fp) */
1001 int perm = (int) EXTRACT_WORD(&memory[cpu.asregs.regs[0] + 20]);
1002 int fd = open (fname, mode, perm);
1004 fprintf(stderr, "open(\"%s\", 0x%x, 0x%x) = %d\n", fname, mode, perm, fd);
1006 /* FIXME - set errno */
1007 cpu.asregs.regs[2] = fd;
1010 case 0x4: /* SYS_read */
1012 int fd = cpu.asregs.regs[2];
1013 char *buf = &memory[cpu.asregs.regs[3]];
1014 /* String length is at 0x12($fp) */
1015 unsigned len = EXTRACT_WORD(&memory[cpu.asregs.regs[0] + 20]);
1016 cpu.asregs.regs[2] = read (fd, buf, len);
1019 case 0x5: /* SYS_write */
1021 char *str = &memory[cpu.asregs.regs[3]];
1022 /* String length is at 0x12($fp) */
1023 unsigned count, len = EXTRACT_WORD(&memory[cpu.asregs.regs[0] + 20]);
1024 count = write (cpu.asregs.regs[2], str, len);
1025 cpu.asregs.regs[2] = count;
1034 case 0x31: /* div.l */
1036 int a = (inst >> 4) & 0xf;
1038 int av = cpu.asregs.regs[a];
1039 int bv = cpu.asregs.regs[b];
1041 cpu.asregs.regs[a] = av / bv;
1044 case 0x32: /* udiv.l */
1046 int a = (inst >> 4) & 0xf;
1048 unsigned int av = cpu.asregs.regs[a];
1049 unsigned int bv = cpu.asregs.regs[b];
1051 cpu.asregs.regs[a] = (av / bv);
1054 case 0x33: /* mod.l */
1056 int a = (inst >> 4) & 0xf;
1058 int av = cpu.asregs.regs[a];
1059 int bv = cpu.asregs.regs[b];
1061 cpu.asregs.regs[a] = av % bv;
1064 case 0x34: /* umod.l */
1066 int a = (inst >> 4) & 0xf;
1068 unsigned int av = cpu.asregs.regs[a];
1069 unsigned int bv = cpu.asregs.regs[b];
1071 cpu.asregs.regs[a] = (av % bv);
1074 case 0x35: /* brk */
1076 cpu.asregs.exception = SIGTRAP;
1077 pc -= 2; /* Adjust pc */
1079 case 0x36: /* ldo.b */
1081 unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
1082 int a = (inst >> 4) & 0xf;
1085 addr += cpu.asregs.regs[b];
1086 cpu.asregs.regs[a] = rbat(opc, addr);
1090 case 0x37: /* sto.b */
1092 unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
1093 int a = (inst >> 4) & 0xf;
1096 addr += cpu.asregs.regs[a];
1097 wbat(opc, addr, cpu.asregs.regs[b]);
1101 case 0x38: /* ldo.s */
1103 unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
1104 int a = (inst >> 4) & 0xf;
1107 addr += cpu.asregs.regs[b];
1108 cpu.asregs.regs[a] = rsat(opc, addr);
1112 case 0x39: /* sto.s */
1114 unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
1115 int a = (inst >> 4) & 0xf;
1118 addr += cpu.asregs.regs[a];
1119 wsat(opc, addr, cpu.asregs.regs[b]);
1126 cpu.asregs.exception = SIGILL;
1134 } while (!cpu.asregs.exception);
1136 /* Hide away the things we've cached while executing. */
1137 cpu.asregs.regs[PC_REGNO] = pc;
1138 cpu.asregs.insts += insts; /* instructions done ... */
1140 signal (SIGINT, sigsave);
1144 sim_write (sd, addr, buffer, size)
1147 unsigned char * buffer;
1153 memcpy (& cpu.asregs.memory[addr], buffer, size);
1159 sim_read (sd, addr, buffer, size)
1162 unsigned char * buffer;
1168 memcpy (buffer, & cpu.asregs.memory[addr], size);
1175 sim_store_register (sd, rn, memory, length)
1178 unsigned char * memory;
1183 if (rn < NUM_MOXIE_REGS && rn >= 0)
1189 /* misalignment safe */
1190 ival = moxie_extract_unsigned_integer (memory, 4);
1191 cpu.asints[rn] = ival;
1201 sim_fetch_register (sd, rn, memory, length)
1204 unsigned char * memory;
1209 if (rn < NUM_MOXIE_REGS && rn >= 0)
1213 long ival = cpu.asints[rn];
1215 /* misalignment-safe */
1216 moxie_store_unsigned_integer (memory, 4, ival);
1231 tracefile = fopen("trace.csv", "wb");
1235 sim_resume (sd, 0, 0);
1243 sim_stop_reason (sd, reason, sigrc)
1245 enum sim_stop * reason;
1248 if (cpu.asregs.exception == SIGQUIT)
1250 * reason = sim_exited;
1251 * sigrc = cpu.asregs.regs[2];
1255 * reason = sim_stopped;
1256 * sigrc = cpu.asregs.exception;
1265 cpu.asregs.exception = SIGINT;
1271 sim_info (sd, verbose)
1275 callback->printf_filtered (callback, "\n\n# instructions executed %llu\n",
1281 sim_open (kind, cb, abfd, argv)
1287 int osize = sim_memory_size;
1291 if (kind == SIM_OPEN_STANDALONE)
1294 /* Discard and reacquire memory -- start with a clean slate. */
1295 sim_size (1); /* small */
1296 sim_size (osize); /* and back again */
1298 set_initial_gprs (); /* Reset the GPR registers. */
1300 /* Fudge our descriptor for now. */
1301 return (SIM_DESC) 1;
1305 sim_close (sd, quitting)
1313 sim_load (sd, prog, abfd, from_tty)
1320 /* Do the right thing for ELF executables; this turns out to be
1321 just about the right thing for any object format that:
1322 - we crack using BFD routines
1323 - follows the traditional UNIX text/data/bss layout
1324 - calls the bss section ".bss". */
1326 extern bfd * sim_load_file (); /* ??? Don't know where this should live. */
1331 handle = bfd_openr (prog, 0); /* could be "moxie" */
1335 printf("``%s'' could not be opened.\n", prog);
1339 /* Makes sure that we have an object file, also cleans gets the
1340 section headers in place. */
1341 if (!bfd_check_format (handle, bfd_object))
1343 /* wasn't an object file */
1345 printf ("``%s'' is not appropriate object file.\n", prog);
1349 /* Clean up after ourselves. */
1353 /* from sh -- dac */
1354 prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
1355 sim_kind == SIM_OPEN_DEBUG,
1357 if (prog_bfd == NULL)
1361 bfd_close (prog_bfd);
1367 sim_create_inferior (sd, prog_bfd, argv, env)
1369 struct bfd * prog_bfd;
1376 /* Set the initial register set. */
1379 set_initial_gprs ();
1382 cpu.asregs.regs[PC_REGNO] = bfd_get_start_address (prog_bfd);
1384 /* Copy args into target memory. */
1386 for (argc = 0; *avp; avp++)
1389 /* Target memory looks like this:
1390 0x00000000 zero word
1391 0x00000004 argc word
1392 0x00000008 start of argv
1394 0x0000???? end of argv
1395 0x0000???? zero word
1396 0x0000???? start of data pointed to by argv */
1401 /* tp is the offset of our first argv data. */
1402 tp = 4 + 4 + argc * 4 + 4;
1404 for (i = 0; i < argc; i++)
1406 /* Set the argv value. */
1407 wlat (0, 4 + 4 + i * 4, tp);
1409 /* Store the string. */
1410 strcpy (&cpu.asregs.memory[tp], argv[i]);
1411 tp += strlen (argv[i]) + 1;
1414 wlat (0, 4 + 4 + i * 4, 0);
1428 sim_do_command (sd, cmd)
1432 /* Nothing there yet; it's all an error. */
1436 char ** simargv = buildargv (cmd);
1437 if (strcmp (simargv[0], "verbose") == 0)
1443 fprintf (stderr,"Error: \"%s\" is not a valid moxie simulator command.\n",
1449 fprintf (stderr, "moxie sim commands: \n");
1450 fprintf (stderr, " verbose\n");
1455 sim_set_callbacks (ptr)
1456 host_callback * ptr;