1 /* Simulator for the moxie processor
2 Copyright (C) 2008-2015 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)))
53 #define EXTRACT_OFFSET(addr) \
56 ((sim_core_read_aligned_1 (scpu, cia, read_map, addr) << 8) \
57 + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+1))) << 16) >> 16)
60 moxie_extract_unsigned_integer (addr
, len
)
66 unsigned char * startaddr
= (unsigned char *)addr
;
67 unsigned char * endaddr
= startaddr
+ len
;
69 if (len
> (int) sizeof (unsigned long))
70 printf ("That operation is not available on integers of more than %d bytes.",
71 sizeof (unsigned long));
73 /* Start at the most significant end of the integer, and work towards
74 the least significant. */
77 for (p
= endaddr
; p
> startaddr
;)
78 retval
= (retval
<< 8) | * -- p
;
84 moxie_store_unsigned_integer (addr
, len
, val
)
90 unsigned char * startaddr
= (unsigned char *)addr
;
91 unsigned char * endaddr
= startaddr
+ len
;
93 for (p
= endaddr
; p
> startaddr
;)
100 /* moxie register names. */
101 static const char *reg_names
[16] =
102 { "$fp", "$sp", "$r0", "$r1", "$r2", "$r3", "$r4", "$r5",
103 "$r6", "$r7", "$r8", "$r9", "$r10", "$r11", "$r12", "$r13" };
105 /* The machine state.
107 This state is maintained in host byte order. The fetch/store
108 register functions must translate between host byte order and the
109 target processor byte order. Keeping this data in target byte
110 order simplifies the register read/write functions. Keeping this
111 data in native order improves the performance of the simulator.
112 Simulation speed is deemed more important. */
114 #define NUM_MOXIE_REGS 17 /* Including PC */
115 #define NUM_MOXIE_SREGS 256 /* The special registers */
118 /* The ordering of the moxie_regset structure is matched in the
119 gdb/config/moxie/tm-moxie.h file in the REGISTER_NAMES macro. */
122 word regs
[NUM_MOXIE_REGS
+ 1]; /* primary registers */
123 word sregs
[256]; /* special registers */
124 word cc
; /* the condition code reg */
126 unsigned long long insts
; /* instruction counter */
137 struct moxie_regset asregs
;
138 word asints
[1]; /* but accessed larger... */
142 static SIM_OPEN_KIND sim_kind
;
143 static int issue_messages
= 0;
156 /* Set up machine just out of reset. */
157 cpu
.asregs
.regs
[PC_REGNO
] = 0;
159 /* Clean out the register contents. */
160 for (i
= 0; i
< NUM_MOXIE_REGS
; i
++)
161 cpu
.asregs
.regs
[i
] = 0;
162 for (i
= 0; i
< NUM_MOXIE_SREGS
; i
++)
163 cpu
.asregs
.sregs
[i
] = 0;
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
;
261 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
262 address_word cia
= CIA_GET (scpu
);
264 cpu
.asregs
.exception
= step
? SIGTRAP
: 0;
265 pc
= cpu
.asregs
.regs
[PC_REGNO
];
266 insts
= cpu
.asregs
.insts
;
268 /* Run instructions here. */
273 /* Fetch the instruction at pc. */
274 inst
= (sim_core_read_aligned_1 (scpu
, cia
, read_map
, pc
) << 8)
275 + sim_core_read_aligned_1 (scpu
, cia
, read_map
, pc
+1);
277 /* Decode instruction. */
278 if (inst
& (1 << 15))
280 if (inst
& (1 << 14))
282 /* This is a Form 3 instruction. */
283 int opcode
= (inst
>> 10 & 0xf);
290 if (cpu
.asregs
.cc
& CC_EQ
)
291 pc
+= INST2OFFSET(inst
);
297 if (! (cpu
.asregs
.cc
& CC_EQ
))
298 pc
+= INST2OFFSET(inst
);
304 if (cpu
.asregs
.cc
& CC_LT
)
305 pc
+= INST2OFFSET(inst
);
310 if (cpu
.asregs
.cc
& CC_GT
)
311 pc
+= INST2OFFSET(inst
);
314 case 0x04: /* bltu */
317 if (cpu
.asregs
.cc
& CC_LTU
)
318 pc
+= INST2OFFSET(inst
);
321 case 0x05: /* bgtu */
324 if (cpu
.asregs
.cc
& CC_GTU
)
325 pc
+= INST2OFFSET(inst
);
331 if (cpu
.asregs
.cc
& (CC_GT
| CC_EQ
))
332 pc
+= INST2OFFSET(inst
);
338 if (cpu
.asregs
.cc
& (CC_LT
| CC_EQ
))
339 pc
+= INST2OFFSET(inst
);
342 case 0x08: /* bgeu */
345 if (cpu
.asregs
.cc
& (CC_GTU
| CC_EQ
))
346 pc
+= INST2OFFSET(inst
);
349 case 0x09: /* bleu */
352 if (cpu
.asregs
.cc
& (CC_LTU
| CC_EQ
))
353 pc
+= INST2OFFSET(inst
);
359 cpu
.asregs
.exception
= SIGILL
;
366 /* This is a Form 2 instruction. */
367 int opcode
= (inst
>> 12 & 0x3);
372 int a
= (inst
>> 8) & 0xf;
373 unsigned av
= cpu
.asregs
.regs
[a
];
374 unsigned v
= (inst
& 0xff);
377 cpu
.asregs
.regs
[a
] = av
+ v
;
382 int a
= (inst
>> 8) & 0xf;
383 unsigned av
= cpu
.asregs
.regs
[a
];
384 unsigned v
= (inst
& 0xff);
387 cpu
.asregs
.regs
[a
] = av
- v
;
392 int a
= (inst
>> 8) & 0xf;
393 unsigned v
= (inst
& 0xff);
396 cpu
.asregs
.regs
[a
] = cpu
.asregs
.sregs
[v
];
401 int a
= (inst
>> 8) & 0xf;
402 unsigned v
= (inst
& 0xff);
405 cpu
.asregs
.sregs
[v
] = cpu
.asregs
.regs
[a
];
410 cpu
.asregs
.exception
= SIGILL
;
417 /* This is a Form 1 instruction. */
418 int opcode
= inst
>> 8;
424 cpu
.asregs
.exception
= SIGILL
;
426 case 0x01: /* ldi.l (immediate) */
428 int reg
= (inst
>> 4) & 0xf;
431 unsigned int val
= EXTRACT_WORD(pc
+2);
432 cpu
.asregs
.regs
[reg
] = val
;
436 case 0x02: /* mov (register-to-register) */
438 int dest
= (inst
>> 4) & 0xf;
439 int src
= (inst
) & 0xf;
442 cpu
.asregs
.regs
[dest
] = cpu
.asregs
.regs
[src
];
445 case 0x03: /* jsra */
447 unsigned int fn
= EXTRACT_WORD(pc
+2);
448 unsigned int sp
= cpu
.asregs
.regs
[1];
451 /* Save a slot for the static chain. */
454 /* Push the return address. */
456 wlat (scpu
, opc
, sp
, pc
+ 6);
458 /* Push the current frame pointer. */
460 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
462 /* Uncache the stack pointer and set the pc and $fp. */
463 cpu
.asregs
.regs
[1] = sp
;
464 cpu
.asregs
.regs
[0] = sp
;
470 unsigned int sp
= cpu
.asregs
.regs
[0];
474 /* Pop the frame pointer. */
475 cpu
.asregs
.regs
[0] = rlat (scpu
, opc
, sp
);
478 /* Pop the return address. */
479 pc
= rlat (scpu
, opc
, sp
) - 2;
482 /* Skip over the static chain slot. */
485 /* Uncache the stack pointer. */
486 cpu
.asregs
.regs
[1] = sp
;
489 case 0x05: /* add.l */
491 int a
= (inst
>> 4) & 0xf;
493 unsigned av
= cpu
.asregs
.regs
[a
];
494 unsigned bv
= cpu
.asregs
.regs
[b
];
497 cpu
.asregs
.regs
[a
] = av
+ bv
;
500 case 0x06: /* push */
502 int a
= (inst
>> 4) & 0xf;
504 int sp
= cpu
.asregs
.regs
[a
] - 4;
507 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[b
]);
508 cpu
.asregs
.regs
[a
] = sp
;
513 int a
= (inst
>> 4) & 0xf;
515 int sp
= cpu
.asregs
.regs
[a
];
518 cpu
.asregs
.regs
[b
] = rlat (scpu
, opc
, sp
);
519 cpu
.asregs
.regs
[a
] = sp
+ 4;
522 case 0x08: /* lda.l */
524 int reg
= (inst
>> 4) & 0xf;
525 unsigned int addr
= EXTRACT_WORD(pc
+2);
528 cpu
.asregs
.regs
[reg
] = rlat (scpu
, opc
, addr
);
532 case 0x09: /* sta.l */
534 int reg
= (inst
>> 4) & 0xf;
535 unsigned int addr
= EXTRACT_WORD(pc
+2);
538 wlat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
542 case 0x0a: /* ld.l (register indirect) */
544 int src
= inst
& 0xf;
545 int dest
= (inst
>> 4) & 0xf;
549 xv
= cpu
.asregs
.regs
[src
];
550 cpu
.asregs
.regs
[dest
] = rlat (scpu
, opc
, xv
);
553 case 0x0b: /* st.l */
555 int dest
= (inst
>> 4) & 0xf;
556 int val
= inst
& 0xf;
559 wlat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
562 case 0x0c: /* ldo.l */
564 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
565 int a
= (inst
>> 4) & 0xf;
569 addr
+= cpu
.asregs
.regs
[b
];
570 cpu
.asregs
.regs
[a
] = rlat (scpu
, opc
, addr
);
574 case 0x0d: /* sto.l */
576 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
577 int a
= (inst
>> 4) & 0xf;
581 addr
+= cpu
.asregs
.regs
[a
];
582 wlat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
588 int a
= (inst
>> 4) & 0xf;
591 int va
= cpu
.asregs
.regs
[a
];
592 int vb
= cpu
.asregs
.regs
[b
];
599 cc
|= (va
< vb
? CC_LT
: 0);
600 cc
|= (va
> vb
? CC_GT
: 0);
601 cc
|= ((unsigned int) va
< (unsigned int) vb
? CC_LTU
: 0);
602 cc
|= ((unsigned int) va
> (unsigned int) vb
? CC_GTU
: 0);
610 case 0x10: /* sex.b */
612 int a
= (inst
>> 4) & 0xf;
614 signed char bv
= cpu
.asregs
.regs
[b
];
617 cpu
.asregs
.regs
[a
] = (int) bv
;
620 case 0x11: /* sex.s */
622 int a
= (inst
>> 4) & 0xf;
624 signed short bv
= cpu
.asregs
.regs
[b
];
627 cpu
.asregs
.regs
[a
] = (int) bv
;
630 case 0x12: /* zex.b */
632 int a
= (inst
>> 4) & 0xf;
634 signed char bv
= cpu
.asregs
.regs
[b
];
637 cpu
.asregs
.regs
[a
] = (int) bv
& 0xff;
640 case 0x13: /* zex.s */
642 int a
= (inst
>> 4) & 0xf;
644 signed short bv
= cpu
.asregs
.regs
[b
];
647 cpu
.asregs
.regs
[a
] = (int) bv
& 0xffff;
650 case 0x14: /* umul.x */
652 int a
= (inst
>> 4) & 0xf;
654 unsigned av
= cpu
.asregs
.regs
[a
];
655 unsigned bv
= cpu
.asregs
.regs
[b
];
656 unsigned long long r
=
657 (unsigned long long) av
* (unsigned long long) bv
;
660 cpu
.asregs
.regs
[a
] = r
>> 32;
663 case 0x15: /* mul.x */
665 int a
= (inst
>> 4) & 0xf;
667 unsigned av
= cpu
.asregs
.regs
[a
];
668 unsigned bv
= cpu
.asregs
.regs
[b
];
670 (signed long long) av
* (signed long long) bv
;
673 cpu
.asregs
.regs
[a
] = r
>> 32;
682 cpu
.asregs
.exception
= SIGILL
;
687 unsigned int fn
= cpu
.asregs
.regs
[(inst
>> 4) & 0xf];
688 unsigned int sp
= cpu
.asregs
.regs
[1];
692 /* Save a slot for the static chain. */
695 /* Push the return address. */
697 wlat (scpu
, opc
, sp
, pc
+ 2);
699 /* Push the current frame pointer. */
701 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
703 /* Uncache the stack pointer and set the fp & pc. */
704 cpu
.asregs
.regs
[1] = sp
;
705 cpu
.asregs
.regs
[0] = sp
;
709 case 0x1a: /* jmpa */
711 unsigned int tgt
= EXTRACT_WORD(pc
+2);
717 case 0x1b: /* ldi.b (immediate) */
719 int reg
= (inst
>> 4) & 0xf;
720 unsigned int val
= EXTRACT_WORD(pc
+2);
723 cpu
.asregs
.regs
[reg
] = val
;
727 case 0x1c: /* ld.b (register indirect) */
729 int src
= inst
& 0xf;
730 int dest
= (inst
>> 4) & 0xf;
734 xv
= cpu
.asregs
.regs
[src
];
735 cpu
.asregs
.regs
[dest
] = rbat (scpu
, opc
, xv
);
738 case 0x1d: /* lda.b */
740 int reg
= (inst
>> 4) & 0xf;
741 unsigned int addr
= EXTRACT_WORD(pc
+2);
744 cpu
.asregs
.regs
[reg
] = rbat (scpu
, opc
, addr
);
748 case 0x1e: /* st.b */
750 int dest
= (inst
>> 4) & 0xf;
751 int val
= inst
& 0xf;
754 wbat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
757 case 0x1f: /* sta.b */
759 int reg
= (inst
>> 4) & 0xf;
760 unsigned int addr
= EXTRACT_WORD(pc
+2);
763 wbat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
767 case 0x20: /* ldi.s (immediate) */
769 int reg
= (inst
>> 4) & 0xf;
771 unsigned int val
= EXTRACT_WORD(pc
+2);
774 cpu
.asregs
.regs
[reg
] = val
;
778 case 0x21: /* ld.s (register indirect) */
780 int src
= inst
& 0xf;
781 int dest
= (inst
>> 4) & 0xf;
785 xv
= cpu
.asregs
.regs
[src
];
786 cpu
.asregs
.regs
[dest
] = rsat (scpu
, opc
, xv
);
789 case 0x22: /* lda.s */
791 int reg
= (inst
>> 4) & 0xf;
792 unsigned int addr
= EXTRACT_WORD(pc
+2);
795 cpu
.asregs
.regs
[reg
] = rsat (scpu
, opc
, addr
);
799 case 0x23: /* st.s */
801 int dest
= (inst
>> 4) & 0xf;
802 int val
= inst
& 0xf;
805 wsat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
808 case 0x24: /* sta.s */
810 int reg
= (inst
>> 4) & 0xf;
811 unsigned int addr
= EXTRACT_WORD(pc
+2);
814 wsat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
820 int reg
= (inst
>> 4) & 0xf;
823 pc
= cpu
.asregs
.regs
[reg
] - 2;
828 int a
= (inst
>> 4) & 0xf;
833 av
= cpu
.asregs
.regs
[a
];
834 bv
= cpu
.asregs
.regs
[b
];
835 cpu
.asregs
.regs
[a
] = av
& bv
;
838 case 0x27: /* lshr */
840 int a
= (inst
>> 4) & 0xf;
842 int av
= cpu
.asregs
.regs
[a
];
843 int bv
= cpu
.asregs
.regs
[b
];
846 cpu
.asregs
.regs
[a
] = (unsigned) ((unsigned) av
>> bv
);
849 case 0x28: /* ashl */
851 int a
= (inst
>> 4) & 0xf;
853 int av
= cpu
.asregs
.regs
[a
];
854 int bv
= cpu
.asregs
.regs
[b
];
857 cpu
.asregs
.regs
[a
] = av
<< bv
;
860 case 0x29: /* sub.l */
862 int a
= (inst
>> 4) & 0xf;
864 unsigned av
= cpu
.asregs
.regs
[a
];
865 unsigned bv
= cpu
.asregs
.regs
[b
];
868 cpu
.asregs
.regs
[a
] = av
- bv
;
873 int a
= (inst
>> 4) & 0xf;
875 int bv
= cpu
.asregs
.regs
[b
];
878 cpu
.asregs
.regs
[a
] = - bv
;
883 int a
= (inst
>> 4) & 0xf;
888 av
= cpu
.asregs
.regs
[a
];
889 bv
= cpu
.asregs
.regs
[b
];
890 cpu
.asregs
.regs
[a
] = av
| bv
;
895 int a
= (inst
>> 4) & 0xf;
897 int bv
= cpu
.asregs
.regs
[b
];
900 cpu
.asregs
.regs
[a
] = 0xffffffff ^ bv
;
903 case 0x2d: /* ashr */
905 int a
= (inst
>> 4) & 0xf;
907 int av
= cpu
.asregs
.regs
[a
];
908 int bv
= cpu
.asregs
.regs
[b
];
911 cpu
.asregs
.regs
[a
] = av
>> bv
;
916 int a
= (inst
>> 4) & 0xf;
921 av
= cpu
.asregs
.regs
[a
];
922 bv
= cpu
.asregs
.regs
[b
];
923 cpu
.asregs
.regs
[a
] = av
^ bv
;
926 case 0x2f: /* mul.l */
928 int a
= (inst
>> 4) & 0xf;
930 unsigned av
= cpu
.asregs
.regs
[a
];
931 unsigned bv
= cpu
.asregs
.regs
[b
];
934 cpu
.asregs
.regs
[a
] = av
* bv
;
939 unsigned int inum
= EXTRACT_WORD(pc
+2);
942 /* Set the special registers appropriately. */
943 cpu
.asregs
.sregs
[2] = 3; /* MOXIE_EX_SWI */
944 cpu
.asregs
.sregs
[3] = inum
;
947 case 0x1: /* SYS_exit */
949 cpu
.asregs
.exception
= SIGQUIT
;
952 case 0x2: /* SYS_open */
955 int mode
= (int) convert_target_flags ((unsigned) cpu
.asregs
.regs
[3]);
956 int perm
= (int) cpu
.asregs
.regs
[4];
957 int fd
= open (fname
, mode
, perm
);
958 sim_core_read_buffer (sd
, scpu
, read_map
, fname
,
959 cpu
.asregs
.regs
[2], 1024);
960 /* FIXME - set errno */
961 cpu
.asregs
.regs
[2] = fd
;
964 case 0x4: /* SYS_read */
966 int fd
= cpu
.asregs
.regs
[2];
967 unsigned len
= (unsigned) cpu
.asregs
.regs
[4];
968 char *buf
= malloc (len
);
969 cpu
.asregs
.regs
[2] = read (fd
, buf
, len
);
970 sim_core_write_buffer (sd
, scpu
, write_map
, buf
,
971 cpu
.asregs
.regs
[3], len
);
975 case 0x5: /* SYS_write */
978 /* String length is at 0x12($fp) */
979 unsigned count
, len
= (unsigned) cpu
.asregs
.regs
[4];
981 sim_core_read_buffer (sd
, scpu
, read_map
, str
,
982 cpu
.asregs
.regs
[3], len
);
983 count
= write (cpu
.asregs
.regs
[2], str
, len
);
985 cpu
.asregs
.regs
[2] = count
;
988 case 0xffffffff: /* Linux System Call */
990 unsigned int handler
= cpu
.asregs
.sregs
[1];
991 unsigned int sp
= cpu
.asregs
.regs
[1];
993 /* Save a slot for the static chain. */
996 /* Push the return address. */
998 wlat (scpu
, opc
, sp
, pc
+ 6);
1000 /* Push the current frame pointer. */
1002 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
1004 /* Uncache the stack pointer and set the fp & pc. */
1005 cpu
.asregs
.regs
[1] = sp
;
1006 cpu
.asregs
.regs
[0] = sp
;
1015 case 0x31: /* div.l */
1017 int a
= (inst
>> 4) & 0xf;
1019 int av
= cpu
.asregs
.regs
[a
];
1020 int bv
= cpu
.asregs
.regs
[b
];
1023 cpu
.asregs
.regs
[a
] = av
/ bv
;
1026 case 0x32: /* udiv.l */
1028 int a
= (inst
>> 4) & 0xf;
1030 unsigned int av
= cpu
.asregs
.regs
[a
];
1031 unsigned int bv
= cpu
.asregs
.regs
[b
];
1034 cpu
.asregs
.regs
[a
] = (av
/ bv
);
1037 case 0x33: /* mod.l */
1039 int a
= (inst
>> 4) & 0xf;
1041 int av
= cpu
.asregs
.regs
[a
];
1042 int bv
= cpu
.asregs
.regs
[b
];
1045 cpu
.asregs
.regs
[a
] = av
% bv
;
1048 case 0x34: /* umod.l */
1050 int a
= (inst
>> 4) & 0xf;
1052 unsigned int av
= cpu
.asregs
.regs
[a
];
1053 unsigned int bv
= cpu
.asregs
.regs
[b
];
1056 cpu
.asregs
.regs
[a
] = (av
% bv
);
1059 case 0x35: /* brk */
1061 cpu
.asregs
.exception
= SIGTRAP
;
1062 pc
-= 2; /* Adjust pc */
1064 case 0x36: /* ldo.b */
1066 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
1067 int a
= (inst
>> 4) & 0xf;
1071 addr
+= cpu
.asregs
.regs
[b
];
1072 cpu
.asregs
.regs
[a
] = rbat (scpu
, opc
, addr
);
1076 case 0x37: /* sto.b */
1078 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
1079 int a
= (inst
>> 4) & 0xf;
1083 addr
+= cpu
.asregs
.regs
[a
];
1084 wbat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
1088 case 0x38: /* ldo.s */
1090 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
1091 int a
= (inst
>> 4) & 0xf;
1095 addr
+= cpu
.asregs
.regs
[b
];
1096 cpu
.asregs
.regs
[a
] = rsat (scpu
, opc
, addr
);
1100 case 0x39: /* sto.s */
1102 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
1103 int a
= (inst
>> 4) & 0xf;
1107 addr
+= cpu
.asregs
.regs
[a
];
1108 wsat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
1115 cpu
.asregs
.exception
= SIGILL
;
1123 } while (!cpu
.asregs
.exception
);
1125 /* Hide away the things we've cached while executing. */
1126 cpu
.asregs
.regs
[PC_REGNO
] = pc
;
1127 cpu
.asregs
.insts
+= insts
; /* instructions done ... */
1131 sim_write (sd
, addr
, buffer
, size
)
1134 const unsigned char * buffer
;
1137 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1139 sim_core_write_buffer (sd
, scpu
, write_map
, buffer
, addr
, size
);
1145 sim_read (sd
, addr
, buffer
, size
)
1148 unsigned char * buffer
;
1151 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1153 sim_core_read_buffer (sd
, scpu
, read_map
, buffer
, addr
, size
);
1160 sim_store_register (sd
, rn
, memory
, length
)
1163 unsigned char * memory
;
1166 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1172 /* misalignment safe */
1173 ival
= moxie_extract_unsigned_integer (memory
, 4);
1174 cpu
.asints
[rn
] = ival
;
1184 sim_fetch_register (sd
, rn
, memory
, length
)
1187 unsigned char * memory
;
1190 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1194 long ival
= cpu
.asints
[rn
];
1196 /* misalignment-safe */
1197 moxie_store_unsigned_integer (memory
, 4, ival
);
1212 tracefile
= fopen("trace.csv", "wb");
1216 sim_resume (sd
, 0, 0);
1224 sim_stop_reason (sd
, reason
, sigrc
)
1226 enum sim_stop
* reason
;
1229 if (cpu
.asregs
.exception
== SIGQUIT
)
1231 * reason
= sim_exited
;
1232 * sigrc
= cpu
.asregs
.regs
[2];
1236 * reason
= sim_stopped
;
1237 * sigrc
= cpu
.asregs
.exception
;
1246 cpu
.asregs
.exception
= SIGINT
;
1252 sim_info (sd
, verbose
)
1256 callback
->printf_filtered (callback
, "\n\n# instructions executed %llu\n",
1262 sim_open (kind
, cb
, abfd
, argv
)
1268 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
1269 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
1271 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
1274 sim_do_command(sd
," memory region 0x00000000,0x4000000") ;
1275 sim_do_command(sd
," memory region 0xE0000000,0x10000") ;
1280 if (kind
== SIM_OPEN_STANDALONE
)
1283 set_initial_gprs (); /* Reset the GPR registers. */
1285 /* Configure/verify the target byte order and other runtime
1286 configuration options. */
1287 if (sim_config (sd
) != SIM_RC_OK
)
1289 sim_module_uninstall (sd
);
1293 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
1295 /* Uninstall the modules to avoid memory leaks,
1296 file descriptor leaks, etc. */
1297 sim_module_uninstall (sd
);
1305 sim_close (sd
, quitting
)
1313 /* Load the device tree blob. */
1316 load_dtb (SIM_DESC sd
, const char *filename
)
1319 FILE *f
= fopen (filename
, "rb");
1321 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1324 printf ("WARNING: ``%s'' could not be opened.\n", filename
);
1327 fseek (f
, 0, SEEK_END
);
1329 fseek (f
, 0, SEEK_SET
);
1330 buf
= alloca (size
);
1331 if (size
!= fread (buf
, 1, size
, f
))
1333 printf ("ERROR: error reading ``%s''.\n", filename
);
1336 sim_core_write_buffer (sd
, scpu
, write_map
, buf
, 0xE0000000, size
);
1337 cpu
.asregs
.sregs
[9] = 0xE0000000;
1342 sim_load (sd
, prog
, abfd
, from_tty
)
1349 /* Do the right thing for ELF executables; this turns out to be
1350 just about the right thing for any object format that:
1351 - we crack using BFD routines
1352 - follows the traditional UNIX text/data/bss layout
1353 - calls the bss section ".bss". */
1355 extern bfd
* sim_load_file (); /* ??? Don't know where this should live. */
1360 handle
= bfd_openr (prog
, 0); /* could be "moxie" */
1364 printf("``%s'' could not be opened.\n", prog
);
1368 /* Makes sure that we have an object file, also cleans gets the
1369 section headers in place. */
1370 if (!bfd_check_format (handle
, bfd_object
))
1372 /* wasn't an object file */
1374 printf ("``%s'' is not appropriate object file.\n", prog
);
1378 /* Clean up after ourselves. */
1382 /* from sh -- dac */
1383 prog_bfd
= sim_load_file (sd
, myname
, callback
, prog
, abfd
,
1384 sim_kind
== SIM_OPEN_DEBUG
,
1386 if (prog_bfd
== NULL
)
1390 bfd_close (prog_bfd
);
1396 sim_create_inferior (sd
, prog_bfd
, argv
, env
)
1398 struct bfd
* prog_bfd
;
1404 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1406 /* Set the initial register set. */
1409 set_initial_gprs ();
1412 if (prog_bfd
!= NULL
)
1413 cpu
.asregs
.regs
[PC_REGNO
] = bfd_get_start_address (prog_bfd
);
1415 /* Copy args into target memory. */
1417 for (argc
= 0; avp
&& *avp
; avp
++)
1420 /* Target memory looks like this:
1421 0x00000000 zero word
1422 0x00000004 argc word
1423 0x00000008 start of argv
1425 0x0000???? end of argv
1426 0x0000???? zero word
1427 0x0000???? start of data pointed to by argv */
1429 wlat (scpu
, 0, 0, 0);
1430 wlat (scpu
, 0, 4, argc
);
1432 /* tp is the offset of our first argv data. */
1433 tp
= 4 + 4 + argc
* 4 + 4;
1435 for (i
= 0; i
< argc
; i
++)
1437 /* Set the argv value. */
1438 wlat (scpu
, 0, 4 + 4 + i
* 4, tp
);
1440 /* Store the string. */
1441 sim_core_write_buffer (sd
, scpu
, write_map
, argv
[i
],
1442 tp
, strlen(argv
[i
])+1);
1443 tp
+= strlen (argv
[i
]) + 1;
1446 wlat (scpu
, 0, 4 + 4 + i
* 4, 0);
1454 sim_do_command (sd
, cmd
)
1458 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
1460 "Error: \"%s\" is not a valid moxie simulator command.\n",
1465 sim_set_callbacks (ptr
)
1466 host_callback
* ptr
;
This page took 0.059438 seconds and 5 git commands to generate.