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);
371 cpu
.asregs
.regs
[a
] = av
+ v
;
376 int a
= (inst
>> 8) & 0xf;
377 unsigned av
= cpu
.asregs
.regs
[a
];
378 unsigned v
= (inst
& 0xff);
381 cpu
.asregs
.regs
[a
] = av
- v
;
386 int a
= (inst
>> 8) & 0xf;
387 unsigned v
= (inst
& 0xff);
390 cpu
.asregs
.regs
[a
] = cpu
.asregs
.sregs
[v
];
395 int a
= (inst
>> 8) & 0xf;
396 unsigned v
= (inst
& 0xff);
399 cpu
.asregs
.sregs
[v
] = cpu
.asregs
.regs
[a
];
404 cpu
.asregs
.exception
= SIGILL
;
411 /* This is a Form 1 instruction. */
412 int opcode
= inst
>> 8;
418 cpu
.asregs
.exception
= SIGILL
;
420 case 0x01: /* ldi.l (immediate) */
422 int reg
= (inst
>> 4) & 0xf;
425 unsigned int val
= EXTRACT_WORD(pc
+2);
426 cpu
.asregs
.regs
[reg
] = val
;
430 case 0x02: /* mov (register-to-register) */
432 int dest
= (inst
>> 4) & 0xf;
433 int src
= (inst
) & 0xf;
436 cpu
.asregs
.regs
[dest
] = cpu
.asregs
.regs
[src
];
439 case 0x03: /* jsra */
441 unsigned int fn
= EXTRACT_WORD(pc
+2);
442 unsigned int sp
= cpu
.asregs
.regs
[1];
445 /* Save a slot for the static chain. */
448 /* Push the return address. */
450 wlat (scpu
, opc
, sp
, pc
+ 6);
452 /* Push the current frame pointer. */
454 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
456 /* Uncache the stack pointer and set the pc and $fp. */
457 cpu
.asregs
.regs
[1] = sp
;
458 cpu
.asregs
.regs
[0] = sp
;
464 unsigned int sp
= cpu
.asregs
.regs
[0];
468 /* Pop the frame pointer. */
469 cpu
.asregs
.regs
[0] = rlat (scpu
, opc
, sp
);
472 /* Pop the return address. */
473 pc
= rlat (scpu
, opc
, sp
) - 2;
476 /* Skip over the static chain slot. */
479 /* Uncache the stack pointer. */
480 cpu
.asregs
.regs
[1] = sp
;
483 case 0x05: /* add.l */
485 int a
= (inst
>> 4) & 0xf;
487 unsigned av
= cpu
.asregs
.regs
[a
];
488 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;
501 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[b
]);
502 cpu
.asregs
.regs
[a
] = sp
;
507 int a
= (inst
>> 4) & 0xf;
509 int sp
= cpu
.asregs
.regs
[a
];
512 cpu
.asregs
.regs
[b
] = rlat (scpu
, opc
, sp
);
513 cpu
.asregs
.regs
[a
] = sp
+ 4;
516 case 0x08: /* lda.l */
518 int reg
= (inst
>> 4) & 0xf;
519 unsigned int addr
= EXTRACT_WORD(pc
+2);
522 cpu
.asregs
.regs
[reg
] = rlat (scpu
, opc
, addr
);
526 case 0x09: /* sta.l */
528 int reg
= (inst
>> 4) & 0xf;
529 unsigned int addr
= EXTRACT_WORD(pc
+2);
532 wlat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
536 case 0x0a: /* ld.l (register indirect) */
538 int src
= inst
& 0xf;
539 int dest
= (inst
>> 4) & 0xf;
543 xv
= cpu
.asregs
.regs
[src
];
544 cpu
.asregs
.regs
[dest
] = rlat (scpu
, opc
, xv
);
547 case 0x0b: /* st.l */
549 int dest
= (inst
>> 4) & 0xf;
550 int val
= inst
& 0xf;
553 wlat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
556 case 0x0c: /* ldo.l */
558 unsigned int addr
= EXTRACT_WORD(pc
+2);
559 int a
= (inst
>> 4) & 0xf;
563 addr
+= cpu
.asregs
.regs
[b
];
564 cpu
.asregs
.regs
[a
] = rlat (scpu
, opc
, addr
);
568 case 0x0d: /* sto.l */
570 unsigned int addr
= EXTRACT_WORD(pc
+2);
571 int a
= (inst
>> 4) & 0xf;
575 addr
+= cpu
.asregs
.regs
[a
];
576 wlat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
582 int a
= (inst
>> 4) & 0xf;
585 int va
= cpu
.asregs
.regs
[a
];
586 int vb
= cpu
.asregs
.regs
[b
];
593 cc
|= (va
< vb
? CC_LT
: 0);
594 cc
|= (va
> vb
? CC_GT
: 0);
595 cc
|= ((unsigned int) va
< (unsigned int) vb
? CC_LTU
: 0);
596 cc
|= ((unsigned int) va
> (unsigned int) vb
? CC_GTU
: 0);
604 case 0x10: /* sex.b */
606 int a
= (inst
>> 4) & 0xf;
608 signed char bv
= cpu
.asregs
.regs
[b
];
611 cpu
.asregs
.regs
[a
] = (int) bv
;
614 case 0x11: /* sex.s */
616 int a
= (inst
>> 4) & 0xf;
618 signed short bv
= cpu
.asregs
.regs
[b
];
621 cpu
.asregs
.regs
[a
] = (int) bv
;
624 case 0x12: /* zex.b */
626 int a
= (inst
>> 4) & 0xf;
628 signed char bv
= cpu
.asregs
.regs
[b
];
631 cpu
.asregs
.regs
[a
] = (int) bv
& 0xff;
634 case 0x13: /* zex.s */
636 int a
= (inst
>> 4) & 0xf;
638 signed short bv
= cpu
.asregs
.regs
[b
];
641 cpu
.asregs
.regs
[a
] = (int) bv
& 0xffff;
644 case 0x14: /* mul.x */
646 int a
= (inst
>> 4) & 0xf;
648 unsigned av
= cpu
.asregs
.regs
[a
];
649 unsigned bv
= cpu
.asregs
.regs
[b
];
651 (signed long long) av
* (signed long long) bv
;
654 cpu
.asregs
.regs
[a
] = r
>> 32;
657 case 0x15: /* umul.x */
659 int a
= (inst
>> 4) & 0xf;
661 unsigned av
= cpu
.asregs
.regs
[a
];
662 unsigned bv
= cpu
.asregs
.regs
[b
];
663 unsigned long long r
=
664 (unsigned long long) av
* (unsigned long long) bv
;
667 cpu
.asregs
.regs
[a
] = r
>> 32;
676 cpu
.asregs
.exception
= SIGILL
;
681 unsigned int fn
= cpu
.asregs
.regs
[(inst
>> 4) & 0xf];
682 unsigned int sp
= cpu
.asregs
.regs
[1];
686 /* Save a slot for the static chain. */
689 /* Push the return address. */
691 wlat (scpu
, opc
, sp
, pc
+ 2);
693 /* Push the current frame pointer. */
695 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
697 /* Uncache the stack pointer and set the fp & pc. */
698 cpu
.asregs
.regs
[1] = sp
;
699 cpu
.asregs
.regs
[0] = sp
;
703 case 0x1a: /* jmpa */
705 unsigned int tgt
= EXTRACT_WORD(pc
+2);
711 case 0x1b: /* ldi.b (immediate) */
713 int reg
= (inst
>> 4) & 0xf;
714 unsigned int val
= EXTRACT_WORD(pc
+2);
717 cpu
.asregs
.regs
[reg
] = val
;
721 case 0x1c: /* ld.b (register indirect) */
723 int src
= inst
& 0xf;
724 int dest
= (inst
>> 4) & 0xf;
728 xv
= cpu
.asregs
.regs
[src
];
729 cpu
.asregs
.regs
[dest
] = rbat (scpu
, opc
, xv
);
732 case 0x1d: /* lda.b */
734 int reg
= (inst
>> 4) & 0xf;
735 unsigned int addr
= EXTRACT_WORD(pc
+2);
738 cpu
.asregs
.regs
[reg
] = rbat (scpu
, opc
, addr
);
742 case 0x1e: /* st.b */
744 int dest
= (inst
>> 4) & 0xf;
745 int val
= inst
& 0xf;
748 wbat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
751 case 0x1f: /* sta.b */
753 int reg
= (inst
>> 4) & 0xf;
754 unsigned int addr
= EXTRACT_WORD(pc
+2);
757 wbat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
761 case 0x20: /* ldi.s (immediate) */
763 int reg
= (inst
>> 4) & 0xf;
765 unsigned int val
= EXTRACT_WORD(pc
+2);
768 cpu
.asregs
.regs
[reg
] = val
;
772 case 0x21: /* ld.s (register indirect) */
774 int src
= inst
& 0xf;
775 int dest
= (inst
>> 4) & 0xf;
779 xv
= cpu
.asregs
.regs
[src
];
780 cpu
.asregs
.regs
[dest
] = rsat (scpu
, opc
, xv
);
783 case 0x22: /* lda.s */
785 int reg
= (inst
>> 4) & 0xf;
786 unsigned int addr
= EXTRACT_WORD(pc
+2);
789 cpu
.asregs
.regs
[reg
] = rsat (scpu
, opc
, addr
);
793 case 0x23: /* st.s */
795 int dest
= (inst
>> 4) & 0xf;
796 int val
= inst
& 0xf;
799 wsat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
802 case 0x24: /* sta.s */
804 int reg
= (inst
>> 4) & 0xf;
805 unsigned int addr
= EXTRACT_WORD(pc
+2);
808 wsat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
814 int reg
= (inst
>> 4) & 0xf;
817 pc
= cpu
.asregs
.regs
[reg
] - 2;
822 int a
= (inst
>> 4) & 0xf;
827 av
= cpu
.asregs
.regs
[a
];
828 bv
= cpu
.asregs
.regs
[b
];
829 cpu
.asregs
.regs
[a
] = av
& bv
;
832 case 0x27: /* lshr */
834 int a
= (inst
>> 4) & 0xf;
836 int av
= cpu
.asregs
.regs
[a
];
837 int bv
= cpu
.asregs
.regs
[b
];
840 cpu
.asregs
.regs
[a
] = (unsigned) ((unsigned) av
>> bv
);
843 case 0x28: /* ashl */
845 int a
= (inst
>> 4) & 0xf;
847 int av
= cpu
.asregs
.regs
[a
];
848 int bv
= cpu
.asregs
.regs
[b
];
851 cpu
.asregs
.regs
[a
] = av
<< bv
;
854 case 0x29: /* sub.l */
856 int a
= (inst
>> 4) & 0xf;
858 unsigned av
= cpu
.asregs
.regs
[a
];
859 unsigned bv
= cpu
.asregs
.regs
[b
];
862 cpu
.asregs
.regs
[a
] = av
- bv
;
867 int a
= (inst
>> 4) & 0xf;
869 int bv
= cpu
.asregs
.regs
[b
];
872 cpu
.asregs
.regs
[a
] = - bv
;
877 int a
= (inst
>> 4) & 0xf;
882 av
= cpu
.asregs
.regs
[a
];
883 bv
= cpu
.asregs
.regs
[b
];
884 cpu
.asregs
.regs
[a
] = av
| bv
;
889 int a
= (inst
>> 4) & 0xf;
891 int bv
= cpu
.asregs
.regs
[b
];
894 cpu
.asregs
.regs
[a
] = 0xffffffff ^ bv
;
897 case 0x2d: /* ashr */
899 int a
= (inst
>> 4) & 0xf;
901 int av
= cpu
.asregs
.regs
[a
];
902 int bv
= cpu
.asregs
.regs
[b
];
905 cpu
.asregs
.regs
[a
] = av
>> bv
;
910 int a
= (inst
>> 4) & 0xf;
915 av
= cpu
.asregs
.regs
[a
];
916 bv
= cpu
.asregs
.regs
[b
];
917 cpu
.asregs
.regs
[a
] = av
^ bv
;
920 case 0x2f: /* mul.l */
922 int a
= (inst
>> 4) & 0xf;
924 unsigned av
= cpu
.asregs
.regs
[a
];
925 unsigned bv
= cpu
.asregs
.regs
[b
];
928 cpu
.asregs
.regs
[a
] = av
* bv
;
933 unsigned int inum
= EXTRACT_WORD(pc
+2);
936 /* Set the special registers appropriately. */
937 cpu
.asregs
.sregs
[2] = 3; /* MOXIE_EX_SWI */
938 cpu
.asregs
.sregs
[3] = inum
;
941 case 0x1: /* SYS_exit */
943 cpu
.asregs
.exception
= SIGQUIT
;
946 case 0x2: /* SYS_open */
949 int mode
= (int) convert_target_flags ((unsigned) cpu
.asregs
.regs
[3]);
950 int perm
= (int) cpu
.asregs
.regs
[4];
951 int fd
= open (fname
, mode
, perm
);
952 sim_core_read_buffer (sd
, scpu
, read_map
, fname
,
953 cpu
.asregs
.regs
[2], 1024);
954 /* FIXME - set errno */
955 cpu
.asregs
.regs
[2] = fd
;
958 case 0x4: /* SYS_read */
960 int fd
= cpu
.asregs
.regs
[2];
961 unsigned len
= (unsigned) cpu
.asregs
.regs
[4];
962 char *buf
= malloc (len
);
963 cpu
.asregs
.regs
[2] = read (fd
, buf
, len
);
964 sim_core_write_buffer (sd
, scpu
, write_map
, buf
,
965 cpu
.asregs
.regs
[3], len
);
969 case 0x5: /* SYS_write */
972 /* String length is at 0x12($fp) */
973 unsigned count
, len
= (unsigned) cpu
.asregs
.regs
[4];
975 sim_core_read_buffer (sd
, scpu
, read_map
, str
,
976 cpu
.asregs
.regs
[3], len
);
977 count
= write (cpu
.asregs
.regs
[2], str
, len
);
979 cpu
.asregs
.regs
[2] = count
;
982 case 0xffffffff: /* Linux System Call */
984 unsigned int handler
= cpu
.asregs
.sregs
[1];
985 unsigned int sp
= cpu
.asregs
.regs
[1];
987 /* Save a slot for the static chain. */
990 /* Push the return address. */
992 wlat (scpu
, opc
, sp
, pc
+ 6);
994 /* Push the current frame pointer. */
996 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
998 /* Uncache the stack pointer and set the fp & pc. */
999 cpu
.asregs
.regs
[1] = sp
;
1000 cpu
.asregs
.regs
[0] = sp
;
1009 case 0x31: /* div.l */
1011 int a
= (inst
>> 4) & 0xf;
1013 int av
= cpu
.asregs
.regs
[a
];
1014 int bv
= cpu
.asregs
.regs
[b
];
1017 cpu
.asregs
.regs
[a
] = av
/ bv
;
1020 case 0x32: /* udiv.l */
1022 int a
= (inst
>> 4) & 0xf;
1024 unsigned int av
= cpu
.asregs
.regs
[a
];
1025 unsigned int bv
= cpu
.asregs
.regs
[b
];
1028 cpu
.asregs
.regs
[a
] = (av
/ bv
);
1031 case 0x33: /* mod.l */
1033 int a
= (inst
>> 4) & 0xf;
1035 int av
= cpu
.asregs
.regs
[a
];
1036 int bv
= cpu
.asregs
.regs
[b
];
1039 cpu
.asregs
.regs
[a
] = av
% bv
;
1042 case 0x34: /* umod.l */
1044 int a
= (inst
>> 4) & 0xf;
1046 unsigned int av
= cpu
.asregs
.regs
[a
];
1047 unsigned int bv
= cpu
.asregs
.regs
[b
];
1050 cpu
.asregs
.regs
[a
] = (av
% bv
);
1053 case 0x35: /* brk */
1055 cpu
.asregs
.exception
= SIGTRAP
;
1056 pc
-= 2; /* Adjust pc */
1058 case 0x36: /* ldo.b */
1060 unsigned int addr
= EXTRACT_WORD(pc
+2);
1061 int a
= (inst
>> 4) & 0xf;
1065 addr
+= cpu
.asregs
.regs
[b
];
1066 cpu
.asregs
.regs
[a
] = rbat (scpu
, opc
, addr
);
1070 case 0x37: /* sto.b */
1072 unsigned int addr
= EXTRACT_WORD(pc
+2);
1073 int a
= (inst
>> 4) & 0xf;
1077 addr
+= cpu
.asregs
.regs
[a
];
1078 wbat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
1082 case 0x38: /* ldo.s */
1084 unsigned int addr
= EXTRACT_WORD(pc
+2);
1085 int a
= (inst
>> 4) & 0xf;
1089 addr
+= cpu
.asregs
.regs
[b
];
1090 cpu
.asregs
.regs
[a
] = rsat (scpu
, opc
, addr
);
1094 case 0x39: /* sto.s */
1096 unsigned int addr
= EXTRACT_WORD(pc
+2);
1097 int a
= (inst
>> 4) & 0xf;
1101 addr
+= cpu
.asregs
.regs
[a
];
1102 wsat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
1109 cpu
.asregs
.exception
= SIGILL
;
1117 } while (!cpu
.asregs
.exception
);
1119 /* Hide away the things we've cached while executing. */
1120 cpu
.asregs
.regs
[PC_REGNO
] = pc
;
1121 cpu
.asregs
.insts
+= insts
; /* instructions done ... */
1125 sim_write (sd
, addr
, buffer
, size
)
1128 const unsigned char * buffer
;
1131 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1133 sim_core_write_buffer (sd
, scpu
, write_map
, buffer
, addr
, size
);
1139 sim_read (sd
, addr
, buffer
, size
)
1142 unsigned char * buffer
;
1145 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1147 sim_core_read_buffer (sd
, scpu
, read_map
, buffer
, addr
, size
);
1154 sim_store_register (sd
, rn
, memory
, length
)
1157 unsigned char * memory
;
1160 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1166 /* misalignment safe */
1167 ival
= moxie_extract_unsigned_integer (memory
, 4);
1168 cpu
.asints
[rn
] = ival
;
1178 sim_fetch_register (sd
, rn
, memory
, length
)
1181 unsigned char * memory
;
1184 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1188 long ival
= cpu
.asints
[rn
];
1190 /* misalignment-safe */
1191 moxie_store_unsigned_integer (memory
, 4, ival
);
1206 tracefile
= fopen("trace.csv", "wb");
1210 sim_resume (sd
, 0, 0);
1218 sim_stop_reason (sd
, reason
, sigrc
)
1220 enum sim_stop
* reason
;
1223 if (cpu
.asregs
.exception
== SIGQUIT
)
1225 * reason
= sim_exited
;
1226 * sigrc
= cpu
.asregs
.regs
[2];
1230 * reason
= sim_stopped
;
1231 * sigrc
= cpu
.asregs
.exception
;
1240 cpu
.asregs
.exception
= SIGINT
;
1246 sim_info (sd
, verbose
)
1250 callback
->printf_filtered (callback
, "\n\n# instructions executed %llu\n",
1256 sim_open (kind
, cb
, abfd
, argv
)
1262 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
1263 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
1265 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
1268 sim_do_command(sd
," memory region 0x00000000,0x4000000") ;
1269 sim_do_command(sd
," memory region 0xE0000000,0x10000") ;
1274 if (kind
== SIM_OPEN_STANDALONE
)
1277 set_initial_gprs (); /* Reset the GPR registers. */
1279 /* Configure/verify the target byte order and other runtime
1280 configuration options. */
1281 if (sim_config (sd
) != SIM_RC_OK
)
1283 sim_module_uninstall (sd
);
1287 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
1289 /* Uninstall the modules to avoid memory leaks,
1290 file descriptor leaks, etc. */
1291 sim_module_uninstall (sd
);
1299 sim_close (sd
, quitting
)
1307 /* Load the device tree blob. */
1310 load_dtb (SIM_DESC sd
, const char *filename
)
1313 FILE *f
= fopen (filename
, "rb");
1315 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1318 printf ("WARNING: ``%s'' could not be opened.\n", filename
);
1321 fseek (f
, 0, SEEK_END
);
1323 fseek (f
, 0, SEEK_SET
);
1324 buf
= alloca (size
);
1325 if (size
!= fread (buf
, 1, size
, f
))
1327 printf ("ERROR: error reading ``%s''.\n", filename
);
1330 sim_core_write_buffer (sd
, scpu
, write_map
, buf
, 0xE0000000, size
);
1331 cpu
.asregs
.sregs
[9] = 0xE0000000;
1336 sim_load (sd
, prog
, abfd
, from_tty
)
1343 /* Do the right thing for ELF executables; this turns out to be
1344 just about the right thing for any object format that:
1345 - we crack using BFD routines
1346 - follows the traditional UNIX text/data/bss layout
1347 - calls the bss section ".bss". */
1349 extern bfd
* sim_load_file (); /* ??? Don't know where this should live. */
1354 handle
= bfd_openr (prog
, 0); /* could be "moxie" */
1358 printf("``%s'' could not be opened.\n", prog
);
1362 /* Makes sure that we have an object file, also cleans gets the
1363 section headers in place. */
1364 if (!bfd_check_format (handle
, bfd_object
))
1366 /* wasn't an object file */
1368 printf ("``%s'' is not appropriate object file.\n", prog
);
1372 /* Clean up after ourselves. */
1376 /* from sh -- dac */
1377 prog_bfd
= sim_load_file (sd
, myname
, callback
, prog
, abfd
,
1378 sim_kind
== SIM_OPEN_DEBUG
,
1380 if (prog_bfd
== NULL
)
1384 bfd_close (prog_bfd
);
1390 sim_create_inferior (sd
, prog_bfd
, argv
, env
)
1392 struct bfd
* prog_bfd
;
1398 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1400 /* Set the initial register set. */
1403 set_initial_gprs ();
1406 if (prog_bfd
!= NULL
)
1407 cpu
.asregs
.regs
[PC_REGNO
] = bfd_get_start_address (prog_bfd
);
1409 /* Copy args into target memory. */
1411 for (argc
= 0; avp
&& *avp
; avp
++)
1414 /* Target memory looks like this:
1415 0x00000000 zero word
1416 0x00000004 argc word
1417 0x00000008 start of argv
1419 0x0000???? end of argv
1420 0x0000???? zero word
1421 0x0000???? start of data pointed to by argv */
1423 wlat (scpu
, 0, 0, 0);
1424 wlat (scpu
, 0, 4, argc
);
1426 /* tp is the offset of our first argv data. */
1427 tp
= 4 + 4 + argc
* 4 + 4;
1429 for (i
= 0; i
< argc
; i
++)
1431 /* Set the argv value. */
1432 wlat (scpu
, 0, 4 + 4 + i
* 4, tp
);
1434 /* Store the string. */
1435 sim_core_write_buffer (sd
, scpu
, write_map
, argv
[i
],
1436 tp
, strlen(argv
[i
])+1);
1437 tp
+= strlen (argv
[i
]) + 1;
1440 wlat (scpu
, 0, 4 + 4 + i
* 4, 0);
1456 sim_do_command (sd
, cmd
)
1460 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
1462 "Error: \"%s\" is not a valid moxie simulator command.\n",
1467 sim_set_callbacks (ptr
)
1468 host_callback
* ptr
;
This page took 0.060334 seconds and 5 git commands to generate.