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;
160 /* Write a 1 byte value to memory. */
163 wbat (sim_cpu
*scpu
, word pc
, word x
, word v
)
165 address_word cia
= CIA_GET (scpu
);
167 sim_core_write_aligned_1 (scpu
, cia
, write_map
, x
, v
);
170 /* Write a 2 byte value to memory. */
173 wsat (sim_cpu
*scpu
, word pc
, word x
, word v
)
175 address_word cia
= CIA_GET (scpu
);
177 sim_core_write_aligned_2 (scpu
, cia
, write_map
, x
, v
);
180 /* Write a 4 byte value to memory. */
183 wlat (sim_cpu
*scpu
, word pc
, word x
, word v
)
185 address_word cia
= CIA_GET (scpu
);
187 sim_core_write_aligned_4 (scpu
, cia
, write_map
, x
, v
);
190 /* Read 2 bytes from memory. */
193 rsat (sim_cpu
*scpu
, word pc
, word x
)
195 address_word cia
= CIA_GET (scpu
);
197 return (sim_core_read_aligned_2 (scpu
, cia
, read_map
, x
));
200 /* Read 1 byte from memory. */
203 rbat (sim_cpu
*scpu
, word pc
, word x
)
205 address_word cia
= CIA_GET (scpu
);
207 return (sim_core_read_aligned_1 (scpu
, cia
, read_map
, x
));
210 /* Read 4 bytes from memory. */
213 rlat (sim_cpu
*scpu
, word pc
, word x
)
215 address_word cia
= CIA_GET (scpu
);
217 return (sim_core_read_aligned_4 (scpu
, cia
, read_map
, x
));
220 #define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; }
223 convert_target_flags (unsigned int tflags
)
225 unsigned int hflags
= 0x0;
227 CHECK_FLAG(0x0001, O_WRONLY
);
228 CHECK_FLAG(0x0002, O_RDWR
);
229 CHECK_FLAG(0x0008, O_APPEND
);
230 CHECK_FLAG(0x0200, O_CREAT
);
231 CHECK_FLAG(0x0400, O_TRUNC
);
232 CHECK_FLAG(0x0800, O_EXCL
);
233 CHECK_FLAG(0x2000, O_SYNC
);
237 "Simulator Error: problem converting target open flags for host. 0x%x\n",
243 #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]);
245 static int tracing
= 0;
248 sim_resume (sd
, step
, siggnal
)
253 unsigned long long insts
;
255 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
256 address_word cia
= CIA_GET (scpu
);
258 cpu
.asregs
.exception
= step
? SIGTRAP
: 0;
259 pc
= cpu
.asregs
.regs
[PC_REGNO
];
260 insts
= cpu
.asregs
.insts
;
262 /* Run instructions here. */
267 /* Fetch the instruction at pc. */
268 inst
= (sim_core_read_aligned_1 (scpu
, cia
, read_map
, pc
) << 8)
269 + sim_core_read_aligned_1 (scpu
, cia
, read_map
, pc
+1);
271 /* Decode instruction. */
272 if (inst
& (1 << 15))
274 if (inst
& (1 << 14))
276 /* This is a Form 3 instruction. */
277 int opcode
= (inst
>> 10 & 0xf);
284 if (cpu
.asregs
.cc
& CC_EQ
)
285 pc
+= INST2OFFSET(inst
);
291 if (! (cpu
.asregs
.cc
& CC_EQ
))
292 pc
+= INST2OFFSET(inst
);
298 if (cpu
.asregs
.cc
& CC_LT
)
299 pc
+= INST2OFFSET(inst
);
304 if (cpu
.asregs
.cc
& CC_GT
)
305 pc
+= INST2OFFSET(inst
);
308 case 0x04: /* bltu */
311 if (cpu
.asregs
.cc
& CC_LTU
)
312 pc
+= INST2OFFSET(inst
);
315 case 0x05: /* bgtu */
318 if (cpu
.asregs
.cc
& CC_GTU
)
319 pc
+= INST2OFFSET(inst
);
325 if (cpu
.asregs
.cc
& (CC_GT
| CC_EQ
))
326 pc
+= INST2OFFSET(inst
);
332 if (cpu
.asregs
.cc
& (CC_LT
| CC_EQ
))
333 pc
+= INST2OFFSET(inst
);
336 case 0x08: /* bgeu */
339 if (cpu
.asregs
.cc
& (CC_GTU
| CC_EQ
))
340 pc
+= INST2OFFSET(inst
);
343 case 0x09: /* bleu */
346 if (cpu
.asregs
.cc
& (CC_LTU
| CC_EQ
))
347 pc
+= INST2OFFSET(inst
);
353 cpu
.asregs
.exception
= SIGILL
;
360 /* This is a Form 2 instruction. */
361 int opcode
= (inst
>> 12 & 0x3);
366 int a
= (inst
>> 8) & 0xf;
367 unsigned av
= cpu
.asregs
.regs
[a
];
368 unsigned v
= (inst
& 0xff);
370 cpu
.asregs
.regs
[a
] = av
+ v
;
375 int a
= (inst
>> 8) & 0xf;
376 unsigned av
= cpu
.asregs
.regs
[a
];
377 unsigned v
= (inst
& 0xff);
379 cpu
.asregs
.regs
[a
] = av
- v
;
384 int a
= (inst
>> 8) & 0xf;
385 unsigned v
= (inst
& 0xff);
387 cpu
.asregs
.regs
[a
] = cpu
.asregs
.sregs
[v
];
392 int a
= (inst
>> 8) & 0xf;
393 unsigned v
= (inst
& 0xff);
395 cpu
.asregs
.sregs
[v
] = cpu
.asregs
.regs
[a
];
400 cpu
.asregs
.exception
= SIGILL
;
407 /* This is a Form 1 instruction. */
408 int opcode
= inst
>> 8;
414 cpu
.asregs
.exception
= SIGILL
;
416 case 0x01: /* ldi.l (immediate) */
418 int reg
= (inst
>> 4) & 0xf;
420 unsigned int val
= EXTRACT_WORD(pc
+2);
421 cpu
.asregs
.regs
[reg
] = val
;
425 case 0x02: /* mov (register-to-register) */
427 int dest
= (inst
>> 4) & 0xf;
428 int src
= (inst
) & 0xf;
430 cpu
.asregs
.regs
[dest
] = cpu
.asregs
.regs
[src
];
433 case 0x03: /* jsra */
435 unsigned int fn
= EXTRACT_WORD(pc
+2);
436 unsigned int sp
= cpu
.asregs
.regs
[1];
438 /* Save a slot for the static chain. */
441 /* Push the return address. */
443 wlat (scpu
, opc
, sp
, pc
+ 6);
445 /* Push the current frame pointer. */
447 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
449 /* Uncache the stack pointer and set the pc and $fp. */
450 cpu
.asregs
.regs
[1] = sp
;
451 cpu
.asregs
.regs
[0] = sp
;
457 unsigned int sp
= cpu
.asregs
.regs
[0];
461 /* Pop the frame pointer. */
462 cpu
.asregs
.regs
[0] = rlat (scpu
, opc
, sp
);
465 /* Pop the return address. */
466 pc
= rlat (scpu
, opc
, sp
) - 2;
469 /* Skip over the static chain slot. */
472 /* Uncache the stack pointer. */
473 cpu
.asregs
.regs
[1] = sp
;
476 case 0x05: /* add.l */
478 int a
= (inst
>> 4) & 0xf;
480 unsigned av
= cpu
.asregs
.regs
[a
];
481 unsigned bv
= cpu
.asregs
.regs
[b
];
483 cpu
.asregs
.regs
[a
] = av
+ bv
;
486 case 0x06: /* push */
488 int a
= (inst
>> 4) & 0xf;
490 int sp
= cpu
.asregs
.regs
[a
] - 4;
492 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[b
]);
493 cpu
.asregs
.regs
[a
] = sp
;
498 int a
= (inst
>> 4) & 0xf;
500 int sp
= cpu
.asregs
.regs
[a
];
502 cpu
.asregs
.regs
[b
] = rlat (scpu
, opc
, sp
);
503 cpu
.asregs
.regs
[a
] = sp
+ 4;
506 case 0x08: /* lda.l */
508 int reg
= (inst
>> 4) & 0xf;
509 unsigned int addr
= EXTRACT_WORD(pc
+2);
511 cpu
.asregs
.regs
[reg
] = rlat (scpu
, opc
, addr
);
515 case 0x09: /* sta.l */
517 int reg
= (inst
>> 4) & 0xf;
518 unsigned int addr
= EXTRACT_WORD(pc
+2);
520 wlat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
524 case 0x0a: /* ld.l (register indirect) */
526 int src
= inst
& 0xf;
527 int dest
= (inst
>> 4) & 0xf;
530 xv
= cpu
.asregs
.regs
[src
];
531 cpu
.asregs
.regs
[dest
] = rlat (scpu
, opc
, xv
);
534 case 0x0b: /* st.l */
536 int dest
= (inst
>> 4) & 0xf;
537 int val
= inst
& 0xf;
539 wlat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
542 case 0x0c: /* ldo.l */
544 unsigned int addr
= EXTRACT_WORD(pc
+2);
545 int a
= (inst
>> 4) & 0xf;
548 addr
+= cpu
.asregs
.regs
[b
];
549 cpu
.asregs
.regs
[a
] = rlat (scpu
, opc
, addr
);
553 case 0x0d: /* sto.l */
555 unsigned int addr
= EXTRACT_WORD(pc
+2);
556 int a
= (inst
>> 4) & 0xf;
559 addr
+= cpu
.asregs
.regs
[a
];
560 wlat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
566 int a
= (inst
>> 4) & 0xf;
569 int va
= cpu
.asregs
.regs
[a
];
570 int vb
= cpu
.asregs
.regs
[b
];
578 cc
|= (va
< vb
? CC_LT
: 0);
579 cc
|= (va
> vb
? CC_GT
: 0);
580 cc
|= ((unsigned int) va
< (unsigned int) vb
? CC_LTU
: 0);
581 cc
|= ((unsigned int) va
> (unsigned int) vb
? CC_GTU
: 0);
589 case 0x10: /* sex.b */
591 int a
= (inst
>> 4) & 0xf;
593 signed char bv
= cpu
.asregs
.regs
[b
];
595 cpu
.asregs
.regs
[a
] = (int) bv
;
598 case 0x11: /* sex.s */
600 int a
= (inst
>> 4) & 0xf;
602 signed short bv
= cpu
.asregs
.regs
[b
];
604 cpu
.asregs
.regs
[a
] = (int) bv
;
617 cpu
.asregs
.exception
= SIGILL
;
622 unsigned int fn
= cpu
.asregs
.regs
[(inst
>> 4) & 0xf];
623 unsigned int sp
= cpu
.asregs
.regs
[1];
627 /* Save a slot for the static chain. */
630 /* Push the return address. */
632 wlat (scpu
, opc
, sp
, pc
+ 2);
634 /* Push the current frame pointer. */
636 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
638 /* Uncache the stack pointer and set the fp & pc. */
639 cpu
.asregs
.regs
[1] = sp
;
640 cpu
.asregs
.regs
[0] = sp
;
644 case 0x1a: /* jmpa */
646 unsigned int tgt
= EXTRACT_WORD(pc
+2);
651 case 0x1b: /* ldi.b (immediate) */
653 int reg
= (inst
>> 4) & 0xf;
655 unsigned int val
= EXTRACT_WORD(pc
+2);
657 cpu
.asregs
.regs
[reg
] = val
;
661 case 0x1c: /* ld.b (register indirect) */
663 int src
= inst
& 0xf;
664 int dest
= (inst
>> 4) & 0xf;
667 xv
= cpu
.asregs
.regs
[src
];
668 cpu
.asregs
.regs
[dest
] = rbat (scpu
, opc
, xv
);
671 case 0x1d: /* lda.b */
673 int reg
= (inst
>> 4) & 0xf;
674 unsigned int addr
= EXTRACT_WORD(pc
+2);
676 cpu
.asregs
.regs
[reg
] = rbat (scpu
, opc
, addr
);
680 case 0x1e: /* st.b */
682 int dest
= (inst
>> 4) & 0xf;
683 int val
= inst
& 0xf;
685 wbat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
688 case 0x1f: /* sta.b */
690 int reg
= (inst
>> 4) & 0xf;
691 unsigned int addr
= EXTRACT_WORD(pc
+2);
693 wbat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
697 case 0x20: /* ldi.s (immediate) */
699 int reg
= (inst
>> 4) & 0xf;
701 unsigned int val
= EXTRACT_WORD(pc
+2);
703 cpu
.asregs
.regs
[reg
] = val
;
707 case 0x21: /* ld.s (register indirect) */
709 int src
= inst
& 0xf;
710 int dest
= (inst
>> 4) & 0xf;
713 xv
= cpu
.asregs
.regs
[src
];
714 cpu
.asregs
.regs
[dest
] = rsat (scpu
, opc
, xv
);
717 case 0x22: /* lda.s */
719 int reg
= (inst
>> 4) & 0xf;
720 unsigned int addr
= EXTRACT_WORD(pc
+2);
722 cpu
.asregs
.regs
[reg
] = rsat (scpu
, opc
, addr
);
726 case 0x23: /* st.s */
728 int dest
= (inst
>> 4) & 0xf;
729 int val
= inst
& 0xf;
731 wsat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
734 case 0x24: /* sta.s */
736 int reg
= (inst
>> 4) & 0xf;
737 unsigned int addr
= EXTRACT_WORD(pc
+2);
739 wsat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
745 int reg
= (inst
>> 4) & 0xf;
747 pc
= cpu
.asregs
.regs
[reg
] - 2;
752 int a
= (inst
>> 4) & 0xf;
756 av
= cpu
.asregs
.regs
[a
];
757 bv
= cpu
.asregs
.regs
[b
];
758 cpu
.asregs
.regs
[a
] = av
& bv
;
761 case 0x27: /* lshr */
763 int a
= (inst
>> 4) & 0xf;
765 int av
= cpu
.asregs
.regs
[a
];
766 int bv
= cpu
.asregs
.regs
[b
];
768 cpu
.asregs
.regs
[a
] = (unsigned) ((unsigned) av
>> bv
);
771 case 0x28: /* ashl */
773 int a
= (inst
>> 4) & 0xf;
775 int av
= cpu
.asregs
.regs
[a
];
776 int bv
= cpu
.asregs
.regs
[b
];
778 cpu
.asregs
.regs
[a
] = av
<< bv
;
781 case 0x29: /* sub.l */
783 int a
= (inst
>> 4) & 0xf;
785 unsigned av
= cpu
.asregs
.regs
[a
];
786 unsigned bv
= cpu
.asregs
.regs
[b
];
788 cpu
.asregs
.regs
[a
] = av
- bv
;
793 int a
= (inst
>> 4) & 0xf;
795 int bv
= cpu
.asregs
.regs
[b
];
797 cpu
.asregs
.regs
[a
] = - bv
;
802 int a
= (inst
>> 4) & 0xf;
806 av
= cpu
.asregs
.regs
[a
];
807 bv
= cpu
.asregs
.regs
[b
];
808 cpu
.asregs
.regs
[a
] = av
| bv
;
813 int a
= (inst
>> 4) & 0xf;
815 int bv
= cpu
.asregs
.regs
[b
];
817 cpu
.asregs
.regs
[a
] = 0xffffffff ^ bv
;
820 case 0x2d: /* ashr */
822 int a
= (inst
>> 4) & 0xf;
824 int av
= cpu
.asregs
.regs
[a
];
825 int bv
= cpu
.asregs
.regs
[b
];
827 cpu
.asregs
.regs
[a
] = av
>> bv
;
832 int a
= (inst
>> 4) & 0xf;
836 av
= cpu
.asregs
.regs
[a
];
837 bv
= cpu
.asregs
.regs
[b
];
838 cpu
.asregs
.regs
[a
] = av
^ bv
;
841 case 0x2f: /* mul.l */
843 int a
= (inst
>> 4) & 0xf;
845 unsigned av
= cpu
.asregs
.regs
[a
];
846 unsigned bv
= cpu
.asregs
.regs
[b
];
848 cpu
.asregs
.regs
[a
] = av
* bv
;
853 unsigned int inum
= EXTRACT_WORD(pc
+2);
855 /* Set the special registers appropriately. */
856 cpu
.asregs
.sregs
[2] = 3; /* MOXIE_EX_SWI */
857 cpu
.asregs
.sregs
[3] = inum
;
860 case 0x1: /* SYS_exit */
862 cpu
.asregs
.exception
= SIGQUIT
;
865 case 0x2: /* SYS_open */
868 int mode
= (int) convert_target_flags ((unsigned) cpu
.asregs
.regs
[3]);
869 int perm
= (int) cpu
.asregs
.regs
[4];
870 int fd
= open (fname
, mode
, perm
);
871 sim_core_read_buffer (sd
, scpu
, read_map
, fname
,
872 cpu
.asregs
.regs
[2], 1024);
873 /* FIXME - set errno */
874 cpu
.asregs
.regs
[2] = fd
;
877 case 0x4: /* SYS_read */
879 int fd
= cpu
.asregs
.regs
[2];
880 unsigned len
= (unsigned) cpu
.asregs
.regs
[4];
881 char *buf
= malloc (len
);
882 cpu
.asregs
.regs
[2] = read (fd
, buf
, len
);
883 sim_core_write_buffer (sd
, scpu
, write_map
, buf
,
884 cpu
.asregs
.regs
[3], len
);
888 case 0x5: /* SYS_write */
891 /* String length is at 0x12($fp) */
892 unsigned count
, len
= (unsigned) cpu
.asregs
.regs
[4];
894 sim_core_read_buffer (sd
, scpu
, read_map
, str
,
895 cpu
.asregs
.regs
[3], len
);
896 count
= write (cpu
.asregs
.regs
[2], str
, len
);
898 cpu
.asregs
.regs
[2] = count
;
901 case 0xffffffff: /* Linux System Call */
903 unsigned int handler
= cpu
.asregs
.sregs
[1];
904 unsigned int sp
= cpu
.asregs
.regs
[1];
906 /* Save a slot for the static chain. */
909 /* Push the return address. */
911 wlat (scpu
, opc
, sp
, pc
+ 6);
913 /* Push the current frame pointer. */
915 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
917 /* Uncache the stack pointer and set the fp & pc. */
918 cpu
.asregs
.regs
[1] = sp
;
919 cpu
.asregs
.regs
[0] = sp
;
928 case 0x31: /* div.l */
930 int a
= (inst
>> 4) & 0xf;
932 int av
= cpu
.asregs
.regs
[a
];
933 int bv
= cpu
.asregs
.regs
[b
];
935 cpu
.asregs
.regs
[a
] = av
/ bv
;
938 case 0x32: /* udiv.l */
940 int a
= (inst
>> 4) & 0xf;
942 unsigned int av
= cpu
.asregs
.regs
[a
];
943 unsigned int bv
= cpu
.asregs
.regs
[b
];
945 cpu
.asregs
.regs
[a
] = (av
/ bv
);
948 case 0x33: /* mod.l */
950 int a
= (inst
>> 4) & 0xf;
952 int av
= cpu
.asregs
.regs
[a
];
953 int bv
= cpu
.asregs
.regs
[b
];
955 cpu
.asregs
.regs
[a
] = av
% bv
;
958 case 0x34: /* umod.l */
960 int a
= (inst
>> 4) & 0xf;
962 unsigned int av
= cpu
.asregs
.regs
[a
];
963 unsigned int bv
= cpu
.asregs
.regs
[b
];
965 cpu
.asregs
.regs
[a
] = (av
% bv
);
970 cpu
.asregs
.exception
= SIGTRAP
;
971 pc
-= 2; /* Adjust pc */
973 case 0x36: /* ldo.b */
975 unsigned int addr
= EXTRACT_WORD(pc
+2);
976 int a
= (inst
>> 4) & 0xf;
979 addr
+= cpu
.asregs
.regs
[b
];
980 cpu
.asregs
.regs
[a
] = rbat (scpu
, opc
, addr
);
984 case 0x37: /* sto.b */
986 unsigned int addr
= EXTRACT_WORD(pc
+2);
987 int a
= (inst
>> 4) & 0xf;
990 addr
+= cpu
.asregs
.regs
[a
];
991 wbat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
995 case 0x38: /* ldo.s */
997 unsigned int addr
= EXTRACT_WORD(pc
+2);
998 int a
= (inst
>> 4) & 0xf;
1001 addr
+= cpu
.asregs
.regs
[b
];
1002 cpu
.asregs
.regs
[a
] = rsat (scpu
, opc
, addr
);
1006 case 0x39: /* sto.s */
1008 unsigned int addr
= EXTRACT_WORD(pc
+2);
1009 int a
= (inst
>> 4) & 0xf;
1012 addr
+= cpu
.asregs
.regs
[a
];
1013 wsat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
1020 cpu
.asregs
.exception
= SIGILL
;
1028 } while (!cpu
.asregs
.exception
);
1030 /* Hide away the things we've cached while executing. */
1031 cpu
.asregs
.regs
[PC_REGNO
] = pc
;
1032 cpu
.asregs
.insts
+= insts
; /* instructions done ... */
1036 sim_write (sd
, addr
, buffer
, size
)
1039 const unsigned char * buffer
;
1042 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1044 sim_core_write_buffer (sd
, scpu
, write_map
, buffer
, addr
, size
);
1050 sim_read (sd
, addr
, buffer
, size
)
1053 unsigned char * buffer
;
1056 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1058 sim_core_read_buffer (sd
, scpu
, read_map
, buffer
, addr
, size
);
1065 sim_store_register (sd
, rn
, memory
, length
)
1068 unsigned char * memory
;
1071 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1077 /* misalignment safe */
1078 ival
= moxie_extract_unsigned_integer (memory
, 4);
1079 cpu
.asints
[rn
] = ival
;
1089 sim_fetch_register (sd
, rn
, memory
, length
)
1092 unsigned char * memory
;
1095 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1099 long ival
= cpu
.asints
[rn
];
1101 /* misalignment-safe */
1102 moxie_store_unsigned_integer (memory
, 4, ival
);
1117 tracefile
= fopen("trace.csv", "wb");
1121 sim_resume (sd
, 0, 0);
1129 sim_stop_reason (sd
, reason
, sigrc
)
1131 enum sim_stop
* reason
;
1134 if (cpu
.asregs
.exception
== SIGQUIT
)
1136 * reason
= sim_exited
;
1137 * sigrc
= cpu
.asregs
.regs
[2];
1141 * reason
= sim_stopped
;
1142 * sigrc
= cpu
.asregs
.exception
;
1151 cpu
.asregs
.exception
= SIGINT
;
1157 sim_info (sd
, verbose
)
1161 callback
->printf_filtered (callback
, "\n\n# instructions executed %llu\n",
1167 sim_open (kind
, cb
, abfd
, argv
)
1173 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
1174 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
1176 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
1179 sim_do_command(sd
," memory region 0x00000000,0x4000000") ;
1180 sim_do_command(sd
," memory region 0xE0000000,0x10000") ;
1185 if (kind
== SIM_OPEN_STANDALONE
)
1188 set_initial_gprs (); /* Reset the GPR registers. */
1190 /* Configure/verify the target byte order and other runtime
1191 configuration options. */
1192 if (sim_config (sd
) != SIM_RC_OK
)
1194 sim_module_uninstall (sd
);
1198 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
1200 /* Uninstall the modules to avoid memory leaks,
1201 file descriptor leaks, etc. */
1202 sim_module_uninstall (sd
);
1210 sim_close (sd
, quitting
)
1218 /* Load the device tree blob. */
1221 load_dtb (SIM_DESC sd
, const char *filename
)
1224 FILE *f
= fopen (filename
, "rb");
1226 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1229 printf ("WARNING: ``%s'' could not be opened.\n", filename
);
1232 fseek (f
, 0, SEEK_END
);
1234 fseek (f
, 0, SEEK_SET
);
1235 buf
= alloca (size
);
1236 if (size
!= fread (buf
, 1, size
, f
))
1238 printf ("ERROR: error reading ``%s''.\n", filename
);
1241 sim_core_write_buffer (sd
, scpu
, write_map
, buf
, 0xE0000000, size
);
1242 cpu
.asregs
.sregs
[9] = 0xE0000000;
1247 sim_load (sd
, prog
, abfd
, from_tty
)
1254 /* Do the right thing for ELF executables; this turns out to be
1255 just about the right thing for any object format that:
1256 - we crack using BFD routines
1257 - follows the traditional UNIX text/data/bss layout
1258 - calls the bss section ".bss". */
1260 extern bfd
* sim_load_file (); /* ??? Don't know where this should live. */
1265 handle
= bfd_openr (prog
, 0); /* could be "moxie" */
1269 printf("``%s'' could not be opened.\n", prog
);
1273 /* Makes sure that we have an object file, also cleans gets the
1274 section headers in place. */
1275 if (!bfd_check_format (handle
, bfd_object
))
1277 /* wasn't an object file */
1279 printf ("``%s'' is not appropriate object file.\n", prog
);
1283 /* Clean up after ourselves. */
1287 /* from sh -- dac */
1288 prog_bfd
= sim_load_file (sd
, myname
, callback
, prog
, abfd
,
1289 sim_kind
== SIM_OPEN_DEBUG
,
1291 if (prog_bfd
== NULL
)
1295 bfd_close (prog_bfd
);
1301 sim_create_inferior (sd
, prog_bfd
, argv
, env
)
1303 struct bfd
* prog_bfd
;
1309 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1311 /* Set the initial register set. */
1314 set_initial_gprs ();
1317 if (prog_bfd
!= NULL
)
1318 cpu
.asregs
.regs
[PC_REGNO
] = bfd_get_start_address (prog_bfd
);
1320 /* Copy args into target memory. */
1322 for (argc
= 0; avp
&& *avp
; avp
++)
1325 /* Target memory looks like this:
1326 0x00000000 zero word
1327 0x00000004 argc word
1328 0x00000008 start of argv
1330 0x0000???? end of argv
1331 0x0000???? zero word
1332 0x0000???? start of data pointed to by argv */
1334 wlat (scpu
, 0, 0, 0);
1335 wlat (scpu
, 0, 4, argc
);
1337 /* tp is the offset of our first argv data. */
1338 tp
= 4 + 4 + argc
* 4 + 4;
1340 for (i
= 0; i
< argc
; i
++)
1342 /* Set the argv value. */
1343 wlat (scpu
, 0, 4 + 4 + i
* 4, tp
);
1345 /* Store the string. */
1346 sim_core_write_buffer (sd
, scpu
, write_map
, argv
[i
],
1347 tp
, strlen(argv
[i
])+1);
1348 tp
+= strlen (argv
[i
]) + 1;
1351 wlat (scpu
, 0, 4 + 4 + i
* 4, 0);
1367 sim_do_command (sd
, cmd
)
1371 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
1373 "Error: \"%s\" is not a valid moxie simulator command.\n",
1378 sim_set_callbacks (ptr
)
1379 host_callback
* ptr
;
This page took 0.068963 seconds and 4 git commands to generate.