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
];
465 int a
= (inst
>> 8) & 0xf;
466 unsigned v
= (inst
& 0xff);
468 cpu
.asregs
.sregs
[v
] = cpu
.asregs
.regs
[a
];
472 cpu
.asregs
.exception
= SIGILL
;
479 /* This is a Form 1 instruction. */
480 int opcode
= inst
>> 8;
485 case 0x01: /* ldi.l (immediate) */
487 int reg
= (inst
>> 4) & 0xf;
489 unsigned int val
= EXTRACT_WORD(&(memory
[pc
+ 2]));
490 cpu
.asregs
.regs
[reg
] = val
;
494 case 0x02: /* mov (register-to-register) */
496 int dest
= (inst
>> 4) & 0xf;
497 int src
= (inst
) & 0xf;
499 cpu
.asregs
.regs
[dest
] = cpu
.asregs
.regs
[src
];
502 case 0x03: /* jsra */
504 unsigned int fn
= EXTRACT_WORD(&(memory
[pc
+ 2]));
505 unsigned int sp
= cpu
.asregs
.regs
[1];
507 /* Save a slot for the static chain. */
510 /* Push the return address. */
512 wlat (opc
, sp
, pc
+ 6);
514 /* Push the current frame pointer. */
516 wlat (opc
, sp
, cpu
.asregs
.regs
[0]);
518 /* Uncache the stack pointer and set the pc and $fp. */
519 cpu
.asregs
.regs
[1] = sp
;
520 cpu
.asregs
.regs
[0] = sp
;
526 unsigned int sp
= cpu
.asregs
.regs
[0];
530 /* Pop the frame pointer. */
531 cpu
.asregs
.regs
[0] = rlat (opc
, sp
);
534 /* Pop the return address. */
535 pc
= rlat (opc
, sp
) - 2;
538 /* Skip over the static chain slot. */
541 /* Uncache the stack pointer. */
542 cpu
.asregs
.regs
[1] = sp
;
545 case 0x05: /* add.l */
547 int a
= (inst
>> 4) & 0xf;
549 unsigned av
= cpu
.asregs
.regs
[a
];
550 unsigned bv
= cpu
.asregs
.regs
[b
];
552 cpu
.asregs
.regs
[a
] = av
+ bv
;
555 case 0x06: /* push */
557 int a
= (inst
>> 4) & 0xf;
559 int sp
= cpu
.asregs
.regs
[a
] - 4;
561 wlat (opc
, sp
, cpu
.asregs
.regs
[b
]);
562 cpu
.asregs
.regs
[a
] = sp
;
567 int a
= (inst
>> 4) & 0xf;
569 int sp
= cpu
.asregs
.regs
[a
];
571 cpu
.asregs
.regs
[b
] = rlat (opc
, sp
);
572 cpu
.asregs
.regs
[a
] = sp
+ 4;
575 case 0x08: /* lda.l */
577 int reg
= (inst
>> 4) & 0xf;
578 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
580 cpu
.asregs
.regs
[reg
] = rlat (opc
, addr
);
584 case 0x09: /* sta.l */
586 int reg
= (inst
>> 4) & 0xf;
587 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
589 wlat (opc
, addr
, cpu
.asregs
.regs
[reg
]);
593 case 0x0a: /* ld.l (register indirect) */
595 int src
= inst
& 0xf;
596 int dest
= (inst
>> 4) & 0xf;
599 xv
= cpu
.asregs
.regs
[src
];
600 cpu
.asregs
.regs
[dest
] = rlat (opc
, xv
);
603 case 0x0b: /* st.l */
605 int dest
= (inst
>> 4) & 0xf;
606 int val
= inst
& 0xf;
608 wlat (opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
611 case 0x0c: /* ldo.l */
613 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
614 int a
= (inst
>> 4) & 0xf;
617 addr
+= cpu
.asregs
.regs
[b
];
618 cpu
.asregs
.regs
[a
] = rlat(opc
, addr
);
622 case 0x0d: /* sto.l */
624 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
625 int a
= (inst
>> 4) & 0xf;
628 addr
+= cpu
.asregs
.regs
[a
];
629 wlat(opc
, addr
, cpu
.asregs
.regs
[b
]);
635 int a
= (inst
>> 4) & 0xf;
638 int va
= cpu
.asregs
.regs
[a
];
639 int vb
= cpu
.asregs
.regs
[b
];
647 cc
|= (va
< vb
? CC_LT
: 0);
648 cc
|= (va
> vb
? CC_GT
: 0);
649 cc
|= ((unsigned int) va
< (unsigned int) vb
? CC_LTU
: 0);
650 cc
|= ((unsigned int) va
> (unsigned int) vb
? CC_GTU
: 0);
658 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
660 if (cpu
.asregs
.cc
& CC_EQ
)
670 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
672 if (! (cpu
.asregs
.cc
& CC_EQ
))
682 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
684 if (cpu
.asregs
.cc
& CC_LT
)
694 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
696 if (cpu
.asregs
.cc
& CC_GT
)
704 case 0x13: /* bltu */
706 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
708 if (cpu
.asregs
.cc
& CC_LTU
)
716 case 0x14: /* bgtu */
718 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
720 if (cpu
.asregs
.cc
& CC_GTU
)
730 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
732 if ((cpu
.asregs
.cc
& CC_GT
) || (cpu
.asregs
.cc
& CC_EQ
))
742 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
744 if ((cpu
.asregs
.cc
& CC_LT
) || (cpu
.asregs
.cc
& CC_EQ
))
752 case 0x17: /* bgeu */
754 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
756 if ((cpu
.asregs
.cc
& CC_GTU
) || (cpu
.asregs
.cc
& CC_EQ
))
764 case 0x18: /* bleu */
766 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
768 if ((cpu
.asregs
.cc
& CC_LTU
) || (cpu
.asregs
.cc
& CC_EQ
))
778 unsigned int fn
= cpu
.asregs
.regs
[(inst
>> 4) & 0xf];
779 unsigned int sp
= cpu
.asregs
.regs
[1];
783 /* Save a slot for the static chain. */
786 /* Push the return address. */
788 wlat (opc
, sp
, pc
+ 2);
790 /* Push the current frame pointer. */
792 wlat (opc
, sp
, cpu
.asregs
.regs
[0]);
794 /* Uncache the stack pointer and set the fp & pc. */
795 cpu
.asregs
.regs
[1] = sp
;
796 cpu
.asregs
.regs
[0] = sp
;
800 case 0x1a: /* jmpa */
802 unsigned int tgt
= EXTRACT_WORD(&memory
[pc
+2]);
807 case 0x1b: /* ldi.b (immediate) */
809 int reg
= (inst
>> 4) & 0xf;
811 unsigned int val
= EXTRACT_WORD(&(memory
[pc
+ 2]));
813 cpu
.asregs
.regs
[reg
] = val
;
817 case 0x1c: /* ld.b (register indirect) */
819 int src
= inst
& 0xf;
820 int dest
= (inst
>> 4) & 0xf;
823 xv
= cpu
.asregs
.regs
[src
];
824 cpu
.asregs
.regs
[dest
] = rbat (opc
, xv
);
827 case 0x1d: /* lda.b */
829 int reg
= (inst
>> 4) & 0xf;
830 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
832 cpu
.asregs
.regs
[reg
] = rbat (opc
, addr
);
836 case 0x1e: /* st.b */
838 int dest
= (inst
>> 4) & 0xf;
839 int val
= inst
& 0xf;
841 wbat (opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
844 case 0x1f: /* sta.b */
846 int reg
= (inst
>> 4) & 0xf;
847 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
849 wbat (opc
, addr
, cpu
.asregs
.regs
[reg
]);
853 case 0x20: /* ldi.s (immediate) */
855 int reg
= (inst
>> 4) & 0xf;
857 unsigned int val
= EXTRACT_WORD(&(memory
[pc
+ 2]));
859 cpu
.asregs
.regs
[reg
] = val
;
863 case 0x21: /* ld.s (register indirect) */
865 int src
= inst
& 0xf;
866 int dest
= (inst
>> 4) & 0xf;
869 xv
= cpu
.asregs
.regs
[src
];
870 cpu
.asregs
.regs
[dest
] = rsat (opc
, xv
);
873 case 0x22: /* lda.s */
875 int reg
= (inst
>> 4) & 0xf;
876 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
878 cpu
.asregs
.regs
[reg
] = rsat (opc
, addr
);
882 case 0x23: /* st.s */
884 int dest
= (inst
>> 4) & 0xf;
885 int val
= inst
& 0xf;
887 wsat (opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
890 case 0x24: /* sta.s */
892 int reg
= (inst
>> 4) & 0xf;
893 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
895 wsat (opc
, addr
, cpu
.asregs
.regs
[reg
]);
901 int reg
= (inst
>> 4) & 0xf;
903 pc
= cpu
.asregs
.regs
[reg
] - 2;
908 int a
= (inst
>> 4) & 0xf;
912 av
= cpu
.asregs
.regs
[a
];
913 bv
= cpu
.asregs
.regs
[b
];
914 cpu
.asregs
.regs
[a
] = av
& bv
;
917 case 0x27: /* lshr */
919 int a
= (inst
>> 4) & 0xf;
921 int av
= cpu
.asregs
.regs
[a
];
922 int bv
= cpu
.asregs
.regs
[b
];
924 cpu
.asregs
.regs
[a
] = (unsigned) ((unsigned) av
>> bv
);
927 case 0x28: /* ashl */
929 int a
= (inst
>> 4) & 0xf;
931 int av
= cpu
.asregs
.regs
[a
];
932 int bv
= cpu
.asregs
.regs
[b
];
934 cpu
.asregs
.regs
[a
] = av
<< bv
;
937 case 0x29: /* sub.l */
939 int a
= (inst
>> 4) & 0xf;
941 unsigned av
= cpu
.asregs
.regs
[a
];
942 unsigned bv
= cpu
.asregs
.regs
[b
];
944 cpu
.asregs
.regs
[a
] = av
- bv
;
949 int a
= (inst
>> 4) & 0xf;
951 int bv
= cpu
.asregs
.regs
[b
];
953 cpu
.asregs
.regs
[a
] = - bv
;
958 int a
= (inst
>> 4) & 0xf;
962 av
= cpu
.asregs
.regs
[a
];
963 bv
= cpu
.asregs
.regs
[b
];
964 cpu
.asregs
.regs
[a
] = av
| bv
;
969 int a
= (inst
>> 4) & 0xf;
971 int bv
= cpu
.asregs
.regs
[b
];
973 cpu
.asregs
.regs
[a
] = 0xffffffff ^ bv
;
976 case 0x2d: /* ashr */
978 int a
= (inst
>> 4) & 0xf;
980 int av
= cpu
.asregs
.regs
[a
];
981 int bv
= cpu
.asregs
.regs
[b
];
983 cpu
.asregs
.regs
[a
] = av
>> bv
;
988 int a
= (inst
>> 4) & 0xf;
992 av
= cpu
.asregs
.regs
[a
];
993 bv
= cpu
.asregs
.regs
[b
];
994 cpu
.asregs
.regs
[a
] = av
^ bv
;
997 case 0x2f: /* mul.l */
999 int a
= (inst
>> 4) & 0xf;
1001 unsigned av
= cpu
.asregs
.regs
[a
];
1002 unsigned bv
= cpu
.asregs
.regs
[b
];
1004 cpu
.asregs
.regs
[a
] = av
* bv
;
1007 case 0x30: /* swi */
1009 unsigned int inum
= EXTRACT_WORD(&memory
[pc
+2]);
1013 case 0x1: /* SYS_exit */
1015 cpu
.asregs
.exception
= SIGQUIT
;
1018 case 0x2: /* SYS_open */
1020 char *fname
= &memory
[cpu
.asregs
.regs
[2]];
1021 int mode
= (int) convert_target_flags ((unsigned) cpu
.asregs
.regs
[3]);
1022 /* Permission bits are at 0x12($fp) */
1023 int perm
= (int) EXTRACT_WORD(&memory
[cpu
.asregs
.regs
[0] + 20]);
1024 int fd
= open (fname
, mode
, perm
);
1026 fprintf(stderr
, "open(\"%s\", 0x%x, 0x%x) = %d\n", fname
, mode
, perm
, fd
);
1028 /* FIXME - set errno */
1029 cpu
.asregs
.regs
[2] = fd
;
1032 case 0x4: /* SYS_read */
1034 int fd
= cpu
.asregs
.regs
[2];
1035 char *buf
= &memory
[cpu
.asregs
.regs
[3]];
1036 /* String length is at 0x12($fp) */
1037 unsigned len
= EXTRACT_WORD(&memory
[cpu
.asregs
.regs
[0] + 20]);
1038 cpu
.asregs
.regs
[2] = read (fd
, buf
, len
);
1041 case 0x5: /* SYS_write */
1043 char *str
= &memory
[cpu
.asregs
.regs
[3]];
1044 /* String length is at 0x12($fp) */
1045 unsigned count
, len
= EXTRACT_WORD(&memory
[cpu
.asregs
.regs
[0] + 20]);
1046 count
= write (cpu
.asregs
.regs
[2], str
, len
);
1047 cpu
.asregs
.regs
[2] = count
;
1056 case 0x31: /* div.l */
1058 int a
= (inst
>> 4) & 0xf;
1060 int av
= cpu
.asregs
.regs
[a
];
1061 int bv
= cpu
.asregs
.regs
[b
];
1063 cpu
.asregs
.regs
[a
] = av
/ bv
;
1066 case 0x32: /* udiv.l */
1068 int a
= (inst
>> 4) & 0xf;
1070 unsigned int av
= cpu
.asregs
.regs
[a
];
1071 unsigned int bv
= cpu
.asregs
.regs
[b
];
1073 cpu
.asregs
.regs
[a
] = (av
/ bv
);
1076 case 0x33: /* mod.l */
1078 int a
= (inst
>> 4) & 0xf;
1080 int av
= cpu
.asregs
.regs
[a
];
1081 int bv
= cpu
.asregs
.regs
[b
];
1083 cpu
.asregs
.regs
[a
] = av
% bv
;
1086 case 0x34: /* umod.l */
1088 int a
= (inst
>> 4) & 0xf;
1090 unsigned int av
= cpu
.asregs
.regs
[a
];
1091 unsigned int bv
= cpu
.asregs
.regs
[b
];
1093 cpu
.asregs
.regs
[a
] = (av
% bv
);
1096 case 0x35: /* brk */
1098 cpu
.asregs
.exception
= SIGTRAP
;
1099 pc
-= 2; /* Adjust pc */
1101 case 0x36: /* ldo.b */
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
] = rbat(opc
, addr
);
1112 case 0x37: /* sto.b */
1114 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
1115 int a
= (inst
>> 4) & 0xf;
1118 addr
+= cpu
.asregs
.regs
[a
];
1119 wbat(opc
, addr
, cpu
.asregs
.regs
[b
]);
1123 case 0x38: /* ldo.s */
1125 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
1126 int a
= (inst
>> 4) & 0xf;
1129 addr
+= cpu
.asregs
.regs
[b
];
1130 cpu
.asregs
.regs
[a
] = rsat(opc
, addr
);
1134 case 0x39: /* sto.s */
1136 unsigned int addr
= EXTRACT_WORD(&memory
[pc
+2]);
1137 int a
= (inst
>> 4) & 0xf;
1140 addr
+= cpu
.asregs
.regs
[a
];
1141 wsat(opc
, addr
, cpu
.asregs
.regs
[b
]);
1148 cpu
.asregs
.exception
= SIGILL
;
1156 } while (!cpu
.asregs
.exception
);
1158 /* Hide away the things we've cached while executing. */
1159 cpu
.asregs
.regs
[PC_REGNO
] = pc
;
1160 cpu
.asregs
.insts
+= insts
; /* instructions done ... */
1162 signal (SIGINT
, sigsave
);
1166 sim_write (sd
, addr
, buffer
, size
)
1169 unsigned char * buffer
;
1175 memcpy (& cpu
.asregs
.memory
[addr
], buffer
, size
);
1181 sim_read (sd
, addr
, buffer
, size
)
1184 unsigned char * buffer
;
1190 memcpy (buffer
, & cpu
.asregs
.memory
[addr
], size
);
1197 sim_store_register (sd
, rn
, memory
, length
)
1200 unsigned char * memory
;
1205 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1211 /* misalignment safe */
1212 ival
= moxie_extract_unsigned_integer (memory
, 4);
1213 cpu
.asints
[rn
] = ival
;
1223 sim_fetch_register (sd
, rn
, memory
, length
)
1226 unsigned char * memory
;
1231 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1235 long ival
= cpu
.asints
[rn
];
1237 /* misalignment-safe */
1238 moxie_store_unsigned_integer (memory
, 4, ival
);
1253 tracefile
= fopen("trace.csv", "wb");
1257 sim_resume (sd
, 0, 0);
1265 sim_stop_reason (sd
, reason
, sigrc
)
1267 enum sim_stop
* reason
;
1270 if (cpu
.asregs
.exception
== SIGQUIT
)
1272 * reason
= sim_exited
;
1273 * sigrc
= cpu
.asregs
.regs
[2];
1277 * reason
= sim_stopped
;
1278 * sigrc
= cpu
.asregs
.exception
;
1287 cpu
.asregs
.exception
= SIGINT
;
1293 sim_info (sd
, verbose
)
1297 callback
->printf_filtered (callback
, "\n\n# instructions executed %llu\n",
1303 sim_open (kind
, cb
, abfd
, argv
)
1309 int osize
= sim_memory_size
;
1313 if (kind
== SIM_OPEN_STANDALONE
)
1316 /* Discard and reacquire memory -- start with a clean slate. */
1317 sim_size (1); /* small */
1318 sim_size (osize
); /* and back again */
1320 set_initial_gprs (); /* Reset the GPR registers. */
1322 /* Fudge our descriptor for now. */
1323 return (SIM_DESC
) 1;
1327 sim_close (sd
, quitting
)
1335 sim_load (sd
, prog
, abfd
, from_tty
)
1342 /* Do the right thing for ELF executables; this turns out to be
1343 just about the right thing for any object format that:
1344 - we crack using BFD routines
1345 - follows the traditional UNIX text/data/bss layout
1346 - calls the bss section ".bss". */
1348 extern bfd
* sim_load_file (); /* ??? Don't know where this should live. */
1353 handle
= bfd_openr (prog
, 0); /* could be "moxie" */
1357 printf("``%s'' could not be opened.\n", prog
);
1361 /* Makes sure that we have an object file, also cleans gets the
1362 section headers in place. */
1363 if (!bfd_check_format (handle
, bfd_object
))
1365 /* wasn't an object file */
1367 printf ("``%s'' is not appropriate object file.\n", prog
);
1371 /* Clean up after ourselves. */
1375 /* from sh -- dac */
1376 prog_bfd
= sim_load_file (sd
, myname
, callback
, prog
, abfd
,
1377 sim_kind
== SIM_OPEN_DEBUG
,
1379 if (prog_bfd
== NULL
)
1383 bfd_close (prog_bfd
);
1389 sim_create_inferior (sd
, prog_bfd
, argv
, env
)
1391 struct bfd
* prog_bfd
;
1398 /* Set the initial register set. */
1401 set_initial_gprs ();
1404 cpu
.asregs
.regs
[PC_REGNO
] = bfd_get_start_address (prog_bfd
);
1406 /* Copy args into target memory. */
1408 for (argc
= 0; *avp
; avp
++)
1411 /* Target memory looks like this:
1412 0x00000000 zero word
1413 0x00000004 argc word
1414 0x00000008 start of argv
1416 0x0000???? end of argv
1417 0x0000???? zero word
1418 0x0000???? start of data pointed to by argv */
1423 /* tp is the offset of our first argv data. */
1424 tp
= 4 + 4 + argc
* 4 + 4;
1426 for (i
= 0; i
< argc
; i
++)
1428 /* Set the argv value. */
1429 wlat (0, 4 + 4 + i
* 4, tp
);
1431 /* Store the string. */
1432 strcpy (&cpu
.asregs
.memory
[tp
], argv
[i
]);
1433 tp
+= strlen (argv
[i
]) + 1;
1436 wlat (0, 4 + 4 + i
* 4, 0);
1450 sim_do_command (sd
, cmd
)
1454 /* Nothing there yet; it's all an error. */
1458 char ** simargv
= buildargv (cmd
);
1459 if (strcmp (simargv
[0], "verbose") == 0)
1465 fprintf (stderr
,"Error: \"%s\" is not a valid moxie simulator command.\n",
1471 fprintf (stderr
, "moxie sim commands: \n");
1472 fprintf (stderr
, " verbose\n");
1477 sim_set_callbacks (ptr
)
1478 host_callback
* ptr
;
This page took 0.098295 seconds and 4 git commands to generate.