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 16 Mbyte (== 2^23) memory space. */
136 static int sim_memory_size = 24;
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 int perm = (int) cpu.asregs.regs[4];
1001 int fd = open (fname, mode, perm);
1002 /* FIXME - set errno */
1003 cpu.asregs.regs[2] = fd;
1006 case 0x4: /* SYS_read */
1008 int fd = cpu.asregs.regs[2];
1009 char *buf = &memory[cpu.asregs.regs[3]];
1010 unsigned len = (unsigned) cpu.asregs.regs[4];
1011 cpu.asregs.regs[2] = read (fd, buf, len);
1014 case 0x5: /* SYS_write */
1016 char *str = &memory[cpu.asregs.regs[3]];
1017 /* String length is at 0x12($fp) */
1018 unsigned count, len = (unsigned) cpu.asregs.regs[4];
1019 count = write (cpu.asregs.regs[2], str, len);
1020 cpu.asregs.regs[2] = count;
1023 case 0xffffffff: /* Linux System Call */
1025 unsigned int handler = cpu.asregs.sregs[1];
1026 unsigned int sp = cpu.asregs.regs[1];
1027 cpu.asregs.sregs[2] = 3; /* MOXIE_EX_SWI */
1029 /* Save a slot for the static chain. */
1032 /* Push the return address. */
1034 wlat (opc, sp, pc + 6);
1036 /* Push the current frame pointer. */
1038 wlat (opc, sp, cpu.asregs.regs[0]);
1040 /* Uncache the stack pointer and set the fp & pc. */
1041 cpu.asregs.regs[1] = sp;
1042 cpu.asregs.regs[0] = sp;
1051 case 0x31: /* div.l */
1053 int a = (inst >> 4) & 0xf;
1055 int av = cpu.asregs.regs[a];
1056 int bv = cpu.asregs.regs[b];
1058 cpu.asregs.regs[a] = av / bv;
1061 case 0x32: /* udiv.l */
1063 int a = (inst >> 4) & 0xf;
1065 unsigned int av = cpu.asregs.regs[a];
1066 unsigned int bv = cpu.asregs.regs[b];
1068 cpu.asregs.regs[a] = (av / bv);
1071 case 0x33: /* mod.l */
1073 int a = (inst >> 4) & 0xf;
1075 int av = cpu.asregs.regs[a];
1076 int bv = cpu.asregs.regs[b];
1078 cpu.asregs.regs[a] = av % bv;
1081 case 0x34: /* umod.l */
1083 int a = (inst >> 4) & 0xf;
1085 unsigned int av = cpu.asregs.regs[a];
1086 unsigned int bv = cpu.asregs.regs[b];
1088 cpu.asregs.regs[a] = (av % bv);
1091 case 0x35: /* brk */
1093 cpu.asregs.exception = SIGTRAP;
1094 pc -= 2; /* Adjust pc */
1096 case 0x36: /* ldo.b */
1098 unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
1099 int a = (inst >> 4) & 0xf;
1102 addr += cpu.asregs.regs[b];
1103 cpu.asregs.regs[a] = rbat(opc, addr);
1107 case 0x37: /* sto.b */
1109 unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
1110 int a = (inst >> 4) & 0xf;
1113 addr += cpu.asregs.regs[a];
1114 wbat(opc, addr, cpu.asregs.regs[b]);
1118 case 0x38: /* ldo.s */
1120 unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
1121 int a = (inst >> 4) & 0xf;
1124 addr += cpu.asregs.regs[b];
1125 cpu.asregs.regs[a] = rsat(opc, addr);
1129 case 0x39: /* sto.s */
1131 unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
1132 int a = (inst >> 4) & 0xf;
1135 addr += cpu.asregs.regs[a];
1136 wsat(opc, addr, cpu.asregs.regs[b]);
1143 cpu.asregs.exception = SIGILL;
1151 } while (!cpu.asregs.exception);
1153 /* Hide away the things we've cached while executing. */
1154 cpu.asregs.regs[PC_REGNO] = pc;
1155 cpu.asregs.insts += insts; /* instructions done ... */
1157 signal (SIGINT, sigsave);
1161 sim_write (sd, addr, buffer, size)
1164 unsigned char * buffer;
1170 memcpy (& cpu.asregs.memory[addr], buffer, size);
1176 sim_read (sd, addr, buffer, size)
1179 unsigned char * buffer;
1185 memcpy (buffer, & cpu.asregs.memory[addr], size);
1192 sim_store_register (sd, rn, memory, length)
1195 unsigned char * memory;
1200 if (rn < NUM_MOXIE_REGS && rn >= 0)
1206 /* misalignment safe */
1207 ival = moxie_extract_unsigned_integer (memory, 4);
1208 cpu.asints[rn] = ival;
1218 sim_fetch_register (sd, rn, memory, length)
1221 unsigned char * memory;
1226 if (rn < NUM_MOXIE_REGS && rn >= 0)
1230 long ival = cpu.asints[rn];
1232 /* misalignment-safe */
1233 moxie_store_unsigned_integer (memory, 4, ival);
1248 tracefile = fopen("trace.csv", "wb");
1252 sim_resume (sd, 0, 0);
1260 sim_stop_reason (sd, reason, sigrc)
1262 enum sim_stop * reason;
1265 if (cpu.asregs.exception == SIGQUIT)
1267 * reason = sim_exited;
1268 * sigrc = cpu.asregs.regs[2];
1272 * reason = sim_stopped;
1273 * sigrc = cpu.asregs.exception;
1282 cpu.asregs.exception = SIGINT;
1288 sim_info (sd, verbose)
1292 callback->printf_filtered (callback, "\n\n# instructions executed %llu\n",
1298 sim_open (kind, cb, abfd, argv)
1304 int osize = sim_memory_size;
1308 if (kind == SIM_OPEN_STANDALONE)
1311 /* Discard and reacquire memory -- start with a clean slate. */
1312 sim_size (1); /* small */
1313 sim_size (osize); /* and back again */
1315 set_initial_gprs (); /* Reset the GPR registers. */
1317 /* Fudge our descriptor for now. */
1318 return (SIM_DESC) 1;
1322 sim_close (sd, quitting)
1330 sim_load (sd, prog, abfd, from_tty)
1337 /* Do the right thing for ELF executables; this turns out to be
1338 just about the right thing for any object format that:
1339 - we crack using BFD routines
1340 - follows the traditional UNIX text/data/bss layout
1341 - calls the bss section ".bss". */
1343 extern bfd * sim_load_file (); /* ??? Don't know where this should live. */
1348 handle = bfd_openr (prog, 0); /* could be "moxie" */
1352 printf("``%s'' could not be opened.\n", prog);
1356 /* Makes sure that we have an object file, also cleans gets the
1357 section headers in place. */
1358 if (!bfd_check_format (handle, bfd_object))
1360 /* wasn't an object file */
1362 printf ("``%s'' is not appropriate object file.\n", prog);
1366 /* Clean up after ourselves. */
1370 /* from sh -- dac */
1371 prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
1372 sim_kind == SIM_OPEN_DEBUG,
1374 if (prog_bfd == NULL)
1378 bfd_close (prog_bfd);
1384 sim_create_inferior (sd, prog_bfd, argv, env)
1386 struct bfd * prog_bfd;
1393 /* Set the initial register set. */
1396 set_initial_gprs ();
1399 cpu.asregs.regs[PC_REGNO] = bfd_get_start_address (prog_bfd);
1401 /* Copy args into target memory. */
1403 for (argc = 0; *avp; avp++)
1406 /* Target memory looks like this:
1407 0x00000000 zero word
1408 0x00000004 argc word
1409 0x00000008 start of argv
1411 0x0000???? end of argv
1412 0x0000???? zero word
1413 0x0000???? start of data pointed to by argv */
1418 /* tp is the offset of our first argv data. */
1419 tp = 4 + 4 + argc * 4 + 4;
1421 for (i = 0; i < argc; i++)
1423 /* Set the argv value. */
1424 wlat (0, 4 + 4 + i * 4, tp);
1426 /* Store the string. */
1427 strcpy (&cpu.asregs.memory[tp], argv[i]);
1428 tp += strlen (argv[i]) + 1;
1431 wlat (0, 4 + 4 + i * 4, 0);
1445 sim_do_command (sd, cmd)
1449 /* Nothing there yet; it's all an error. */
1453 char ** simargv = buildargv (cmd);
1454 if (strcmp (simargv[0], "verbose") == 0)
1460 fprintf (stderr,"Error: \"%s\" is not a valid moxie simulator command.\n",
1466 fprintf (stderr, "moxie sim commands: \n");
1467 fprintf (stderr, " verbose\n");
1472 sim_set_callbacks (ptr)
1473 host_callback * ptr;