1 /* Simulator for the moxie processor
2 Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
3 Contributed by Anthony Green
5 This file is part of GDB, the GNU debugger.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
23 #include <sys/times.h>
24 #include <sys/param.h>
25 #include <netinet/in.h> /* for byte ordering macros */
27 #include "gdb/callback.h"
28 #include "libiberty.h"
29 #include "gdb/remote-sim.h"
35 typedef unsigned int uword
;
37 host_callback
* callback
;
41 /* Extract the signed 10-bit offset from a 16-bit branch
43 #define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
45 #define EXTRACT_WORD(addr) \
46 ((sim_core_read_aligned_1 (scpu, cia, read_map, addr) << 24) \
47 + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+1) << 16) \
48 + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+2) << 8) \
49 + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+3)))
52 moxie_extract_unsigned_integer (addr
, len
)
58 unsigned char * startaddr
= (unsigned char *)addr
;
59 unsigned char * endaddr
= startaddr
+ len
;
61 if (len
> (int) sizeof (unsigned long))
62 printf ("That operation is not available on integers of more than %d bytes.",
63 sizeof (unsigned long));
65 /* Start at the most significant end of the integer, and work towards
66 the least significant. */
69 for (p
= endaddr
; p
> startaddr
;)
70 retval
= (retval
<< 8) | * -- p
;
76 moxie_store_unsigned_integer (addr
, len
, val
)
82 unsigned char * startaddr
= (unsigned char *)addr
;
83 unsigned char * endaddr
= startaddr
+ len
;
85 for (p
= endaddr
; p
> startaddr
;)
92 /* moxie register names. */
93 static const char *reg_names
[16] =
94 { "$fp", "$sp", "$r0", "$r1", "$r2", "$r3", "$r4", "$r5",
95 "$r6", "$r7", "$r8", "$r9", "$r10", "$r11", "$r12", "$r13" };
99 This state is maintained in host byte order. The fetch/store
100 register functions must translate between host byte order and the
101 target processor byte order. Keeping this data in target byte
102 order simplifies the register read/write functions. Keeping this
103 data in native order improves the performance of the simulator.
104 Simulation speed is deemed more important. */
106 #define NUM_MOXIE_REGS 17 /* Including PC */
107 #define NUM_MOXIE_SREGS 256 /* The special registers */
110 /* The ordering of the moxie_regset structure is matched in the
111 gdb/config/moxie/tm-moxie.h file in the REGISTER_NAMES macro. */
114 word regs
[NUM_MOXIE_REGS
+ 1]; /* primary registers */
115 word sregs
[256]; /* special registers */
116 word cc
; /* the condition code reg */
118 unsigned long long insts
; /* instruction counter */
129 struct moxie_regset asregs
;
130 word asints
[1]; /* but accessed larger... */
134 static SIM_OPEN_KIND sim_kind
;
135 static int issue_messages
= 0;
148 /* Set up machine just out of reset. */
149 cpu
.asregs
.regs
[PC_REGNO
] = 0;
151 /* Clean out the register contents. */
152 for (i
= 0; i
< NUM_MOXIE_REGS
; i
++)
153 cpu
.asregs
.regs
[i
] = 0;
154 for (i
= 0; i
< NUM_MOXIE_SREGS
; i
++)
155 cpu
.asregs
.sregs
[i
] = 0;
161 cpu
.asregs
.exception
= SIGINT
;
164 /* Write a 1 byte value to memory. */
167 wbat (sim_cpu
*scpu
, word pc
, word x
, word v
)
169 address_word cia
= CIA_GET (scpu
);
171 sim_core_write_aligned_1 (scpu
, cia
, write_map
, x
, v
);
174 /* Write a 2 byte value to memory. */
177 wsat (sim_cpu
*scpu
, word pc
, word x
, word v
)
179 address_word cia
= CIA_GET (scpu
);
181 sim_core_write_aligned_2 (scpu
, cia
, write_map
, x
, v
);
184 /* Write a 4 byte value to memory. */
187 wlat (sim_cpu
*scpu
, word pc
, word x
, word v
)
189 address_word cia
= CIA_GET (scpu
);
191 sim_core_write_aligned_4 (scpu
, cia
, write_map
, x
, v
);
194 /* Read 2 bytes from memory. */
197 rsat (sim_cpu
*scpu
, word pc
, word x
)
199 address_word cia
= CIA_GET (scpu
);
201 return (sim_core_read_aligned_2 (scpu
, cia
, read_map
, x
));
204 /* Read 1 byte from memory. */
207 rbat (sim_cpu
*scpu
, word pc
, word x
)
209 address_word cia
= CIA_GET (scpu
);
211 return (sim_core_read_aligned_1 (scpu
, cia
, read_map
, x
));
214 /* Read 4 bytes from memory. */
217 rlat (sim_cpu
*scpu
, word pc
, word x
)
219 address_word cia
= CIA_GET (scpu
);
221 return (sim_core_read_aligned_4 (scpu
, cia
, read_map
, x
));
224 #define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; }
227 convert_target_flags (unsigned int tflags
)
229 unsigned int hflags
= 0x0;
231 CHECK_FLAG(0x0001, O_WRONLY
);
232 CHECK_FLAG(0x0002, O_RDWR
);
233 CHECK_FLAG(0x0008, O_APPEND
);
234 CHECK_FLAG(0x0200, O_CREAT
);
235 CHECK_FLAG(0x0400, O_TRUNC
);
236 CHECK_FLAG(0x0800, O_EXCL
);
237 CHECK_FLAG(0x2000, O_SYNC
);
241 "Simulator Error: problem converting target open flags for host. 0x%x\n",
247 #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]);
249 static int tracing
= 0;
252 sim_resume (sd
, step
, siggnal
)
257 unsigned long long insts
;
260 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
261 address_word cia
= CIA_GET (scpu
);
263 sigsave
= signal (SIGINT
, interrupt
);
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
) - 2;
297 if (! (cpu
.asregs
.cc
& CC_EQ
))
298 pc
+= INST2OFFSET(inst
) - 2;
304 if (cpu
.asregs
.cc
& CC_LT
)
305 pc
+= INST2OFFSET(inst
) - 2;
310 if (cpu
.asregs
.cc
& CC_GT
)
311 pc
+= INST2OFFSET(inst
) - 2;
314 case 0x04: /* bltu */
317 if (cpu
.asregs
.cc
& CC_LTU
)
318 pc
+= INST2OFFSET(inst
) - 2;
321 case 0x05: /* bgtu */
324 if (cpu
.asregs
.cc
& CC_GTU
)
325 pc
+= INST2OFFSET(inst
) - 2;
331 if (cpu
.asregs
.cc
& (CC_GT
| CC_EQ
))
332 pc
+= INST2OFFSET(inst
) - 2;
338 if (cpu
.asregs
.cc
& (CC_LT
| CC_EQ
))
339 pc
+= INST2OFFSET(inst
) - 2;
342 case 0x08: /* bgeu */
345 if (cpu
.asregs
.cc
& (CC_GTU
| CC_EQ
))
346 pc
+= INST2OFFSET(inst
) - 2;
349 case 0x09: /* bleu */
352 if (cpu
.asregs
.cc
& (CC_LTU
| CC_EQ
))
353 pc
+= INST2OFFSET(inst
) - 2;
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);
376 cpu
.asregs
.regs
[a
] = av
+ v
;
381 int a
= (inst
>> 8) & 0xf;
382 unsigned av
= cpu
.asregs
.regs
[a
];
383 unsigned v
= (inst
& 0xff);
385 cpu
.asregs
.regs
[a
] = av
- v
;
390 int a
= (inst
>> 8) & 0xf;
391 unsigned v
= (inst
& 0xff);
393 cpu
.asregs
.regs
[a
] = cpu
.asregs
.sregs
[v
];
398 int a
= (inst
>> 8) & 0xf;
399 unsigned v
= (inst
& 0xff);
401 cpu
.asregs
.sregs
[v
] = cpu
.asregs
.regs
[a
];
406 cpu
.asregs
.exception
= SIGILL
;
413 /* This is a Form 1 instruction. */
414 int opcode
= inst
>> 8;
420 cpu
.asregs
.exception
= SIGILL
;
422 case 0x01: /* ldi.l (immediate) */
424 int reg
= (inst
>> 4) & 0xf;
426 unsigned int val
= EXTRACT_WORD(pc
+2);
427 cpu
.asregs
.regs
[reg
] = val
;
431 case 0x02: /* mov (register-to-register) */
433 int dest
= (inst
>> 4) & 0xf;
434 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];
444 /* Save a slot for the static chain. */
447 /* Push the return address. */
449 wlat (scpu
, opc
, sp
, pc
+ 6);
451 /* Push the current frame pointer. */
453 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
455 /* Uncache the stack pointer and set the pc and $fp. */
456 cpu
.asregs
.regs
[1] = sp
;
457 cpu
.asregs
.regs
[0] = sp
;
463 unsigned int sp
= cpu
.asregs
.regs
[0];
467 /* Pop the frame pointer. */
468 cpu
.asregs
.regs
[0] = rlat (scpu
, opc
, sp
);
471 /* Pop the return address. */
472 pc
= rlat (scpu
, opc
, sp
) - 2;
475 /* Skip over the static chain slot. */
478 /* Uncache the stack pointer. */
479 cpu
.asregs
.regs
[1] = sp
;
482 case 0x05: /* add.l */
484 int a
= (inst
>> 4) & 0xf;
486 unsigned av
= cpu
.asregs
.regs
[a
];
487 unsigned bv
= cpu
.asregs
.regs
[b
];
489 cpu
.asregs
.regs
[a
] = av
+ bv
;
492 case 0x06: /* push */
494 int a
= (inst
>> 4) & 0xf;
496 int sp
= cpu
.asregs
.regs
[a
] - 4;
498 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[b
]);
499 cpu
.asregs
.regs
[a
] = sp
;
504 int a
= (inst
>> 4) & 0xf;
506 int sp
= cpu
.asregs
.regs
[a
];
508 cpu
.asregs
.regs
[b
] = rlat (scpu
, opc
, sp
);
509 cpu
.asregs
.regs
[a
] = sp
+ 4;
512 case 0x08: /* lda.l */
514 int reg
= (inst
>> 4) & 0xf;
515 unsigned int addr
= EXTRACT_WORD(pc
+2);
517 cpu
.asregs
.regs
[reg
] = rlat (scpu
, opc
, addr
);
521 case 0x09: /* sta.l */
523 int reg
= (inst
>> 4) & 0xf;
524 unsigned int addr
= EXTRACT_WORD(pc
+2);
526 wlat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
530 case 0x0a: /* ld.l (register indirect) */
532 int src
= inst
& 0xf;
533 int dest
= (inst
>> 4) & 0xf;
536 xv
= cpu
.asregs
.regs
[src
];
537 cpu
.asregs
.regs
[dest
] = rlat (scpu
, opc
, xv
);
540 case 0x0b: /* st.l */
542 int dest
= (inst
>> 4) & 0xf;
543 int val
= inst
& 0xf;
545 wlat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
548 case 0x0c: /* ldo.l */
550 unsigned int addr
= EXTRACT_WORD(pc
+2);
551 int a
= (inst
>> 4) & 0xf;
554 addr
+= cpu
.asregs
.regs
[b
];
555 cpu
.asregs
.regs
[a
] = rlat (scpu
, opc
, addr
);
559 case 0x0d: /* sto.l */
561 unsigned int addr
= EXTRACT_WORD(pc
+2);
562 int a
= (inst
>> 4) & 0xf;
565 addr
+= cpu
.asregs
.regs
[a
];
566 wlat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
572 int a
= (inst
>> 4) & 0xf;
575 int va
= cpu
.asregs
.regs
[a
];
576 int vb
= cpu
.asregs
.regs
[b
];
584 cc
|= (va
< vb
? CC_LT
: 0);
585 cc
|= (va
> vb
? CC_GT
: 0);
586 cc
|= ((unsigned int) va
< (unsigned int) vb
? CC_LTU
: 0);
587 cc
|= ((unsigned int) va
> (unsigned int) vb
? CC_GTU
: 0);
607 cpu
.asregs
.exception
= SIGILL
;
612 unsigned int fn
= cpu
.asregs
.regs
[(inst
>> 4) & 0xf];
613 unsigned int sp
= cpu
.asregs
.regs
[1];
617 /* Save a slot for the static chain. */
620 /* Push the return address. */
622 wlat (scpu
, opc
, sp
, pc
+ 2);
624 /* Push the current frame pointer. */
626 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
628 /* Uncache the stack pointer and set the fp & pc. */
629 cpu
.asregs
.regs
[1] = sp
;
630 cpu
.asregs
.regs
[0] = sp
;
634 case 0x1a: /* jmpa */
636 unsigned int tgt
= EXTRACT_WORD(pc
+2);
641 case 0x1b: /* ldi.b (immediate) */
643 int reg
= (inst
>> 4) & 0xf;
645 unsigned int val
= EXTRACT_WORD(pc
+2);
647 cpu
.asregs
.regs
[reg
] = val
;
651 case 0x1c: /* ld.b (register indirect) */
653 int src
= inst
& 0xf;
654 int dest
= (inst
>> 4) & 0xf;
657 xv
= cpu
.asregs
.regs
[src
];
658 cpu
.asregs
.regs
[dest
] = rbat (scpu
, opc
, xv
);
661 case 0x1d: /* lda.b */
663 int reg
= (inst
>> 4) & 0xf;
664 unsigned int addr
= EXTRACT_WORD(pc
+2);
666 cpu
.asregs
.regs
[reg
] = rbat (scpu
, opc
, addr
);
670 case 0x1e: /* st.b */
672 int dest
= (inst
>> 4) & 0xf;
673 int val
= inst
& 0xf;
675 wbat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
678 case 0x1f: /* sta.b */
680 int reg
= (inst
>> 4) & 0xf;
681 unsigned int addr
= EXTRACT_WORD(pc
+2);
683 wbat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
687 case 0x20: /* ldi.s (immediate) */
689 int reg
= (inst
>> 4) & 0xf;
691 unsigned int val
= EXTRACT_WORD(pc
+2);
693 cpu
.asregs
.regs
[reg
] = val
;
697 case 0x21: /* ld.s (register indirect) */
699 int src
= inst
& 0xf;
700 int dest
= (inst
>> 4) & 0xf;
703 xv
= cpu
.asregs
.regs
[src
];
704 cpu
.asregs
.regs
[dest
] = rsat (scpu
, opc
, xv
);
707 case 0x22: /* lda.s */
709 int reg
= (inst
>> 4) & 0xf;
710 unsigned int addr
= EXTRACT_WORD(pc
+2);
712 cpu
.asregs
.regs
[reg
] = rsat (scpu
, opc
, addr
);
716 case 0x23: /* st.s */
718 int dest
= (inst
>> 4) & 0xf;
719 int val
= inst
& 0xf;
721 wsat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
724 case 0x24: /* sta.s */
726 int reg
= (inst
>> 4) & 0xf;
727 unsigned int addr
= EXTRACT_WORD(pc
+2);
729 wsat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
735 int reg
= (inst
>> 4) & 0xf;
737 pc
= cpu
.asregs
.regs
[reg
] - 2;
742 int a
= (inst
>> 4) & 0xf;
746 av
= cpu
.asregs
.regs
[a
];
747 bv
= cpu
.asregs
.regs
[b
];
748 cpu
.asregs
.regs
[a
] = av
& bv
;
751 case 0x27: /* lshr */
753 int a
= (inst
>> 4) & 0xf;
755 int av
= cpu
.asregs
.regs
[a
];
756 int bv
= cpu
.asregs
.regs
[b
];
758 cpu
.asregs
.regs
[a
] = (unsigned) ((unsigned) av
>> bv
);
761 case 0x28: /* ashl */
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
] = av
<< bv
;
771 case 0x29: /* sub.l */
773 int a
= (inst
>> 4) & 0xf;
775 unsigned av
= cpu
.asregs
.regs
[a
];
776 unsigned bv
= cpu
.asregs
.regs
[b
];
778 cpu
.asregs
.regs
[a
] = av
- bv
;
783 int a
= (inst
>> 4) & 0xf;
785 int bv
= cpu
.asregs
.regs
[b
];
787 cpu
.asregs
.regs
[a
] = - bv
;
792 int a
= (inst
>> 4) & 0xf;
796 av
= cpu
.asregs
.regs
[a
];
797 bv
= cpu
.asregs
.regs
[b
];
798 cpu
.asregs
.regs
[a
] = av
| bv
;
803 int a
= (inst
>> 4) & 0xf;
805 int bv
= cpu
.asregs
.regs
[b
];
807 cpu
.asregs
.regs
[a
] = 0xffffffff ^ bv
;
810 case 0x2d: /* ashr */
812 int a
= (inst
>> 4) & 0xf;
814 int av
= cpu
.asregs
.regs
[a
];
815 int bv
= cpu
.asregs
.regs
[b
];
817 cpu
.asregs
.regs
[a
] = av
>> bv
;
822 int a
= (inst
>> 4) & 0xf;
826 av
= cpu
.asregs
.regs
[a
];
827 bv
= cpu
.asregs
.regs
[b
];
828 cpu
.asregs
.regs
[a
] = av
^ bv
;
831 case 0x2f: /* mul.l */
833 int a
= (inst
>> 4) & 0xf;
835 unsigned av
= cpu
.asregs
.regs
[a
];
836 unsigned bv
= cpu
.asregs
.regs
[b
];
838 cpu
.asregs
.regs
[a
] = av
* bv
;
843 unsigned int inum
= EXTRACT_WORD(pc
+2);
845 /* Set the special registers appropriately. */
846 cpu
.asregs
.sregs
[2] = 3; /* MOXIE_EX_SWI */
847 cpu
.asregs
.sregs
[3] = inum
;
850 case 0x1: /* SYS_exit */
852 cpu
.asregs
.exception
= SIGQUIT
;
855 case 0x2: /* SYS_open */
858 int mode
= (int) convert_target_flags ((unsigned) cpu
.asregs
.regs
[3]);
859 int perm
= (int) cpu
.asregs
.regs
[4];
860 int fd
= open (fname
, mode
, perm
);
861 sim_core_read_buffer (sd
, scpu
, read_map
, fname
,
862 cpu
.asregs
.regs
[2], 1024);
863 /* FIXME - set errno */
864 cpu
.asregs
.regs
[2] = fd
;
867 case 0x4: /* SYS_read */
869 int fd
= cpu
.asregs
.regs
[2];
870 unsigned len
= (unsigned) cpu
.asregs
.regs
[4];
871 char *buf
= malloc (len
);
872 cpu
.asregs
.regs
[2] = read (fd
, buf
, len
);
873 sim_core_write_buffer (sd
, scpu
, write_map
, buf
,
874 cpu
.asregs
.regs
[3], len
);
878 case 0x5: /* SYS_write */
881 /* String length is at 0x12($fp) */
882 unsigned count
, len
= (unsigned) cpu
.asregs
.regs
[4];
884 sim_core_read_buffer (sd
, scpu
, read_map
, str
,
885 cpu
.asregs
.regs
[3], len
);
886 count
= write (cpu
.asregs
.regs
[2], str
, len
);
888 cpu
.asregs
.regs
[2] = count
;
891 case 0xffffffff: /* Linux System Call */
893 unsigned int handler
= cpu
.asregs
.sregs
[1];
894 unsigned int sp
= cpu
.asregs
.regs
[1];
896 /* Save a slot for the static chain. */
899 /* Push the return address. */
901 wlat (scpu
, opc
, sp
, pc
+ 6);
903 /* Push the current frame pointer. */
905 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
907 /* Uncache the stack pointer and set the fp & pc. */
908 cpu
.asregs
.regs
[1] = sp
;
909 cpu
.asregs
.regs
[0] = sp
;
918 case 0x31: /* div.l */
920 int a
= (inst
>> 4) & 0xf;
922 int av
= cpu
.asregs
.regs
[a
];
923 int bv
= cpu
.asregs
.regs
[b
];
925 cpu
.asregs
.regs
[a
] = av
/ bv
;
928 case 0x32: /* udiv.l */
930 int a
= (inst
>> 4) & 0xf;
932 unsigned int av
= cpu
.asregs
.regs
[a
];
933 unsigned int bv
= cpu
.asregs
.regs
[b
];
935 cpu
.asregs
.regs
[a
] = (av
/ bv
);
938 case 0x33: /* mod.l */
940 int a
= (inst
>> 4) & 0xf;
942 int av
= cpu
.asregs
.regs
[a
];
943 int bv
= cpu
.asregs
.regs
[b
];
945 cpu
.asregs
.regs
[a
] = av
% bv
;
948 case 0x34: /* umod.l */
950 int a
= (inst
>> 4) & 0xf;
952 unsigned int av
= cpu
.asregs
.regs
[a
];
953 unsigned int bv
= cpu
.asregs
.regs
[b
];
955 cpu
.asregs
.regs
[a
] = (av
% bv
);
960 cpu
.asregs
.exception
= SIGTRAP
;
961 pc
-= 2; /* Adjust pc */
963 case 0x36: /* ldo.b */
965 unsigned int addr
= EXTRACT_WORD(pc
+2);
966 int a
= (inst
>> 4) & 0xf;
969 addr
+= cpu
.asregs
.regs
[b
];
970 cpu
.asregs
.regs
[a
] = rbat (scpu
, opc
, addr
);
974 case 0x37: /* sto.b */
976 unsigned int addr
= EXTRACT_WORD(pc
+2);
977 int a
= (inst
>> 4) & 0xf;
980 addr
+= cpu
.asregs
.regs
[a
];
981 wbat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
985 case 0x38: /* ldo.s */
987 unsigned int addr
= EXTRACT_WORD(pc
+2);
988 int a
= (inst
>> 4) & 0xf;
991 addr
+= cpu
.asregs
.regs
[b
];
992 cpu
.asregs
.regs
[a
] = rsat (scpu
, opc
, addr
);
996 case 0x39: /* sto.s */
998 unsigned int addr
= EXTRACT_WORD(pc
+2);
999 int a
= (inst
>> 4) & 0xf;
1002 addr
+= cpu
.asregs
.regs
[a
];
1003 wsat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
1010 cpu
.asregs
.exception
= SIGILL
;
1018 } while (!cpu
.asregs
.exception
);
1020 /* Hide away the things we've cached while executing. */
1021 cpu
.asregs
.regs
[PC_REGNO
] = pc
;
1022 cpu
.asregs
.insts
+= insts
; /* instructions done ... */
1024 signal (SIGINT
, sigsave
);
1028 sim_write (sd
, addr
, buffer
, size
)
1031 const unsigned char * buffer
;
1034 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1036 sim_core_write_buffer (sd
, scpu
, write_map
, buffer
, addr
, size
);
1042 sim_read (sd
, addr
, buffer
, size
)
1045 unsigned char * buffer
;
1048 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1050 sim_core_read_buffer (sd
, scpu
, read_map
, buffer
, addr
, size
);
1057 sim_store_register (sd
, rn
, memory
, length
)
1060 unsigned char * memory
;
1063 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1069 /* misalignment safe */
1070 ival
= moxie_extract_unsigned_integer (memory
, 4);
1071 cpu
.asints
[rn
] = ival
;
1081 sim_fetch_register (sd
, rn
, memory
, length
)
1084 unsigned char * memory
;
1087 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1091 long ival
= cpu
.asints
[rn
];
1093 /* misalignment-safe */
1094 moxie_store_unsigned_integer (memory
, 4, ival
);
1109 tracefile
= fopen("trace.csv", "wb");
1113 sim_resume (sd
, 0, 0);
1121 sim_stop_reason (sd
, reason
, sigrc
)
1123 enum sim_stop
* reason
;
1126 if (cpu
.asregs
.exception
== SIGQUIT
)
1128 * reason
= sim_exited
;
1129 * sigrc
= cpu
.asregs
.regs
[2];
1133 * reason
= sim_stopped
;
1134 * sigrc
= cpu
.asregs
.exception
;
1143 cpu
.asregs
.exception
= SIGINT
;
1149 sim_info (sd
, verbose
)
1153 callback
->printf_filtered (callback
, "\n\n# instructions executed %llu\n",
1159 sim_open (kind
, cb
, abfd
, argv
)
1165 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
1166 printf ("0x%x 0x%x\n", sd
, STATE_MAGIC(sd
));
1167 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
1169 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
1172 sim_do_command(sd
," memory region 0x00000000,0x4000000") ;
1173 sim_do_command(sd
," memory region 0xE0000000,0x10000") ;
1178 if (kind
== SIM_OPEN_STANDALONE
)
1181 set_initial_gprs (); /* Reset the GPR registers. */
1183 /* Configure/verify the target byte order and other runtime
1184 configuration options. */
1185 if (sim_config (sd
) != SIM_RC_OK
)
1187 sim_module_uninstall (sd
);
1191 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
1193 /* Uninstall the modules to avoid memory leaks,
1194 file descriptor leaks, etc. */
1195 sim_module_uninstall (sd
);
1203 sim_close (sd
, quitting
)
1211 /* Load the device tree blob. */
1214 load_dtb (SIM_DESC sd
, const char *filename
)
1217 FILE *f
= fopen (filename
, "rb");
1219 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1222 printf ("WARNING: ``%s'' could not be opened.\n", filename
);
1225 fseek (f
, 0, SEEK_END
);
1227 fseek (f
, 0, SEEK_SET
);
1228 buf
= alloca (size
);
1229 if (size
!= fread (buf
, 1, size
, f
))
1231 printf ("ERROR: error reading ``%s''.\n", filename
);
1234 sim_core_write_buffer (sd
, scpu
, write_map
, buf
, 0xE0000000, size
);
1235 cpu
.asregs
.sregs
[9] = 0xE0000000;
1240 sim_load (sd
, prog
, abfd
, from_tty
)
1247 /* Do the right thing for ELF executables; this turns out to be
1248 just about the right thing for any object format that:
1249 - we crack using BFD routines
1250 - follows the traditional UNIX text/data/bss layout
1251 - calls the bss section ".bss". */
1253 extern bfd
* sim_load_file (); /* ??? Don't know where this should live. */
1258 handle
= bfd_openr (prog
, 0); /* could be "moxie" */
1262 printf("``%s'' could not be opened.\n", prog
);
1266 /* Makes sure that we have an object file, also cleans gets the
1267 section headers in place. */
1268 if (!bfd_check_format (handle
, bfd_object
))
1270 /* wasn't an object file */
1272 printf ("``%s'' is not appropriate object file.\n", prog
);
1276 /* Clean up after ourselves. */
1280 /* from sh -- dac */
1281 prog_bfd
= sim_load_file (sd
, myname
, callback
, prog
, abfd
,
1282 sim_kind
== SIM_OPEN_DEBUG
,
1284 if (prog_bfd
== NULL
)
1288 bfd_close (prog_bfd
);
1294 sim_create_inferior (sd
, prog_bfd
, argv
, env
)
1296 struct bfd
* prog_bfd
;
1302 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1304 /* Set the initial register set. */
1307 set_initial_gprs ();
1310 if (prog_bfd
!= NULL
)
1311 cpu
.asregs
.regs
[PC_REGNO
] = bfd_get_start_address (prog_bfd
);
1313 /* Copy args into target memory. */
1315 for (argc
= 0; avp
&& *avp
; avp
++)
1318 /* Target memory looks like this:
1319 0x00000000 zero word
1320 0x00000004 argc word
1321 0x00000008 start of argv
1323 0x0000???? end of argv
1324 0x0000???? zero word
1325 0x0000???? start of data pointed to by argv */
1327 wlat (scpu
, 0, 0, 0);
1328 wlat (scpu
, 0, 4, argc
);
1330 /* tp is the offset of our first argv data. */
1331 tp
= 4 + 4 + argc
* 4 + 4;
1333 for (i
= 0; i
< argc
; i
++)
1335 /* Set the argv value. */
1336 wlat (scpu
, 0, 4 + 4 + i
* 4, tp
);
1338 /* Store the string. */
1339 sim_core_write_buffer (sd
, scpu
, write_map
, argv
[i
],
1340 tp
, strlen(argv
[i
])+1);
1341 tp
+= strlen (argv
[i
]) + 1;
1344 wlat (scpu
, 0, 4 + 4 + i
* 4, 0);
1360 sim_do_command (sd
, cmd
)
1364 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
1366 "Error: \"%s\" is not a valid moxie simulator command.\n",
1371 sim_set_callbacks (ptr
)
1372 host_callback
* ptr
;
This page took 0.058302 seconds and 4 git commands to generate.