dd87648b5ff7730fb3eb2bd052b8582d0ef9f2d7
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 #define EXTRACT_WORD(addr) (((addr)[0] << 24) \
44 moxie_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 for (p
= endaddr
; p
> startaddr
;)
62 retval
= (retval
<< 8) | * -- p
;
68 moxie_store_unsigned_integer (addr
, len
, val
)
74 unsigned char * startaddr
= (unsigned char *)addr
;
75 unsigned char * endaddr
= startaddr
+ len
;
77 for (p
= endaddr
; p
> startaddr
;)
84 /* moxie register names. */
85 static const char *reg_names
[16] =
86 { "$fp", "$sp", "$r0", "$r1", "$r2", "$r3", "$r4", "$r5",
87 "$r6", "$r7", "$r8", "$r9", "$r10", "$r11", "$r12", "$r13" };
91 This state is maintained in host byte order. The fetch/store
92 register functions must translate between host byte order and the
93 target processor byte order. Keeping this data in target byte
94 order simplifies the register read/write functions. Keeping this
95 data in native order improves the performance of the simulator.
96 Simulation speed is deemed more important. */
98 #define NUM_MOXIE_REGS 17 /* Including PC */
99 #define NUM_MOXIE_SREGS 256 /* The special registers */
102 /* The ordering of the moxie_regset structure is matched in the
103 gdb/config/moxie/tm-moxie.h file in the REGISTER_NAMES macro. */
106 word regs
[NUM_MOXIE_REGS
+ 1]; /* primary registers */
107 word sregs
[256]; /* special registers */
108 word cc
; /* the condition code reg */
111 unsigned char * memory
;
112 unsigned long long insts
; /* instruction counter */
123 struct moxie_regset asregs
;
124 word asints
[1]; /* but accessed larger... */
128 static SIM_OPEN_KIND sim_kind
;
129 static int issue_messages
= 0;
131 /* Default to a 8 Mbyte (== 2^23) memory space. */
132 static int sim_memory_size
= 23;
134 #define MEM_SIZE_FLOOR 64
139 sim_memory_size
= power
;
140 cpu
.asregs
.msize
= 1 << sim_memory_size
;
142 if (cpu
.asregs
.memory
)
143 free (cpu
.asregs
.memory
);
145 /* Watch out for the '0 count' problem. There's probably a better
146 way.. e.g., why do we use 64 here? */
147 if (cpu
.asregs
.msize
< 64) /* Ensure a boundary. */
148 cpu
.asregs
.memory
= (unsigned char *) calloc (64, (64 + cpu
.asregs
.msize
) / 64);
150 cpu
.asregs
.memory
= (unsigned char *) calloc (64, cpu
.asregs
.msize
/ 64);
152 if (!cpu
.asregs
.memory
)
156 "Not enough VM for simulation of %d bytes of RAM\n",
159 cpu
.asregs
.msize
= 1;
160 cpu
.asregs
.memory
= (unsigned char *) calloc (1, 1);
167 if (cpu
.asregs
.msize
!= (1 << sim_memory_size
))
168 sim_size (sim_memory_size
);
177 unsigned long memsize
;
181 /* Set up machine just out of reset. */
182 cpu
.asregs
.regs
[PC_REGNO
] = 0;
184 memsize
= cpu
.asregs
.msize
/ (1024 * 1024);
186 if (issue_messages
> 1)
187 fprintf (stderr
, "Simulated memory of %d Mbytes (0x0 .. 0x%08x)\n",
188 memsize
, cpu
.asregs
.msize
- 1);
190 /* Clean out the register contents. */
191 for (i
= 0; i
< NUM_MOXIE_REGS
; i
++)
192 cpu
.asregs
.regs
[i
] = 0;
193 for (i
= 0; i
< NUM_MOXIE_SREGS
; i
++)
194 cpu
.asregs
.sregs
[i
] = 0;
200 cpu
.asregs
.exception
= SIGINT
;
203 /* Write a 1 byte value to memory. */
209 if (((uword
)x
) >= cpu
.asregs
.msize
)
212 fprintf (stderr
, "byte write to 0x%x outside memory range\n", x
);
214 cpu
.asregs
.exception
= SIGSEGV
;
219 unsigned char * p
= cpu
.asregs
.memory
+ x
;
225 /* Write a 2 byte value to memory. */
231 if (((uword
)x
) >= cpu
.asregs
.msize
)
234 fprintf (stderr
, "short word write to 0x%x outside memory range\n", x
);
236 cpu
.asregs
.exception
= SIGSEGV
;
243 fprintf (stderr
, "short word write to unaligned memory address: 0x%x\n", x
);
245 cpu
.asregs
.exception
= SIGBUS
;
248 unsigned char * p
= cpu
.asregs
.memory
+ x
;
255 /* Write a 4 byte value to memory. */
261 if (((uword
)x
) >= cpu
.asregs
.msize
)
264 fprintf (stderr
, "word write to 0x%x outside memory range\n", x
);
266 cpu
.asregs
.exception
= SIGSEGV
;
273 fprintf (stderr
, "word write to unaligned memory address: 0x%x\n", x
);
275 cpu
.asregs
.exception
= SIGBUS
;
278 unsigned char * p
= cpu
.asregs
.memory
+ x
;
287 /* Read 2 bytes from memory. */
293 if (((uword
) x
) >= cpu
.asregs
.msize
)
296 fprintf (stderr
, "short word read from 0x%x outside memory range\n", x
);
298 cpu
.asregs
.exception
= SIGSEGV
;
306 fprintf (stderr
, "short word read from unaligned address: 0x%x\n", x
);
308 cpu
.asregs
.exception
= SIGBUS
;
312 unsigned char * p
= cpu
.asregs
.memory
+ x
;
313 return (p
[0] << 8) | p
[1];
318 /* Read 1 byte from memory. */
324 if (((uword
) x
) >= cpu
.asregs
.msize
)
327 fprintf (stderr
, "byte read from 0x%x outside memory range\n", x
);
329 cpu
.asregs
.exception
= SIGSEGV
;
334 unsigned char * p
= cpu
.asregs
.memory
+ x
;
339 /* Read 4 bytes from memory. */
345 if (((uword
) x
) >= cpu
.asregs
.msize
)
348 fprintf (stderr
, "word read from 0x%x outside memory range\n", x
);
350 cpu
.asregs
.exception
= SIGSEGV
;
358 fprintf (stderr
, "word read from unaligned address: 0x%x\n", x
);
360 cpu
.asregs
.exception
= SIGBUS
;
364 unsigned char * p
= cpu
.asregs
.memory
+ x
;
365 return (EXTRACT_WORD(p
));
370 #define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; }
373 convert_target_flags (unsigned int tflags
)
375 unsigned int hflags
= 0x0;
377 CHECK_FLAG(0x0001, O_WRONLY
);
378 CHECK_FLAG(0x0002, O_RDWR
);
379 CHECK_FLAG(0x0008, O_APPEND
);
380 CHECK_FLAG(0x0200, O_CREAT
);
381 CHECK_FLAG(0x0400, O_TRUNC
);
382 CHECK_FLAG(0x0800, O_EXCL
);
383 CHECK_FLAG(0x2000, O_SYNC
);
387 "Simulator Error: problem converting target open flags for host. 0x%x\n",
393 #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]);
395 static int tracing
= 0;
398 sim_resume (sd
, step
, siggnal
)
403 unsigned long long insts
;
407 sigsave
= signal (SIGINT
, interrupt
);
408 cpu
.asregs
.exception
= step
? SIGTRAP
: 0;
409 pc
= cpu
.asregs
.regs
[PC_REGNO
];
410 insts
= cpu
.asregs
.insts
;
411 unsigned char *memory
= cpu
.asregs
.memory
;
413 /* Run instructions here. */
418 /* Fetch the instruction at pc. */
419 inst
= (memory
[pc
] << 8) + memory
[pc
+ 1];
421 /* Decode instruction. */
422 if (inst
& (1 << 15))
424 if (inst
& (1 << 14))
426 /* This is a Form 3 instruction. */
427 /* We haven't implemented any yet, so just SIGILL for now. */
429 cpu
.asregs
.exception
= SIGILL
;
434 /* This is a Form 2 instruction. */
435 int opcode
= (inst
>> 12 & 0x3);
440 int a
= (inst
>> 8) & 0xf;
441 unsigned av
= cpu
.asregs
.regs
[a
];
442 unsigned v
= (inst
& 0xff);
444 cpu
.asregs
.regs
[a
] = av
+ v
;
449 int a
= (inst
>> 8) & 0xf;
450 unsigned av
= cpu
.asregs
.regs
[a
];
451 unsigned v
= (inst
& 0xff);
453 cpu
.asregs
.regs
[a
] = av
- v
;
458 int a
= (inst
>> 8) & 0xf;
459 unsigned v
= (inst
& 0xff);
461 cpu
.asregs
.regs
[a
] = cpu
.asregs
.sregs
[v
];
466 int a
= (inst
>> 8) & 0xf;
467 unsigned v
= (inst
& 0xff);
469 cpu
.asregs
.sregs
[v
] = cpu
.asregs
.regs
[a
];
474 cpu
.asregs
.exception
= SIGILL
;
481 /* This is a Form 1 instruction. */
482 int opcode
= inst
>> 8;
487 case 0x01: /* ldi.l (immediate) */
489 int reg
= (inst
>> 4) & 0xf;
491 unsigned int val
= EXTRACT_WORD(&(memory
[pc
+ 2]));
492 cpu
.asregs
.regs
[reg
] = val
;
496 case 0x02: /* mov (register-to-register) */
498 int dest
= (inst
>> 4) & 0xf;
499 int src
= (inst
) & 0xf;
501 cpu
.asregs
.regs
[dest
] = cpu
.asregs
.regs
[src
];
504 case 0x03: /* jsra */
506 unsigned int fn
= EXTRACT_WORD(&(memory
[pc
+ 2]));
507 unsigned int sp
= cpu
.asregs
.regs
[1];
509 /* Save a slot for the static chain. */
512 /* Push the return address. */
514 wlat (opc
, sp
, pc
+ 6);
516 /* Push the current frame pointer. */
518 wlat (opc
, sp
, cpu
.asregs
.regs
[0]);
520 /* Uncache the stack pointer and set the pc and $fp. */
521 cpu
.asregs
.regs
[1] = sp
;
522 cpu
.asregs
.regs
[0] = sp
;
528 unsigned int sp
= cpu
.asregs
.regs
[0];
532 /* Pop the frame pointer. */
533 cpu
.asregs
.regs
[0] = rlat (opc
, sp
);
536 /* Pop the return address. */
537 pc
= rlat (opc
, sp
) - 2;
540 /* Skip over the static chain slot. */
543 /* Uncache the stack pointer. */
544 cpu
.asregs
.regs
[1] = sp
;
547 case 0x05: /* add.l */
549 int a
= (inst
>> 4) & 0xf;
551 unsigned av
= cpu
.asregs
.regs
[a
];
552 unsigned bv
= cpu
.asregs
.regs
[b
];
554 cpu
.asregs
.regs
[a
] = av
+ bv
;
557 case 0x06: /* push */
559 int a
= (inst
>> 4) & 0xf;
561 int sp
= cpu
.asregs
.regs
[a
] - 4;
563 wlat (opc
, sp
, cpu
.asregs
.regs
[b
]);
564 cpu
.asregs
.regs
[a
] = sp
;
569 int a
= (inst
>> 4) & 0xf;
571 int sp
= cpu
.asregs
.regs
[a
];
573 cpu
.asregs
.regs
[b
] = rlat (opc
, sp
);
574 cpu
.asregs
.regs
[a
] = sp
+ 4;
577 case 0x08: /* lda.l */
579 int reg
= (inst
>> 4) & 0xf;
580 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
582 cpu
.asregs
.regs
[reg
] = rlat (opc
, addr
);
586 case 0x09: /* sta.l */
588 int reg
= (inst
>> 4) & 0xf;
589 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
591 wlat (opc
, addr
, cpu
.asregs
.regs
[reg
]);
595 case 0x0a: /* ld.l (register indirect) */
597 int src
= inst
& 0xf;
598 int dest
= (inst
>> 4) & 0xf;
601 xv
= cpu
.asregs
.regs
[src
];
602 cpu
.asregs
.regs
[dest
] = rlat (opc
, xv
);
605 case 0x0b: /* st.l */
607 int dest
= (inst
>> 4) & 0xf;
608 int val
= inst
& 0xf;
610 wlat (opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
613 case 0x0c: /* ldo.l */
615 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
616 int a
= (inst
>> 4) & 0xf;
619 addr
+= cpu
.asregs
.regs
[b
];
620 cpu
.asregs
.regs
[a
] = rlat(opc
, addr
);
624 case 0x0d: /* sto.l */
626 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
627 int a
= (inst
>> 4) & 0xf;
630 addr
+= cpu
.asregs
.regs
[a
];
631 wlat(opc
, addr
, cpu
.asregs
.regs
[b
]);
637 int a
= (inst
>> 4) & 0xf;
640 int va
= cpu
.asregs
.regs
[a
];
641 int vb
= cpu
.asregs
.regs
[b
];
649 cc
|= (va
< vb
? CC_LT
: 0);
650 cc
|= (va
> vb
? CC_GT
: 0);
651 cc
|= ((unsigned int) va
< (unsigned int) vb
? CC_LTU
: 0);
652 cc
|= ((unsigned int) va
> (unsigned int) vb
? CC_GTU
: 0);
660 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
662 if (cpu
.asregs
.cc
& CC_EQ
)
672 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
674 if (! (cpu
.asregs
.cc
& CC_EQ
))
684 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
686 if (cpu
.asregs
.cc
& CC_LT
)
696 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
698 if (cpu
.asregs
.cc
& CC_GT
)
706 case 0x13: /* bltu */
708 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
710 if (cpu
.asregs
.cc
& CC_LTU
)
718 case 0x14: /* bgtu */
720 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
722 if (cpu
.asregs
.cc
& CC_GTU
)
732 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
734 if ((cpu
.asregs
.cc
& CC_GT
) || (cpu
.asregs
.cc
& CC_EQ
))
744 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
746 if ((cpu
.asregs
.cc
& CC_LT
) || (cpu
.asregs
.cc
& CC_EQ
))
754 case 0x17: /* bgeu */
756 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
758 if ((cpu
.asregs
.cc
& CC_GTU
) || (cpu
.asregs
.cc
& CC_EQ
))
766 case 0x18: /* bleu */
768 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
770 if ((cpu
.asregs
.cc
& CC_LTU
) || (cpu
.asregs
.cc
& CC_EQ
))
780 unsigned int fn
= cpu
.asregs
.regs
[(inst
>> 4) & 0xf];
781 unsigned int sp
= cpu
.asregs
.regs
[1];
785 /* Save a slot for the static chain. */
788 /* Push the return address. */
790 wlat (opc
, sp
, pc
+ 2);
792 /* Push the current frame pointer. */
794 wlat (opc
, sp
, cpu
.asregs
.regs
[0]);
796 /* Uncache the stack pointer and set the fp & pc. */
797 cpu
.asregs
.regs
[1] = sp
;
798 cpu
.asregs
.regs
[0] = sp
;
802 case 0x1a: /* jmpa */
804 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
809 case 0x1b: /* ldi.b (immediate) */
811 int reg
= (inst
>> 4) & 0xf;
813 unsigned int val
= EXTRACT_WORD(&(memory
[pc
+ 2]));
815 cpu
.asregs
.regs
[reg
] = val
;
819 case 0x1c: /* ld.b (register indirect) */
821 int src
= inst
& 0xf;
822 int dest
= (inst
>> 4) & 0xf;
825 xv
= cpu
.asregs
.regs
[src
];
826 cpu
.asregs
.regs
[dest
] = rbat (opc
, xv
);
829 case 0x1d: /* lda.b */
831 int reg
= (inst
>> 4) & 0xf;
832 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
834 cpu
.asregs
.regs
[reg
] = rbat (opc
, addr
);
838 case 0x1e: /* st.b */
840 int dest
= (inst
>> 4) & 0xf;
841 int val
= inst
& 0xf;
843 wbat (opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
846 case 0x1f: /* sta.b */
848 int reg
= (inst
>> 4) & 0xf;
849 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
851 wbat (opc
, addr
, cpu
.asregs
.regs
[reg
]);
855 case 0x20: /* ldi.s (immediate) */
857 int reg
= (inst
>> 4) & 0xf;
859 unsigned int val
= EXTRACT_WORD(&(memory
[pc
+ 2]));
861 cpu
.asregs
.regs
[reg
] = val
;
865 case 0x21: /* ld.s (register indirect) */
867 int src
= inst
& 0xf;
868 int dest
= (inst
>> 4) & 0xf;
871 xv
= cpu
.asregs
.regs
[src
];
872 cpu
.asregs
.regs
[dest
] = rsat (opc
, xv
);
875 case 0x22: /* lda.s */
877 int reg
= (inst
>> 4) & 0xf;
878 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
880 cpu
.asregs
.regs
[reg
] = rsat (opc
, addr
);
884 case 0x23: /* st.s */
886 int dest
= (inst
>> 4) & 0xf;
887 int val
= inst
& 0xf;
889 wsat (opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
892 case 0x24: /* sta.s */
894 int reg
= (inst
>> 4) & 0xf;
895 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
897 wsat (opc
, addr
, cpu
.asregs
.regs
[reg
]);
903 int reg
= (inst
>> 4) & 0xf;
905 pc
= cpu
.asregs
.regs
[reg
] - 2;
910 int a
= (inst
>> 4) & 0xf;
914 av
= cpu
.asregs
.regs
[a
];
915 bv
= cpu
.asregs
.regs
[b
];
916 cpu
.asregs
.regs
[a
] = av
& bv
;
919 case 0x27: /* lshr */
921 int a
= (inst
>> 4) & 0xf;
923 int av
= cpu
.asregs
.regs
[a
];
924 int bv
= cpu
.asregs
.regs
[b
];
926 cpu
.asregs
.regs
[a
] = (unsigned) ((unsigned) av
>> bv
);
929 case 0x28: /* ashl */
931 int a
= (inst
>> 4) & 0xf;
933 int av
= cpu
.asregs
.regs
[a
];
934 int bv
= cpu
.asregs
.regs
[b
];
936 cpu
.asregs
.regs
[a
] = av
<< bv
;
939 case 0x29: /* sub.l */
941 int a
= (inst
>> 4) & 0xf;
943 unsigned av
= cpu
.asregs
.regs
[a
];
944 unsigned bv
= cpu
.asregs
.regs
[b
];
946 cpu
.asregs
.regs
[a
] = av
- bv
;
951 int a
= (inst
>> 4) & 0xf;
953 int bv
= cpu
.asregs
.regs
[b
];
955 cpu
.asregs
.regs
[a
] = - bv
;
960 int a
= (inst
>> 4) & 0xf;
964 av
= cpu
.asregs
.regs
[a
];
965 bv
= cpu
.asregs
.regs
[b
];
966 cpu
.asregs
.regs
[a
] = av
| bv
;
971 int a
= (inst
>> 4) & 0xf;
973 int bv
= cpu
.asregs
.regs
[b
];
975 cpu
.asregs
.regs
[a
] = 0xffffffff ^ bv
;
978 case 0x2d: /* ashr */
980 int a
= (inst
>> 4) & 0xf;
982 int av
= cpu
.asregs
.regs
[a
];
983 int bv
= cpu
.asregs
.regs
[b
];
985 cpu
.asregs
.regs
[a
] = av
>> bv
;
990 int a
= (inst
>> 4) & 0xf;
994 av
= cpu
.asregs
.regs
[a
];
995 bv
= cpu
.asregs
.regs
[b
];
996 cpu
.asregs
.regs
[a
] = av
^ bv
;
999 case 0x2f: /* mul.l */
1001 int a
= (inst
>> 4) & 0xf;
1003 unsigned av
= cpu
.asregs
.regs
[a
];
1004 unsigned bv
= cpu
.asregs
.regs
[b
];
1006 cpu
.asregs
.regs
[a
] = av
* bv
;
1009 case 0x30: /* swi */
1011 unsigned int inum
= EXTRACT_WORD(&memory
[pc
+2]);
1015 case 0x1: /* SYS_exit */
1017 cpu
.asregs
.exception
= SIGQUIT
;
1020 case 0x2: /* SYS_open */
1022 char *fname
= &memory
[cpu
.asregs
.regs
[2]];
1023 int mode
= (int) convert_target_flags ((unsigned) cpu
.asregs
.regs
[3]);
1024 /* Permission bits are at 0x12($fp) */
1025 int perm
= (int) EXTRACT_WORD(&memory
[cpu
.asregs
.regs
[0] + 20]);
1026 int fd
= open (fname
, mode
, perm
);
1028 fprintf(stderr
, "open(\"%s\", 0x%x, 0x%x) = %d\n", fname
, mode
, perm
, fd
);
1030 /* FIXME - set errno */
1031 cpu
.asregs
.regs
[2] = fd
;
1034 case 0x4: /* SYS_read */
1036 int fd
= cpu
.asregs
.regs
[2];
1037 char *buf
= &memory
[cpu
.asregs
.regs
[3]];
1038 /* String length is at 0x12($fp) */
1039 unsigned len
= EXTRACT_WORD(&memory
[cpu
.asregs
.regs
[0] + 20]);
1040 cpu
.asregs
.regs
[2] = read (fd
, buf
, len
);
1043 case 0x5: /* SYS_write */
1045 char *str
= &memory
[cpu
.asregs
.regs
[3]];
1046 /* String length is at 0x12($fp) */
1047 unsigned count
, len
= EXTRACT_WORD(&memory
[cpu
.asregs
.regs
[0] + 20]);
1048 count
= write (cpu
.asregs
.regs
[2], str
, len
);
1049 cpu
.asregs
.regs
[2] = count
;
1058 case 0x31: /* div.l */
1060 int a
= (inst
>> 4) & 0xf;
1062 int av
= cpu
.asregs
.regs
[a
];
1063 int bv
= cpu
.asregs
.regs
[b
];
1065 cpu
.asregs
.regs
[a
] = av
/ bv
;
1068 case 0x32: /* udiv.l */
1070 int a
= (inst
>> 4) & 0xf;
1072 unsigned int av
= cpu
.asregs
.regs
[a
];
1073 unsigned int bv
= cpu
.asregs
.regs
[b
];
1075 cpu
.asregs
.regs
[a
] = (av
/ bv
);
1078 case 0x33: /* mod.l */
1080 int a
= (inst
>> 4) & 0xf;
1082 int av
= cpu
.asregs
.regs
[a
];
1083 int bv
= cpu
.asregs
.regs
[b
];
1085 cpu
.asregs
.regs
[a
] = av
% bv
;
1088 case 0x34: /* umod.l */
1090 int a
= (inst
>> 4) & 0xf;
1092 unsigned int av
= cpu
.asregs
.regs
[a
];
1093 unsigned int bv
= cpu
.asregs
.regs
[b
];
1095 cpu
.asregs
.regs
[a
] = (av
% bv
);
1098 case 0x35: /* brk */
1100 cpu
.asregs
.exception
= SIGTRAP
;
1101 pc
-= 2; /* Adjust pc */
1103 case 0x36: /* ldo.b */
1105 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
1106 int a
= (inst
>> 4) & 0xf;
1109 addr
+= cpu
.asregs
.regs
[b
];
1110 cpu
.asregs
.regs
[a
] = rbat(opc
, addr
);
1114 case 0x37: /* sto.b */
1116 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
1117 int a
= (inst
>> 4) & 0xf;
1120 addr
+= cpu
.asregs
.regs
[a
];
1121 wbat(opc
, addr
, cpu
.asregs
.regs
[b
]);
1125 case 0x38: /* ldo.s */
1127 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
1128 int a
= (inst
>> 4) & 0xf;
1131 addr
+= cpu
.asregs
.regs
[b
];
1132 cpu
.asregs
.regs
[a
] = rsat(opc
, addr
);
1136 case 0x39: /* sto.s */
1138 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
1139 int a
= (inst
>> 4) & 0xf;
1142 addr
+= cpu
.asregs
.regs
[a
];
1143 wsat(opc
, addr
, cpu
.asregs
.regs
[b
]);
1150 cpu
.asregs
.exception
= SIGILL
;
1158 } while (!cpu
.asregs
.exception
);
1160 /* Hide away the things we've cached while executing. */
1161 cpu
.asregs
.regs
[PC_REGNO
] = pc
;
1162 cpu
.asregs
.insts
+= insts
; /* instructions done ... */
1164 signal (SIGINT
, sigsave
);
1168 sim_write (sd
, addr
, buffer
, size
)
1171 unsigned char * buffer
;
1177 memcpy (& cpu
.asregs
.memory
[addr
], buffer
, size
);
1183 sim_read (sd
, addr
, buffer
, size
)
1186 unsigned char * buffer
;
1192 memcpy (buffer
, & cpu
.asregs
.memory
[addr
], size
);
1199 sim_store_register (sd
, rn
, memory
, length
)
1202 unsigned char * memory
;
1207 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1213 /* misalignment safe */
1214 ival
= moxie_extract_unsigned_integer (memory
, 4);
1215 cpu
.asints
[rn
] = ival
;
1225 sim_fetch_register (sd
, rn
, memory
, length
)
1228 unsigned char * memory
;
1233 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1237 long ival
= cpu
.asints
[rn
];
1239 /* misalignment-safe */
1240 moxie_store_unsigned_integer (memory
, 4, ival
);
1255 tracefile
= fopen("trace.csv", "wb");
1259 sim_resume (sd
, 0, 0);
1267 sim_stop_reason (sd
, reason
, sigrc
)
1269 enum sim_stop
* reason
;
1272 if (cpu
.asregs
.exception
== SIGQUIT
)
1274 * reason
= sim_exited
;
1275 * sigrc
= cpu
.asregs
.regs
[2];
1279 * reason
= sim_stopped
;
1280 * sigrc
= cpu
.asregs
.exception
;
1289 cpu
.asregs
.exception
= SIGINT
;
1295 sim_info (sd
, verbose
)
1299 callback
->printf_filtered (callback
, "\n\n# instructions executed %llu\n",
1305 sim_open (kind
, cb
, abfd
, argv
)
1311 int osize
= sim_memory_size
;
1315 if (kind
== SIM_OPEN_STANDALONE
)
1318 /* Discard and reacquire memory -- start with a clean slate. */
1319 sim_size (1); /* small */
1320 sim_size (osize
); /* and back again */
1322 set_initial_gprs (); /* Reset the GPR registers. */
1324 /* Fudge our descriptor for now. */
1325 return (SIM_DESC
) 1;
1329 sim_close (sd
, quitting
)
1337 sim_load (sd
, prog
, abfd
, from_tty
)
1344 /* Do the right thing for ELF executables; this turns out to be
1345 just about the right thing for any object format that:
1346 - we crack using BFD routines
1347 - follows the traditional UNIX text/data/bss layout
1348 - calls the bss section ".bss". */
1350 extern bfd
* sim_load_file (); /* ??? Don't know where this should live. */
1355 handle
= bfd_openr (prog
, 0); /* could be "moxie" */
1359 printf("``%s'' could not be opened.\n", prog
);
1363 /* Makes sure that we have an object file, also cleans gets the
1364 section headers in place. */
1365 if (!bfd_check_format (handle
, bfd_object
))
1367 /* wasn't an object file */
1369 printf ("``%s'' is not appropriate object file.\n", prog
);
1373 /* Clean up after ourselves. */
1377 /* from sh -- dac */
1378 prog_bfd
= sim_load_file (sd
, myname
, callback
, prog
, abfd
,
1379 sim_kind
== SIM_OPEN_DEBUG
,
1381 if (prog_bfd
== NULL
)
1385 bfd_close (prog_bfd
);
1391 sim_create_inferior (sd
, prog_bfd
, argv
, env
)
1393 struct bfd
* prog_bfd
;
1400 /* Set the initial register set. */
1403 set_initial_gprs ();
1406 cpu
.asregs
.regs
[PC_REGNO
] = bfd_get_start_address (prog_bfd
);
1408 /* Copy args into target memory. */
1410 for (argc
= 0; *avp
; avp
++)
1413 /* Target memory looks like this:
1414 0x00000000 zero word
1415 0x00000004 argc word
1416 0x00000008 start of argv
1418 0x0000???? end of argv
1419 0x0000???? zero word
1420 0x0000???? start of data pointed to by argv */
1425 /* tp is the offset of our first argv data. */
1426 tp
= 4 + 4 + argc
* 4 + 4;
1428 for (i
= 0; i
< argc
; i
++)
1430 /* Set the argv value. */
1431 wlat (0, 4 + 4 + i
* 4, tp
);
1433 /* Store the string. */
1434 strcpy (&cpu
.asregs
.memory
[tp
], argv
[i
]);
1435 tp
+= strlen (argv
[i
]) + 1;
1438 wlat (0, 4 + 4 + i
* 4, 0);
1452 sim_do_command (sd
, cmd
)
1456 /* Nothing there yet; it's all an error. */
1460 char ** simargv
= buildargv (cmd
);
1461 if (strcmp (simargv
[0], "verbose") == 0)
1467 fprintf (stderr
,"Error: \"%s\" is not a valid moxie simulator command.\n",
1473 fprintf (stderr
, "moxie sim commands: \n");
1474 fprintf (stderr
, " verbose\n");
1479 sim_set_callbacks (ptr
)
1480 host_callback
* ptr
;
This page took 0.063473 seconds and 3 git commands to generate.