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>
29 #include "libiberty.h"
30 #include "gdb/remote-sim.h"
34 #include "sim-options.h"
37 typedef unsigned int uword
;
39 /* Extract the signed 10-bit offset from a 16-bit branch
41 #define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
43 #define EXTRACT_WORD(addr) \
44 ((sim_core_read_aligned_1 (scpu, cia, read_map, addr) << 24) \
45 + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+1) << 16) \
46 + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+2) << 8) \
47 + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+3)))
49 #define EXTRACT_OFFSET(addr) \
52 ((sim_core_read_aligned_1 (scpu, cia, read_map, addr) << 8) \
53 + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+1))) << 16) >> 16)
56 moxie_extract_unsigned_integer (unsigned char *addr
, int 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 %zu 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 (unsigned char *addr
, int len
, unsigned long val
)
81 unsigned char * startaddr
= (unsigned char *)addr
;
82 unsigned char * endaddr
= startaddr
+ len
;
84 for (p
= endaddr
; p
> startaddr
;)
91 /* moxie register names. */
92 static const char *reg_names
[16] =
93 { "$fp", "$sp", "$r0", "$r1", "$r2", "$r3", "$r4", "$r5",
94 "$r6", "$r7", "$r8", "$r9", "$r10", "$r11", "$r12", "$r13" };
98 This state is maintained in host byte order. The fetch/store
99 register functions must translate between host byte order and the
100 target processor byte order. Keeping this data in target byte
101 order simplifies the register read/write functions. Keeping this
102 data in native order improves the performance of the simulator.
103 Simulation speed is deemed more important. */
105 #define NUM_MOXIE_REGS 17 /* Including PC */
106 #define NUM_MOXIE_SREGS 256 /* The special registers */
109 /* The ordering of the moxie_regset structure is matched in the
110 gdb/config/moxie/tm-moxie.h file in the REGISTER_NAMES macro. */
111 /* TODO: This should be moved to sim-main.h:_sim_cpu. */
114 word regs
[NUM_MOXIE_REGS
+ 1]; /* primary registers */
115 word sregs
[256]; /* special registers */
116 word cc
; /* the condition code reg */
117 unsigned long long insts
; /* instruction counter */
126 /* TODO: This should be moved to sim-main.h:_sim_cpu. */
129 struct moxie_regset asregs
;
130 word asints
[1]; /* but accessed larger... */
134 set_initial_gprs (void)
139 /* Set up machine just out of reset. */
140 cpu
.asregs
.regs
[PC_REGNO
] = 0;
142 /* Clean out the register contents. */
143 for (i
= 0; i
< NUM_MOXIE_REGS
; i
++)
144 cpu
.asregs
.regs
[i
] = 0;
145 for (i
= 0; i
< NUM_MOXIE_SREGS
; i
++)
146 cpu
.asregs
.sregs
[i
] = 0;
149 /* Write a 1 byte value to memory. */
152 wbat (sim_cpu
*scpu
, word pc
, word x
, word v
)
154 address_word cia
= CPU_PC_GET (scpu
);
156 sim_core_write_aligned_1 (scpu
, cia
, write_map
, x
, v
);
159 /* Write a 2 byte value to memory. */
162 wsat (sim_cpu
*scpu
, word pc
, word x
, word v
)
164 address_word cia
= CPU_PC_GET (scpu
);
166 sim_core_write_aligned_2 (scpu
, cia
, write_map
, x
, v
);
169 /* Write a 4 byte value to memory. */
172 wlat (sim_cpu
*scpu
, word pc
, word x
, word v
)
174 address_word cia
= CPU_PC_GET (scpu
);
176 sim_core_write_aligned_4 (scpu
, cia
, write_map
, x
, v
);
179 /* Read 2 bytes from memory. */
182 rsat (sim_cpu
*scpu
, word pc
, word x
)
184 address_word cia
= CPU_PC_GET (scpu
);
186 return (sim_core_read_aligned_2 (scpu
, cia
, read_map
, x
));
189 /* Read 1 byte from memory. */
192 rbat (sim_cpu
*scpu
, word pc
, word x
)
194 address_word cia
= CPU_PC_GET (scpu
);
196 return (sim_core_read_aligned_1 (scpu
, cia
, read_map
, x
));
199 /* Read 4 bytes from memory. */
202 rlat (sim_cpu
*scpu
, word pc
, word x
)
204 address_word cia
= CPU_PC_GET (scpu
);
206 return (sim_core_read_aligned_4 (scpu
, cia
, read_map
, x
));
209 #define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; }
212 convert_target_flags (unsigned int tflags
)
214 unsigned int hflags
= 0x0;
216 CHECK_FLAG(0x0001, O_WRONLY
);
217 CHECK_FLAG(0x0002, O_RDWR
);
218 CHECK_FLAG(0x0008, O_APPEND
);
219 CHECK_FLAG(0x0200, O_CREAT
);
220 CHECK_FLAG(0x0400, O_TRUNC
);
221 CHECK_FLAG(0x0800, O_EXCL
);
222 CHECK_FLAG(0x2000, O_SYNC
);
226 "Simulator Error: problem converting target open flags for host. 0x%x\n",
232 /* TODO: Move to sim-trace.h. */
233 static FILE *tracefile
;
234 static const int tracing
= 0;
235 #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]);
238 sim_engine_run (SIM_DESC sd
,
239 int next_cpu_nr
, /* ignore */
240 int nr_cpus
, /* ignore */
241 int siggnal
) /* ignore */
245 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
246 address_word cia
= CPU_PC_GET (scpu
);
248 pc
= cpu
.asregs
.regs
[PC_REGNO
];
250 /* Run instructions here. */
255 /* Fetch the instruction at pc. */
256 inst
= (sim_core_read_aligned_1 (scpu
, cia
, read_map
, pc
) << 8)
257 + sim_core_read_aligned_1 (scpu
, cia
, read_map
, pc
+1);
259 /* Decode instruction. */
260 if (inst
& (1 << 15))
262 if (inst
& (1 << 14))
264 /* This is a Form 3 instruction. */
265 int opcode
= (inst
>> 10 & 0xf);
272 if (cpu
.asregs
.cc
& CC_EQ
)
273 pc
+= INST2OFFSET(inst
);
279 if (! (cpu
.asregs
.cc
& CC_EQ
))
280 pc
+= INST2OFFSET(inst
);
286 if (cpu
.asregs
.cc
& CC_LT
)
287 pc
+= INST2OFFSET(inst
);
292 if (cpu
.asregs
.cc
& CC_GT
)
293 pc
+= INST2OFFSET(inst
);
296 case 0x04: /* bltu */
299 if (cpu
.asregs
.cc
& CC_LTU
)
300 pc
+= INST2OFFSET(inst
);
303 case 0x05: /* bgtu */
306 if (cpu
.asregs
.cc
& CC_GTU
)
307 pc
+= INST2OFFSET(inst
);
313 if (cpu
.asregs
.cc
& (CC_GT
| CC_EQ
))
314 pc
+= INST2OFFSET(inst
);
320 if (cpu
.asregs
.cc
& (CC_LT
| CC_EQ
))
321 pc
+= INST2OFFSET(inst
);
324 case 0x08: /* bgeu */
327 if (cpu
.asregs
.cc
& (CC_GTU
| CC_EQ
))
328 pc
+= INST2OFFSET(inst
);
331 case 0x09: /* bleu */
334 if (cpu
.asregs
.cc
& (CC_LTU
| CC_EQ
))
335 pc
+= INST2OFFSET(inst
);
341 sim_engine_halt (sd
, NULL
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
348 /* This is a Form 2 instruction. */
349 int opcode
= (inst
>> 12 & 0x3);
354 int a
= (inst
>> 8) & 0xf;
355 unsigned av
= cpu
.asregs
.regs
[a
];
356 unsigned v
= (inst
& 0xff);
359 cpu
.asregs
.regs
[a
] = av
+ v
;
364 int a
= (inst
>> 8) & 0xf;
365 unsigned av
= cpu
.asregs
.regs
[a
];
366 unsigned v
= (inst
& 0xff);
369 cpu
.asregs
.regs
[a
] = av
- v
;
374 int a
= (inst
>> 8) & 0xf;
375 unsigned v
= (inst
& 0xff);
378 cpu
.asregs
.regs
[a
] = cpu
.asregs
.sregs
[v
];
383 int a
= (inst
>> 8) & 0xf;
384 unsigned v
= (inst
& 0xff);
387 cpu
.asregs
.sregs
[v
] = cpu
.asregs
.regs
[a
];
392 sim_engine_halt (sd
, NULL
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
399 /* This is a Form 1 instruction. */
400 int opcode
= inst
>> 8;
406 sim_engine_halt (sd
, NULL
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
408 case 0x01: /* ldi.l (immediate) */
410 int reg
= (inst
>> 4) & 0xf;
411 unsigned int val
= EXTRACT_WORD(pc
+2);
414 cpu
.asregs
.regs
[reg
] = val
;
418 case 0x02: /* mov (register-to-register) */
420 int dest
= (inst
>> 4) & 0xf;
421 int src
= (inst
) & 0xf;
424 cpu
.asregs
.regs
[dest
] = cpu
.asregs
.regs
[src
];
427 case 0x03: /* jsra */
429 unsigned int fn
= EXTRACT_WORD(pc
+2);
430 unsigned int sp
= cpu
.asregs
.regs
[1];
433 /* Save a slot for the static chain. */
436 /* Push the return address. */
438 wlat (scpu
, opc
, sp
, pc
+ 6);
440 /* Push the current frame pointer. */
442 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
444 /* Uncache the stack pointer and set the pc and $fp. */
445 cpu
.asregs
.regs
[1] = sp
;
446 cpu
.asregs
.regs
[0] = sp
;
452 unsigned int sp
= cpu
.asregs
.regs
[0];
456 /* Pop the frame pointer. */
457 cpu
.asregs
.regs
[0] = rlat (scpu
, opc
, sp
);
460 /* Pop the return address. */
461 pc
= rlat (scpu
, opc
, sp
) - 2;
464 /* Skip over the static chain slot. */
467 /* Uncache the stack pointer. */
468 cpu
.asregs
.regs
[1] = sp
;
471 case 0x05: /* add.l */
473 int a
= (inst
>> 4) & 0xf;
475 unsigned av
= cpu
.asregs
.regs
[a
];
476 unsigned bv
= cpu
.asregs
.regs
[b
];
479 cpu
.asregs
.regs
[a
] = av
+ bv
;
482 case 0x06: /* push */
484 int a
= (inst
>> 4) & 0xf;
486 int sp
= cpu
.asregs
.regs
[a
] - 4;
489 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[b
]);
490 cpu
.asregs
.regs
[a
] = sp
;
495 int a
= (inst
>> 4) & 0xf;
497 int sp
= cpu
.asregs
.regs
[a
];
500 cpu
.asregs
.regs
[b
] = rlat (scpu
, opc
, sp
);
501 cpu
.asregs
.regs
[a
] = sp
+ 4;
504 case 0x08: /* lda.l */
506 int reg
= (inst
>> 4) & 0xf;
507 unsigned int addr
= EXTRACT_WORD(pc
+2);
510 cpu
.asregs
.regs
[reg
] = rlat (scpu
, opc
, addr
);
514 case 0x09: /* sta.l */
516 int reg
= (inst
>> 4) & 0xf;
517 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;
531 xv
= cpu
.asregs
.regs
[src
];
532 cpu
.asregs
.regs
[dest
] = rlat (scpu
, opc
, xv
);
535 case 0x0b: /* st.l */
537 int dest
= (inst
>> 4) & 0xf;
538 int val
= inst
& 0xf;
541 wlat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
544 case 0x0c: /* ldo.l */
546 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
547 int a
= (inst
>> 4) & 0xf;
551 addr
+= cpu
.asregs
.regs
[b
];
552 cpu
.asregs
.regs
[a
] = rlat (scpu
, opc
, addr
);
556 case 0x0d: /* sto.l */
558 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
559 int a
= (inst
>> 4) & 0xf;
563 addr
+= cpu
.asregs
.regs
[a
];
564 wlat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
570 int a
= (inst
>> 4) & 0xf;
573 int va
= cpu
.asregs
.regs
[a
];
574 int vb
= cpu
.asregs
.regs
[b
];
581 cc
|= (va
< vb
? CC_LT
: 0);
582 cc
|= (va
> vb
? CC_GT
: 0);
583 cc
|= ((unsigned int) va
< (unsigned int) vb
? CC_LTU
: 0);
584 cc
|= ((unsigned int) va
> (unsigned int) vb
? CC_GTU
: 0);
592 case 0x10: /* sex.b */
594 int a
= (inst
>> 4) & 0xf;
596 signed char bv
= cpu
.asregs
.regs
[b
];
599 cpu
.asregs
.regs
[a
] = (int) bv
;
602 case 0x11: /* sex.s */
604 int a
= (inst
>> 4) & 0xf;
606 signed short bv
= cpu
.asregs
.regs
[b
];
609 cpu
.asregs
.regs
[a
] = (int) bv
;
612 case 0x12: /* zex.b */
614 int a
= (inst
>> 4) & 0xf;
616 signed char bv
= cpu
.asregs
.regs
[b
];
619 cpu
.asregs
.regs
[a
] = (int) bv
& 0xff;
622 case 0x13: /* zex.s */
624 int a
= (inst
>> 4) & 0xf;
626 signed short bv
= cpu
.asregs
.regs
[b
];
629 cpu
.asregs
.regs
[a
] = (int) bv
& 0xffff;
632 case 0x14: /* umul.x */
634 int a
= (inst
>> 4) & 0xf;
636 unsigned av
= cpu
.asregs
.regs
[a
];
637 unsigned bv
= cpu
.asregs
.regs
[b
];
638 unsigned long long r
=
639 (unsigned long long) av
* (unsigned long long) bv
;
642 cpu
.asregs
.regs
[a
] = r
>> 32;
645 case 0x15: /* mul.x */
647 int a
= (inst
>> 4) & 0xf;
649 unsigned av
= cpu
.asregs
.regs
[a
];
650 unsigned bv
= cpu
.asregs
.regs
[b
];
652 (signed long long) av
* (signed long long) bv
;
655 cpu
.asregs
.regs
[a
] = r
>> 32;
664 sim_engine_halt (sd
, NULL
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
669 unsigned int fn
= cpu
.asregs
.regs
[(inst
>> 4) & 0xf];
670 unsigned int sp
= cpu
.asregs
.regs
[1];
674 /* Save a slot for the static chain. */
677 /* Push the return address. */
679 wlat (scpu
, opc
, sp
, pc
+ 2);
681 /* Push the current frame pointer. */
683 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
685 /* Uncache the stack pointer and set the fp & pc. */
686 cpu
.asregs
.regs
[1] = sp
;
687 cpu
.asregs
.regs
[0] = sp
;
691 case 0x1a: /* jmpa */
693 unsigned int tgt
= EXTRACT_WORD(pc
+2);
699 case 0x1b: /* ldi.b (immediate) */
701 int reg
= (inst
>> 4) & 0xf;
702 unsigned int val
= EXTRACT_WORD(pc
+2);
705 cpu
.asregs
.regs
[reg
] = val
;
709 case 0x1c: /* ld.b (register indirect) */
711 int src
= inst
& 0xf;
712 int dest
= (inst
>> 4) & 0xf;
716 xv
= cpu
.asregs
.regs
[src
];
717 cpu
.asregs
.regs
[dest
] = rbat (scpu
, opc
, xv
);
720 case 0x1d: /* lda.b */
722 int reg
= (inst
>> 4) & 0xf;
723 unsigned int addr
= EXTRACT_WORD(pc
+2);
726 cpu
.asregs
.regs
[reg
] = rbat (scpu
, opc
, addr
);
730 case 0x1e: /* st.b */
732 int dest
= (inst
>> 4) & 0xf;
733 int val
= inst
& 0xf;
736 wbat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
739 case 0x1f: /* sta.b */
741 int reg
= (inst
>> 4) & 0xf;
742 unsigned int addr
= EXTRACT_WORD(pc
+2);
745 wbat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
749 case 0x20: /* ldi.s (immediate) */
751 int reg
= (inst
>> 4) & 0xf;
753 unsigned int val
= EXTRACT_WORD(pc
+2);
756 cpu
.asregs
.regs
[reg
] = val
;
760 case 0x21: /* ld.s (register indirect) */
762 int src
= inst
& 0xf;
763 int dest
= (inst
>> 4) & 0xf;
767 xv
= cpu
.asregs
.regs
[src
];
768 cpu
.asregs
.regs
[dest
] = rsat (scpu
, opc
, xv
);
771 case 0x22: /* lda.s */
773 int reg
= (inst
>> 4) & 0xf;
774 unsigned int addr
= EXTRACT_WORD(pc
+2);
777 cpu
.asregs
.regs
[reg
] = rsat (scpu
, opc
, addr
);
781 case 0x23: /* st.s */
783 int dest
= (inst
>> 4) & 0xf;
784 int val
= inst
& 0xf;
787 wsat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
790 case 0x24: /* sta.s */
792 int reg
= (inst
>> 4) & 0xf;
793 unsigned int addr
= EXTRACT_WORD(pc
+2);
796 wsat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
802 int reg
= (inst
>> 4) & 0xf;
805 pc
= cpu
.asregs
.regs
[reg
] - 2;
810 int a
= (inst
>> 4) & 0xf;
815 av
= cpu
.asregs
.regs
[a
];
816 bv
= cpu
.asregs
.regs
[b
];
817 cpu
.asregs
.regs
[a
] = av
& bv
;
820 case 0x27: /* lshr */
822 int a
= (inst
>> 4) & 0xf;
824 int av
= cpu
.asregs
.regs
[a
];
825 int bv
= cpu
.asregs
.regs
[b
];
828 cpu
.asregs
.regs
[a
] = (unsigned) ((unsigned) av
>> bv
);
831 case 0x28: /* ashl */
833 int a
= (inst
>> 4) & 0xf;
835 int av
= cpu
.asregs
.regs
[a
];
836 int bv
= cpu
.asregs
.regs
[b
];
839 cpu
.asregs
.regs
[a
] = av
<< bv
;
842 case 0x29: /* sub.l */
844 int a
= (inst
>> 4) & 0xf;
846 unsigned av
= cpu
.asregs
.regs
[a
];
847 unsigned bv
= cpu
.asregs
.regs
[b
];
850 cpu
.asregs
.regs
[a
] = av
- bv
;
855 int a
= (inst
>> 4) & 0xf;
857 int bv
= cpu
.asregs
.regs
[b
];
860 cpu
.asregs
.regs
[a
] = - bv
;
865 int a
= (inst
>> 4) & 0xf;
870 av
= cpu
.asregs
.regs
[a
];
871 bv
= cpu
.asregs
.regs
[b
];
872 cpu
.asregs
.regs
[a
] = av
| bv
;
877 int a
= (inst
>> 4) & 0xf;
879 int bv
= cpu
.asregs
.regs
[b
];
882 cpu
.asregs
.regs
[a
] = 0xffffffff ^ bv
;
885 case 0x2d: /* ashr */
887 int a
= (inst
>> 4) & 0xf;
889 int av
= cpu
.asregs
.regs
[a
];
890 int bv
= cpu
.asregs
.regs
[b
];
893 cpu
.asregs
.regs
[a
] = av
>> bv
;
898 int a
= (inst
>> 4) & 0xf;
903 av
= cpu
.asregs
.regs
[a
];
904 bv
= cpu
.asregs
.regs
[b
];
905 cpu
.asregs
.regs
[a
] = av
^ bv
;
908 case 0x2f: /* mul.l */
910 int a
= (inst
>> 4) & 0xf;
912 unsigned av
= cpu
.asregs
.regs
[a
];
913 unsigned bv
= cpu
.asregs
.regs
[b
];
916 cpu
.asregs
.regs
[a
] = av
* bv
;
921 unsigned int inum
= EXTRACT_WORD(pc
+2);
924 /* Set the special registers appropriately. */
925 cpu
.asregs
.sregs
[2] = 3; /* MOXIE_EX_SWI */
926 cpu
.asregs
.sregs
[3] = inum
;
929 case 0x1: /* SYS_exit */
931 sim_engine_halt (sd
, NULL
, NULL
, pc
, sim_exited
,
935 case 0x2: /* SYS_open */
938 int mode
= (int) convert_target_flags ((unsigned) cpu
.asregs
.regs
[3]);
939 int perm
= (int) cpu
.asregs
.regs
[4];
940 int fd
= open (fname
, mode
, perm
);
941 sim_core_read_buffer (sd
, scpu
, read_map
, fname
,
942 cpu
.asregs
.regs
[2], 1024);
943 /* FIXME - set errno */
944 cpu
.asregs
.regs
[2] = fd
;
947 case 0x4: /* SYS_read */
949 int fd
= cpu
.asregs
.regs
[2];
950 unsigned len
= (unsigned) cpu
.asregs
.regs
[4];
951 char *buf
= malloc (len
);
952 cpu
.asregs
.regs
[2] = read (fd
, buf
, len
);
953 sim_core_write_buffer (sd
, scpu
, write_map
, buf
,
954 cpu
.asregs
.regs
[3], len
);
958 case 0x5: /* SYS_write */
961 /* String length is at 0x12($fp) */
962 unsigned count
, len
= (unsigned) cpu
.asregs
.regs
[4];
964 sim_core_read_buffer (sd
, scpu
, read_map
, str
,
965 cpu
.asregs
.regs
[3], len
);
966 count
= write (cpu
.asregs
.regs
[2], str
, len
);
968 cpu
.asregs
.regs
[2] = count
;
971 case 0xffffffff: /* Linux System Call */
973 unsigned int handler
= cpu
.asregs
.sregs
[1];
974 unsigned int sp
= cpu
.asregs
.regs
[1];
976 /* Save a slot for the static chain. */
979 /* Push the return address. */
981 wlat (scpu
, opc
, sp
, pc
+ 6);
983 /* Push the current frame pointer. */
985 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
987 /* Uncache the stack pointer and set the fp & pc. */
988 cpu
.asregs
.regs
[1] = sp
;
989 cpu
.asregs
.regs
[0] = sp
;
998 case 0x31: /* div.l */
1000 int a
= (inst
>> 4) & 0xf;
1002 int av
= cpu
.asregs
.regs
[a
];
1003 int bv
= cpu
.asregs
.regs
[b
];
1006 cpu
.asregs
.regs
[a
] = av
/ bv
;
1009 case 0x32: /* udiv.l */
1011 int a
= (inst
>> 4) & 0xf;
1013 unsigned int av
= cpu
.asregs
.regs
[a
];
1014 unsigned int bv
= cpu
.asregs
.regs
[b
];
1017 cpu
.asregs
.regs
[a
] = (av
/ bv
);
1020 case 0x33: /* mod.l */
1022 int a
= (inst
>> 4) & 0xf;
1024 int av
= cpu
.asregs
.regs
[a
];
1025 int bv
= cpu
.asregs
.regs
[b
];
1028 cpu
.asregs
.regs
[a
] = av
% bv
;
1031 case 0x34: /* umod.l */
1033 int a
= (inst
>> 4) & 0xf;
1035 unsigned int av
= cpu
.asregs
.regs
[a
];
1036 unsigned int bv
= cpu
.asregs
.regs
[b
];
1039 cpu
.asregs
.regs
[a
] = (av
% bv
);
1042 case 0x35: /* brk */
1044 sim_engine_halt (sd
, NULL
, NULL
, pc
, sim_stopped
, SIM_SIGTRAP
);
1045 pc
-= 2; /* Adjust pc */
1047 case 0x36: /* ldo.b */
1049 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
1050 int a
= (inst
>> 4) & 0xf;
1054 addr
+= cpu
.asregs
.regs
[b
];
1055 cpu
.asregs
.regs
[a
] = rbat (scpu
, opc
, addr
);
1059 case 0x37: /* sto.b */
1061 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
1062 int a
= (inst
>> 4) & 0xf;
1066 addr
+= cpu
.asregs
.regs
[a
];
1067 wbat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
1071 case 0x38: /* ldo.s */
1073 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
1074 int a
= (inst
>> 4) & 0xf;
1078 addr
+= cpu
.asregs
.regs
[b
];
1079 cpu
.asregs
.regs
[a
] = rsat (scpu
, opc
, addr
);
1083 case 0x39: /* sto.s */
1085 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
1086 int a
= (inst
>> 4) & 0xf;
1090 addr
+= cpu
.asregs
.regs
[a
];
1091 wsat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
1098 sim_engine_halt (sd
, NULL
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1105 cpu
.asregs
.regs
[PC_REGNO
] = pc
;
1110 sim_store_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
1112 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1118 /* misalignment safe */
1119 ival
= moxie_extract_unsigned_integer (memory
, 4);
1120 cpu
.asints
[rn
] = ival
;
1130 sim_fetch_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
1132 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1136 long ival
= cpu
.asints
[rn
];
1138 /* misalignment-safe */
1139 moxie_store_unsigned_integer (memory
, 4, ival
);
1149 moxie_pc_get (sim_cpu
*cpu
)
1151 return cpu
->registers
[PCIDX
];
1155 moxie_pc_set (sim_cpu
*cpu
, sim_cia pc
)
1157 cpu
->registers
[PCIDX
] = pc
;
1161 free_state (SIM_DESC sd
)
1163 if (STATE_MODULES (sd
) != NULL
)
1164 sim_module_uninstall (sd
);
1165 sim_cpu_free_all (sd
);
1166 sim_state_free (sd
);
1170 sim_open (SIM_OPEN_KIND kind
, host_callback
*cb
, struct bfd
*abfd
, char **argv
)
1173 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
1174 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
1176 /* The cpu data is kept in a separately allocated chunk of memory. */
1177 if (sim_cpu_alloc_all (sd
, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK
)
1183 STATE_WATCHPOINTS (sd
)->pc
= &cpu
.asregs
.regs
[PC_REGNO
];
1184 STATE_WATCHPOINTS (sd
)->sizeof_pc
= sizeof (word
);
1186 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
1192 /* getopt will print the error message so we just have to exit if this fails.
1193 FIXME: Hmmm... in the case of gdb we need getopt to call
1195 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
1201 sim_do_command(sd
," memory region 0x00000000,0x4000000") ;
1202 sim_do_command(sd
," memory region 0xE0000000,0x10000") ;
1204 /* Check for/establish the a reference program image. */
1205 if (sim_analyze_program (sd
,
1206 (STATE_PROG_ARGV (sd
) != NULL
1207 ? *STATE_PROG_ARGV (sd
)
1208 : NULL
), abfd
) != SIM_RC_OK
)
1214 /* Configure/verify the target byte order and other runtime
1215 configuration options. */
1216 if (sim_config (sd
) != SIM_RC_OK
)
1218 sim_module_uninstall (sd
);
1222 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
1224 /* Uninstall the modules to avoid memory leaks,
1225 file descriptor leaks, etc. */
1226 sim_module_uninstall (sd
);
1230 /* CPU specific initialization. */
1231 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
1233 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
1235 CPU_PC_FETCH (cpu
) = moxie_pc_get
;
1236 CPU_PC_STORE (cpu
) = moxie_pc_set
;
1238 set_initial_gprs (); /* Reset the GPR registers. */
1245 sim_close (SIM_DESC sd
, int quitting
)
1251 /* Load the device tree blob. */
1254 load_dtb (SIM_DESC sd
, const char *filename
)
1257 FILE *f
= fopen (filename
, "rb");
1259 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1261 /* Don't warn as the sim works fine w/out a device tree. */
1264 fseek (f
, 0, SEEK_END
);
1266 fseek (f
, 0, SEEK_SET
);
1267 buf
= alloca (size
);
1268 if (size
!= fread (buf
, 1, size
, f
))
1270 sim_io_eprintf (sd
, "ERROR: error reading ``%s''.\n", filename
);
1273 sim_core_write_buffer (sd
, scpu
, write_map
, buf
, 0xE0000000, size
);
1274 cpu
.asregs
.sregs
[9] = 0xE0000000;
1279 sim_create_inferior (SIM_DESC sd
, struct bfd
*prog_bfd
, char **argv
, char **env
)
1283 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1285 if (prog_bfd
!= NULL
)
1286 cpu
.asregs
.regs
[PC_REGNO
] = bfd_get_start_address (prog_bfd
);
1288 /* Copy args into target memory. */
1290 for (argc
= 0; avp
&& *avp
; avp
++)
1293 /* Target memory looks like this:
1294 0x00000000 zero word
1295 0x00000004 argc word
1296 0x00000008 start of argv
1298 0x0000???? end of argv
1299 0x0000???? zero word
1300 0x0000???? start of data pointed to by argv */
1302 wlat (scpu
, 0, 0, 0);
1303 wlat (scpu
, 0, 4, argc
);
1305 /* tp is the offset of our first argv data. */
1306 tp
= 4 + 4 + argc
* 4 + 4;
1308 for (i
= 0; i
< argc
; i
++)
1310 /* Set the argv value. */
1311 wlat (scpu
, 0, 4 + 4 + i
* 4, tp
);
1313 /* Store the string. */
1314 sim_core_write_buffer (sd
, scpu
, write_map
, argv
[i
],
1315 tp
, strlen(argv
[i
])+1);
1316 tp
+= strlen (argv
[i
]) + 1;
1319 wlat (scpu
, 0, 4 + 4 + i
* 4, 0);
This page took 0.057388 seconds and 5 git commands to generate.