1 /* Simulator for the moxie processor
2 Copyright (C) 2008-2014 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/>. */
25 #include <sys/times.h>
26 #include <sys/param.h>
27 #include <netinet/in.h> /* for byte ordering macros */
29 #include "gdb/callback.h"
30 #include "libiberty.h"
31 #include "gdb/remote-sim.h"
37 typedef unsigned int uword
;
39 host_callback
* callback
;
43 /* Extract the signed 10-bit offset from a 16-bit branch
45 #define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
47 #define EXTRACT_WORD(addr) \
48 ((sim_core_read_aligned_1 (scpu, cia, read_map, addr) << 24) \
49 + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+1) << 16) \
50 + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+2) << 8) \
51 + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+3)))
54 moxie_extract_unsigned_integer (addr
, len
)
60 unsigned char * startaddr
= (unsigned char *)addr
;
61 unsigned char * endaddr
= startaddr
+ len
;
63 if (len
> (int) sizeof (unsigned long))
64 printf ("That operation is not available on integers of more than %d bytes.",
65 sizeof (unsigned long));
67 /* Start at the most significant end of the integer, and work towards
68 the least significant. */
71 for (p
= endaddr
; p
> startaddr
;)
72 retval
= (retval
<< 8) | * -- p
;
78 moxie_store_unsigned_integer (addr
, len
, val
)
84 unsigned char * startaddr
= (unsigned char *)addr
;
85 unsigned char * endaddr
= startaddr
+ len
;
87 for (p
= endaddr
; p
> startaddr
;)
94 /* moxie register names. */
95 static const char *reg_names
[16] =
96 { "$fp", "$sp", "$r0", "$r1", "$r2", "$r3", "$r4", "$r5",
97 "$r6", "$r7", "$r8", "$r9", "$r10", "$r11", "$r12", "$r13" };
101 This state is maintained in host byte order. The fetch/store
102 register functions must translate between host byte order and the
103 target processor byte order. Keeping this data in target byte
104 order simplifies the register read/write functions. Keeping this
105 data in native order improves the performance of the simulator.
106 Simulation speed is deemed more important. */
108 #define NUM_MOXIE_REGS 17 /* Including PC */
109 #define NUM_MOXIE_SREGS 256 /* The special registers */
112 /* The ordering of the moxie_regset structure is matched in the
113 gdb/config/moxie/tm-moxie.h file in the REGISTER_NAMES macro. */
116 word regs
[NUM_MOXIE_REGS
+ 1]; /* primary registers */
117 word sregs
[256]; /* special registers */
118 word cc
; /* the condition code reg */
120 unsigned long long insts
; /* instruction counter */
131 struct moxie_regset asregs
;
132 word asints
[1]; /* but accessed larger... */
136 static SIM_OPEN_KIND sim_kind
;
137 static int issue_messages
= 0;
150 /* Set up machine just out of reset. */
151 cpu
.asregs
.regs
[PC_REGNO
] = 0;
153 /* Clean out the register contents. */
154 for (i
= 0; i
< NUM_MOXIE_REGS
; i
++)
155 cpu
.asregs
.regs
[i
] = 0;
156 for (i
= 0; i
< NUM_MOXIE_SREGS
; i
++)
157 cpu
.asregs
.sregs
[i
] = 0;
163 cpu
.asregs
.exception
= SIGINT
;
166 /* Write a 1 byte value to memory. */
169 wbat (sim_cpu
*scpu
, word pc
, word x
, word v
)
171 address_word cia
= CIA_GET (scpu
);
173 sim_core_write_aligned_1 (scpu
, cia
, write_map
, x
, v
);
176 /* Write a 2 byte value to memory. */
179 wsat (sim_cpu
*scpu
, word pc
, word x
, word v
)
181 address_word cia
= CIA_GET (scpu
);
183 sim_core_write_aligned_2 (scpu
, cia
, write_map
, x
, v
);
186 /* Write a 4 byte value to memory. */
189 wlat (sim_cpu
*scpu
, word pc
, word x
, word v
)
191 address_word cia
= CIA_GET (scpu
);
193 sim_core_write_aligned_4 (scpu
, cia
, write_map
, x
, v
);
196 /* Read 2 bytes from memory. */
199 rsat (sim_cpu
*scpu
, word pc
, word x
)
201 address_word cia
= CIA_GET (scpu
);
203 return (sim_core_read_aligned_2 (scpu
, cia
, read_map
, x
));
206 /* Read 1 byte from memory. */
209 rbat (sim_cpu
*scpu
, word pc
, word x
)
211 address_word cia
= CIA_GET (scpu
);
213 return (sim_core_read_aligned_1 (scpu
, cia
, read_map
, x
));
216 /* Read 4 bytes from memory. */
219 rlat (sim_cpu
*scpu
, word pc
, word x
)
221 address_word cia
= CIA_GET (scpu
);
223 return (sim_core_read_aligned_4 (scpu
, cia
, read_map
, x
));
226 #define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; }
229 convert_target_flags (unsigned int tflags
)
231 unsigned int hflags
= 0x0;
233 CHECK_FLAG(0x0001, O_WRONLY
);
234 CHECK_FLAG(0x0002, O_RDWR
);
235 CHECK_FLAG(0x0008, O_APPEND
);
236 CHECK_FLAG(0x0200, O_CREAT
);
237 CHECK_FLAG(0x0400, O_TRUNC
);
238 CHECK_FLAG(0x0800, O_EXCL
);
239 CHECK_FLAG(0x2000, O_SYNC
);
243 "Simulator Error: problem converting target open flags for host. 0x%x\n",
249 #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]);
251 static int tracing
= 0;
254 sim_resume (sd
, step
, siggnal
)
259 unsigned long long insts
;
262 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
263 address_word cia
= CIA_GET (scpu
);
265 sigsave
= signal (SIGINT
, interrupt
);
266 cpu
.asregs
.exception
= step
? SIGTRAP
: 0;
267 pc
= cpu
.asregs
.regs
[PC_REGNO
];
268 insts
= cpu
.asregs
.insts
;
270 /* Run instructions here. */
275 /* Fetch the instruction at pc. */
276 inst
= (sim_core_read_aligned_1 (scpu
, cia
, read_map
, pc
) << 8)
277 + sim_core_read_aligned_1 (scpu
, cia
, read_map
, pc
+1);
279 /* Decode instruction. */
280 if (inst
& (1 << 15))
282 if (inst
& (1 << 14))
284 /* This is a Form 3 instruction. */
285 int opcode
= (inst
>> 10 & 0xf);
292 if (cpu
.asregs
.cc
& CC_EQ
)
293 pc
+= INST2OFFSET(inst
);
299 if (! (cpu
.asregs
.cc
& CC_EQ
))
300 pc
+= INST2OFFSET(inst
);
306 if (cpu
.asregs
.cc
& CC_LT
)
307 pc
+= INST2OFFSET(inst
);
312 if (cpu
.asregs
.cc
& CC_GT
)
313 pc
+= INST2OFFSET(inst
);
316 case 0x04: /* bltu */
319 if (cpu
.asregs
.cc
& CC_LTU
)
320 pc
+= INST2OFFSET(inst
);
323 case 0x05: /* bgtu */
326 if (cpu
.asregs
.cc
& CC_GTU
)
327 pc
+= INST2OFFSET(inst
);
333 if (cpu
.asregs
.cc
& (CC_GT
| CC_EQ
))
334 pc
+= INST2OFFSET(inst
);
340 if (cpu
.asregs
.cc
& (CC_LT
| CC_EQ
))
341 pc
+= INST2OFFSET(inst
);
344 case 0x08: /* bgeu */
347 if (cpu
.asregs
.cc
& (CC_GTU
| CC_EQ
))
348 pc
+= INST2OFFSET(inst
);
351 case 0x09: /* bleu */
354 if (cpu
.asregs
.cc
& (CC_LTU
| CC_EQ
))
355 pc
+= INST2OFFSET(inst
);
361 cpu
.asregs
.exception
= SIGILL
;
368 /* This is a Form 2 instruction. */
369 int opcode
= (inst
>> 12 & 0x3);
374 int a
= (inst
>> 8) & 0xf;
375 unsigned av
= cpu
.asregs
.regs
[a
];
376 unsigned v
= (inst
& 0xff);
378 cpu
.asregs
.regs
[a
] = av
+ v
;
383 int a
= (inst
>> 8) & 0xf;
384 unsigned av
= cpu
.asregs
.regs
[a
];
385 unsigned v
= (inst
& 0xff);
387 cpu
.asregs
.regs
[a
] = av
- v
;
392 int a
= (inst
>> 8) & 0xf;
393 unsigned v
= (inst
& 0xff);
395 cpu
.asregs
.regs
[a
] = cpu
.asregs
.sregs
[v
];
400 int a
= (inst
>> 8) & 0xf;
401 unsigned v
= (inst
& 0xff);
403 cpu
.asregs
.sregs
[v
] = cpu
.asregs
.regs
[a
];
408 cpu
.asregs
.exception
= SIGILL
;
415 /* This is a Form 1 instruction. */
416 int opcode
= inst
>> 8;
422 cpu
.asregs
.exception
= SIGILL
;
424 case 0x01: /* ldi.l (immediate) */
426 int reg
= (inst
>> 4) & 0xf;
428 unsigned int val
= EXTRACT_WORD(pc
+2);
429 cpu
.asregs
.regs
[reg
] = val
;
433 case 0x02: /* mov (register-to-register) */
435 int dest
= (inst
>> 4) & 0xf;
436 int src
= (inst
) & 0xf;
438 cpu
.asregs
.regs
[dest
] = cpu
.asregs
.regs
[src
];
441 case 0x03: /* jsra */
443 unsigned int fn
= EXTRACT_WORD(pc
+2);
444 unsigned int sp
= cpu
.asregs
.regs
[1];
446 /* Save a slot for the static chain. */
449 /* Push the return address. */
451 wlat (scpu
, opc
, sp
, pc
+ 6);
453 /* Push the current frame pointer. */
455 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
457 /* Uncache the stack pointer and set the pc and $fp. */
458 cpu
.asregs
.regs
[1] = sp
;
459 cpu
.asregs
.regs
[0] = sp
;
465 unsigned int sp
= cpu
.asregs
.regs
[0];
469 /* Pop the frame pointer. */
470 cpu
.asregs
.regs
[0] = rlat (scpu
, opc
, sp
);
473 /* Pop the return address. */
474 pc
= rlat (scpu
, opc
, sp
) - 2;
477 /* Skip over the static chain slot. */
480 /* Uncache the stack pointer. */
481 cpu
.asregs
.regs
[1] = sp
;
484 case 0x05: /* add.l */
486 int a
= (inst
>> 4) & 0xf;
488 unsigned av
= cpu
.asregs
.regs
[a
];
489 unsigned bv
= cpu
.asregs
.regs
[b
];
491 cpu
.asregs
.regs
[a
] = av
+ bv
;
494 case 0x06: /* push */
496 int a
= (inst
>> 4) & 0xf;
498 int sp
= cpu
.asregs
.regs
[a
] - 4;
500 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[b
]);
501 cpu
.asregs
.regs
[a
] = sp
;
506 int a
= (inst
>> 4) & 0xf;
508 int sp
= cpu
.asregs
.regs
[a
];
510 cpu
.asregs
.regs
[b
] = rlat (scpu
, opc
, sp
);
511 cpu
.asregs
.regs
[a
] = sp
+ 4;
514 case 0x08: /* lda.l */
516 int reg
= (inst
>> 4) & 0xf;
517 unsigned int addr
= EXTRACT_WORD(pc
+2);
519 cpu
.asregs
.regs
[reg
] = rlat (scpu
, opc
, addr
);
523 case 0x09: /* sta.l */
525 int reg
= (inst
>> 4) & 0xf;
526 unsigned int addr
= EXTRACT_WORD(pc
+2);
528 wlat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
532 case 0x0a: /* ld.l (register indirect) */
534 int src
= inst
& 0xf;
535 int dest
= (inst
>> 4) & 0xf;
538 xv
= cpu
.asregs
.regs
[src
];
539 cpu
.asregs
.regs
[dest
] = rlat (scpu
, opc
, xv
);
542 case 0x0b: /* st.l */
544 int dest
= (inst
>> 4) & 0xf;
545 int val
= inst
& 0xf;
547 wlat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
550 case 0x0c: /* ldo.l */
552 unsigned int addr
= EXTRACT_WORD(pc
+2);
553 int a
= (inst
>> 4) & 0xf;
556 addr
+= cpu
.asregs
.regs
[b
];
557 cpu
.asregs
.regs
[a
] = rlat (scpu
, opc
, addr
);
561 case 0x0d: /* sto.l */
563 unsigned int addr
= EXTRACT_WORD(pc
+2);
564 int a
= (inst
>> 4) & 0xf;
567 addr
+= cpu
.asregs
.regs
[a
];
568 wlat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
574 int a
= (inst
>> 4) & 0xf;
577 int va
= cpu
.asregs
.regs
[a
];
578 int vb
= cpu
.asregs
.regs
[b
];
586 cc
|= (va
< vb
? CC_LT
: 0);
587 cc
|= (va
> vb
? CC_GT
: 0);
588 cc
|= ((unsigned int) va
< (unsigned int) vb
? CC_LTU
: 0);
589 cc
|= ((unsigned int) va
> (unsigned int) vb
? CC_GTU
: 0);
609 cpu
.asregs
.exception
= SIGILL
;
614 unsigned int fn
= cpu
.asregs
.regs
[(inst
>> 4) & 0xf];
615 unsigned int sp
= cpu
.asregs
.regs
[1];
619 /* Save a slot for the static chain. */
622 /* Push the return address. */
624 wlat (scpu
, opc
, sp
, pc
+ 2);
626 /* Push the current frame pointer. */
628 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
630 /* Uncache the stack pointer and set the fp & pc. */
631 cpu
.asregs
.regs
[1] = sp
;
632 cpu
.asregs
.regs
[0] = sp
;
636 case 0x1a: /* jmpa */
638 unsigned int tgt
= EXTRACT_WORD(pc
+2);
643 case 0x1b: /* ldi.b (immediate) */
645 int reg
= (inst
>> 4) & 0xf;
647 unsigned int val
= EXTRACT_WORD(pc
+2);
649 cpu
.asregs
.regs
[reg
] = val
;
653 case 0x1c: /* ld.b (register indirect) */
655 int src
= inst
& 0xf;
656 int dest
= (inst
>> 4) & 0xf;
659 xv
= cpu
.asregs
.regs
[src
];
660 cpu
.asregs
.regs
[dest
] = rbat (scpu
, opc
, xv
);
663 case 0x1d: /* lda.b */
665 int reg
= (inst
>> 4) & 0xf;
666 unsigned int addr
= EXTRACT_WORD(pc
+2);
668 cpu
.asregs
.regs
[reg
] = rbat (scpu
, opc
, addr
);
672 case 0x1e: /* st.b */
674 int dest
= (inst
>> 4) & 0xf;
675 int val
= inst
& 0xf;
677 wbat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
680 case 0x1f: /* sta.b */
682 int reg
= (inst
>> 4) & 0xf;
683 unsigned int addr
= EXTRACT_WORD(pc
+2);
685 wbat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
689 case 0x20: /* ldi.s (immediate) */
691 int reg
= (inst
>> 4) & 0xf;
693 unsigned int val
= EXTRACT_WORD(pc
+2);
695 cpu
.asregs
.regs
[reg
] = val
;
699 case 0x21: /* ld.s (register indirect) */
701 int src
= inst
& 0xf;
702 int dest
= (inst
>> 4) & 0xf;
705 xv
= cpu
.asregs
.regs
[src
];
706 cpu
.asregs
.regs
[dest
] = rsat (scpu
, opc
, xv
);
709 case 0x22: /* lda.s */
711 int reg
= (inst
>> 4) & 0xf;
712 unsigned int addr
= EXTRACT_WORD(pc
+2);
714 cpu
.asregs
.regs
[reg
] = rsat (scpu
, opc
, addr
);
718 case 0x23: /* st.s */
720 int dest
= (inst
>> 4) & 0xf;
721 int val
= inst
& 0xf;
723 wsat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
726 case 0x24: /* sta.s */
728 int reg
= (inst
>> 4) & 0xf;
729 unsigned int addr
= EXTRACT_WORD(pc
+2);
731 wsat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
737 int reg
= (inst
>> 4) & 0xf;
739 pc
= cpu
.asregs
.regs
[reg
] - 2;
744 int a
= (inst
>> 4) & 0xf;
748 av
= cpu
.asregs
.regs
[a
];
749 bv
= cpu
.asregs
.regs
[b
];
750 cpu
.asregs
.regs
[a
] = av
& bv
;
753 case 0x27: /* lshr */
755 int a
= (inst
>> 4) & 0xf;
757 int av
= cpu
.asregs
.regs
[a
];
758 int bv
= cpu
.asregs
.regs
[b
];
760 cpu
.asregs
.regs
[a
] = (unsigned) ((unsigned) av
>> bv
);
763 case 0x28: /* ashl */
765 int a
= (inst
>> 4) & 0xf;
767 int av
= cpu
.asregs
.regs
[a
];
768 int bv
= cpu
.asregs
.regs
[b
];
770 cpu
.asregs
.regs
[a
] = av
<< bv
;
773 case 0x29: /* sub.l */
775 int a
= (inst
>> 4) & 0xf;
777 unsigned av
= cpu
.asregs
.regs
[a
];
778 unsigned bv
= cpu
.asregs
.regs
[b
];
780 cpu
.asregs
.regs
[a
] = av
- bv
;
785 int a
= (inst
>> 4) & 0xf;
787 int bv
= cpu
.asregs
.regs
[b
];
789 cpu
.asregs
.regs
[a
] = - bv
;
794 int a
= (inst
>> 4) & 0xf;
798 av
= cpu
.asregs
.regs
[a
];
799 bv
= cpu
.asregs
.regs
[b
];
800 cpu
.asregs
.regs
[a
] = av
| bv
;
805 int a
= (inst
>> 4) & 0xf;
807 int bv
= cpu
.asregs
.regs
[b
];
809 cpu
.asregs
.regs
[a
] = 0xffffffff ^ bv
;
812 case 0x2d: /* ashr */
814 int a
= (inst
>> 4) & 0xf;
816 int av
= cpu
.asregs
.regs
[a
];
817 int bv
= cpu
.asregs
.regs
[b
];
819 cpu
.asregs
.regs
[a
] = av
>> bv
;
824 int a
= (inst
>> 4) & 0xf;
828 av
= cpu
.asregs
.regs
[a
];
829 bv
= cpu
.asregs
.regs
[b
];
830 cpu
.asregs
.regs
[a
] = av
^ bv
;
833 case 0x2f: /* mul.l */
835 int a
= (inst
>> 4) & 0xf;
837 unsigned av
= cpu
.asregs
.regs
[a
];
838 unsigned bv
= cpu
.asregs
.regs
[b
];
840 cpu
.asregs
.regs
[a
] = av
* bv
;
845 unsigned int inum
= EXTRACT_WORD(pc
+2);
847 /* Set the special registers appropriately. */
848 cpu
.asregs
.sregs
[2] = 3; /* MOXIE_EX_SWI */
849 cpu
.asregs
.sregs
[3] = inum
;
852 case 0x1: /* SYS_exit */
854 cpu
.asregs
.exception
= SIGQUIT
;
857 case 0x2: /* SYS_open */
860 int mode
= (int) convert_target_flags ((unsigned) cpu
.asregs
.regs
[3]);
861 int perm
= (int) cpu
.asregs
.regs
[4];
862 int fd
= open (fname
, mode
, perm
);
863 sim_core_read_buffer (sd
, scpu
, read_map
, fname
,
864 cpu
.asregs
.regs
[2], 1024);
865 /* FIXME - set errno */
866 cpu
.asregs
.regs
[2] = fd
;
869 case 0x4: /* SYS_read */
871 int fd
= cpu
.asregs
.regs
[2];
872 unsigned len
= (unsigned) cpu
.asregs
.regs
[4];
873 char *buf
= malloc (len
);
874 cpu
.asregs
.regs
[2] = read (fd
, buf
, len
);
875 sim_core_write_buffer (sd
, scpu
, write_map
, buf
,
876 cpu
.asregs
.regs
[3], len
);
880 case 0x5: /* SYS_write */
883 /* String length is at 0x12($fp) */
884 unsigned count
, len
= (unsigned) cpu
.asregs
.regs
[4];
886 sim_core_read_buffer (sd
, scpu
, read_map
, str
,
887 cpu
.asregs
.regs
[3], len
);
888 count
= write (cpu
.asregs
.regs
[2], str
, len
);
890 cpu
.asregs
.regs
[2] = count
;
893 case 0xffffffff: /* Linux System Call */
895 unsigned int handler
= cpu
.asregs
.sregs
[1];
896 unsigned int sp
= cpu
.asregs
.regs
[1];
898 /* Save a slot for the static chain. */
901 /* Push the return address. */
903 wlat (scpu
, opc
, sp
, pc
+ 6);
905 /* Push the current frame pointer. */
907 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
909 /* Uncache the stack pointer and set the fp & pc. */
910 cpu
.asregs
.regs
[1] = sp
;
911 cpu
.asregs
.regs
[0] = sp
;
920 case 0x31: /* div.l */
922 int a
= (inst
>> 4) & 0xf;
924 int av
= cpu
.asregs
.regs
[a
];
925 int bv
= cpu
.asregs
.regs
[b
];
927 cpu
.asregs
.regs
[a
] = av
/ bv
;
930 case 0x32: /* udiv.l */
932 int a
= (inst
>> 4) & 0xf;
934 unsigned int av
= cpu
.asregs
.regs
[a
];
935 unsigned int bv
= cpu
.asregs
.regs
[b
];
937 cpu
.asregs
.regs
[a
] = (av
/ bv
);
940 case 0x33: /* mod.l */
942 int a
= (inst
>> 4) & 0xf;
944 int av
= cpu
.asregs
.regs
[a
];
945 int bv
= cpu
.asregs
.regs
[b
];
947 cpu
.asregs
.regs
[a
] = av
% bv
;
950 case 0x34: /* umod.l */
952 int a
= (inst
>> 4) & 0xf;
954 unsigned int av
= cpu
.asregs
.regs
[a
];
955 unsigned int bv
= cpu
.asregs
.regs
[b
];
957 cpu
.asregs
.regs
[a
] = (av
% bv
);
962 cpu
.asregs
.exception
= SIGTRAP
;
963 pc
-= 2; /* Adjust pc */
965 case 0x36: /* ldo.b */
967 unsigned int addr
= EXTRACT_WORD(pc
+2);
968 int a
= (inst
>> 4) & 0xf;
971 addr
+= cpu
.asregs
.regs
[b
];
972 cpu
.asregs
.regs
[a
] = rbat (scpu
, opc
, addr
);
976 case 0x37: /* sto.b */
978 unsigned int addr
= EXTRACT_WORD(pc
+2);
979 int a
= (inst
>> 4) & 0xf;
982 addr
+= cpu
.asregs
.regs
[a
];
983 wbat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
987 case 0x38: /* ldo.s */
989 unsigned int addr
= EXTRACT_WORD(pc
+2);
990 int a
= (inst
>> 4) & 0xf;
993 addr
+= cpu
.asregs
.regs
[b
];
994 cpu
.asregs
.regs
[a
] = rsat (scpu
, opc
, addr
);
998 case 0x39: /* sto.s */
1000 unsigned int addr
= EXTRACT_WORD(pc
+2);
1001 int a
= (inst
>> 4) & 0xf;
1004 addr
+= cpu
.asregs
.regs
[a
];
1005 wsat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
1012 cpu
.asregs
.exception
= SIGILL
;
1020 } while (!cpu
.asregs
.exception
);
1022 /* Hide away the things we've cached while executing. */
1023 cpu
.asregs
.regs
[PC_REGNO
] = pc
;
1024 cpu
.asregs
.insts
+= insts
; /* instructions done ... */
1026 signal (SIGINT
, sigsave
);
1030 sim_write (sd
, addr
, buffer
, size
)
1033 const unsigned char * buffer
;
1036 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1038 sim_core_write_buffer (sd
, scpu
, write_map
, buffer
, addr
, size
);
1044 sim_read (sd
, addr
, buffer
, size
)
1047 unsigned char * buffer
;
1050 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1052 sim_core_read_buffer (sd
, scpu
, read_map
, buffer
, addr
, size
);
1059 sim_store_register (sd
, rn
, memory
, length
)
1062 unsigned char * memory
;
1065 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1071 /* misalignment safe */
1072 ival
= moxie_extract_unsigned_integer (memory
, 4);
1073 cpu
.asints
[rn
] = ival
;
1083 sim_fetch_register (sd
, rn
, memory
, length
)
1086 unsigned char * memory
;
1089 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1093 long ival
= cpu
.asints
[rn
];
1095 /* misalignment-safe */
1096 moxie_store_unsigned_integer (memory
, 4, ival
);
1111 tracefile
= fopen("trace.csv", "wb");
1115 sim_resume (sd
, 0, 0);
1123 sim_stop_reason (sd
, reason
, sigrc
)
1125 enum sim_stop
* reason
;
1128 if (cpu
.asregs
.exception
== SIGQUIT
)
1130 * reason
= sim_exited
;
1131 * sigrc
= cpu
.asregs
.regs
[2];
1135 * reason
= sim_stopped
;
1136 * sigrc
= cpu
.asregs
.exception
;
1145 cpu
.asregs
.exception
= SIGINT
;
1151 sim_info (sd
, verbose
)
1155 callback
->printf_filtered (callback
, "\n\n# instructions executed %llu\n",
1161 sim_open (kind
, cb
, abfd
, argv
)
1167 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
1168 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
1170 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
1173 sim_do_command(sd
," memory region 0x00000000,0x4000000") ;
1174 sim_do_command(sd
," memory region 0xE0000000,0x10000") ;
1179 if (kind
== SIM_OPEN_STANDALONE
)
1182 set_initial_gprs (); /* Reset the GPR registers. */
1184 /* Configure/verify the target byte order and other runtime
1185 configuration options. */
1186 if (sim_config (sd
) != SIM_RC_OK
)
1188 sim_module_uninstall (sd
);
1192 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
1194 /* Uninstall the modules to avoid memory leaks,
1195 file descriptor leaks, etc. */
1196 sim_module_uninstall (sd
);
1204 sim_close (sd
, quitting
)
1212 /* Load the device tree blob. */
1215 load_dtb (SIM_DESC sd
, const char *filename
)
1218 FILE *f
= fopen (filename
, "rb");
1220 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1223 printf ("WARNING: ``%s'' could not be opened.\n", filename
);
1226 fseek (f
, 0, SEEK_END
);
1228 fseek (f
, 0, SEEK_SET
);
1229 buf
= alloca (size
);
1230 if (size
!= fread (buf
, 1, size
, f
))
1232 printf ("ERROR: error reading ``%s''.\n", filename
);
1235 sim_core_write_buffer (sd
, scpu
, write_map
, buf
, 0xE0000000, size
);
1236 cpu
.asregs
.sregs
[9] = 0xE0000000;
1241 sim_load (sd
, prog
, abfd
, from_tty
)
1248 /* Do the right thing for ELF executables; this turns out to be
1249 just about the right thing for any object format that:
1250 - we crack using BFD routines
1251 - follows the traditional UNIX text/data/bss layout
1252 - calls the bss section ".bss". */
1254 extern bfd
* sim_load_file (); /* ??? Don't know where this should live. */
1259 handle
= bfd_openr (prog
, 0); /* could be "moxie" */
1263 printf("``%s'' could not be opened.\n", prog
);
1267 /* Makes sure that we have an object file, also cleans gets the
1268 section headers in place. */
1269 if (!bfd_check_format (handle
, bfd_object
))
1271 /* wasn't an object file */
1273 printf ("``%s'' is not appropriate object file.\n", prog
);
1277 /* Clean up after ourselves. */
1281 /* from sh -- dac */
1282 prog_bfd
= sim_load_file (sd
, myname
, callback
, prog
, abfd
,
1283 sim_kind
== SIM_OPEN_DEBUG
,
1285 if (prog_bfd
== NULL
)
1289 bfd_close (prog_bfd
);
1295 sim_create_inferior (sd
, prog_bfd
, argv
, env
)
1297 struct bfd
* prog_bfd
;
1303 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1305 /* Set the initial register set. */
1308 set_initial_gprs ();
1311 if (prog_bfd
!= NULL
)
1312 cpu
.asregs
.regs
[PC_REGNO
] = bfd_get_start_address (prog_bfd
);
1314 /* Copy args into target memory. */
1316 for (argc
= 0; avp
&& *avp
; avp
++)
1319 /* Target memory looks like this:
1320 0x00000000 zero word
1321 0x00000004 argc word
1322 0x00000008 start of argv
1324 0x0000???? end of argv
1325 0x0000???? zero word
1326 0x0000???? start of data pointed to by argv */
1328 wlat (scpu
, 0, 0, 0);
1329 wlat (scpu
, 0, 4, argc
);
1331 /* tp is the offset of our first argv data. */
1332 tp
= 4 + 4 + argc
* 4 + 4;
1334 for (i
= 0; i
< argc
; i
++)
1336 /* Set the argv value. */
1337 wlat (scpu
, 0, 4 + 4 + i
* 4, tp
);
1339 /* Store the string. */
1340 sim_core_write_buffer (sd
, scpu
, write_map
, argv
[i
],
1341 tp
, strlen(argv
[i
])+1);
1342 tp
+= strlen (argv
[i
]) + 1;
1345 wlat (scpu
, 0, 4 + 4 + i
* 4, 0);
1361 sim_do_command (sd
, cmd
)
1365 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
1367 "Error: \"%s\" is not a valid moxie simulator command.\n",
1372 sim_set_callbacks (ptr
)
1373 host_callback
* ptr
;
This page took 0.064564 seconds and 4 git commands to generate.