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 */
118 unsigned long long insts
; /* instruction counter */
127 /* TODO: This should be moved to sim-main.h:_sim_cpu. */
130 struct moxie_regset asregs
;
131 word asints
[1]; /* but accessed larger... */
135 set_initial_gprs (void)
140 /* Set up machine just out of reset. */
141 cpu
.asregs
.regs
[PC_REGNO
] = 0;
143 /* Clean out the register contents. */
144 for (i
= 0; i
< NUM_MOXIE_REGS
; i
++)
145 cpu
.asregs
.regs
[i
] = 0;
146 for (i
= 0; i
< NUM_MOXIE_SREGS
; i
++)
147 cpu
.asregs
.sregs
[i
] = 0;
150 /* Write a 1 byte value to memory. */
153 wbat (sim_cpu
*scpu
, word pc
, word x
, word v
)
155 address_word cia
= CIA_GET (scpu
);
157 sim_core_write_aligned_1 (scpu
, cia
, write_map
, x
, v
);
160 /* Write a 2 byte value to memory. */
163 wsat (sim_cpu
*scpu
, word pc
, word x
, word v
)
165 address_word cia
= CIA_GET (scpu
);
167 sim_core_write_aligned_2 (scpu
, cia
, write_map
, x
, v
);
170 /* Write a 4 byte value to memory. */
173 wlat (sim_cpu
*scpu
, word pc
, word x
, word v
)
175 address_word cia
= CIA_GET (scpu
);
177 sim_core_write_aligned_4 (scpu
, cia
, write_map
, x
, v
);
180 /* Read 2 bytes from memory. */
183 rsat (sim_cpu
*scpu
, word pc
, word x
)
185 address_word cia
= CIA_GET (scpu
);
187 return (sim_core_read_aligned_2 (scpu
, cia
, read_map
, x
));
190 /* Read 1 byte from memory. */
193 rbat (sim_cpu
*scpu
, word pc
, word x
)
195 address_word cia
= CIA_GET (scpu
);
197 return (sim_core_read_aligned_1 (scpu
, cia
, read_map
, x
));
200 /* Read 4 bytes from memory. */
203 rlat (sim_cpu
*scpu
, word pc
, word x
)
205 address_word cia
= CIA_GET (scpu
);
207 return (sim_core_read_aligned_4 (scpu
, cia
, read_map
, x
));
210 #define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; }
213 convert_target_flags (unsigned int tflags
)
215 unsigned int hflags
= 0x0;
217 CHECK_FLAG(0x0001, O_WRONLY
);
218 CHECK_FLAG(0x0002, O_RDWR
);
219 CHECK_FLAG(0x0008, O_APPEND
);
220 CHECK_FLAG(0x0200, O_CREAT
);
221 CHECK_FLAG(0x0400, O_TRUNC
);
222 CHECK_FLAG(0x0800, O_EXCL
);
223 CHECK_FLAG(0x2000, O_SYNC
);
227 "Simulator Error: problem converting target open flags for host. 0x%x\n",
233 /* TODO: Move to sim-trace.h. */
234 static FILE *tracefile
;
235 static const int tracing
= 0;
236 #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]);
239 sim_resume (SIM_DESC sd
, int step
, int siggnal
)
242 unsigned long long insts
;
244 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
245 address_word cia
= CIA_GET (scpu
);
247 cpu
.asregs
.exception
= step
? SIGTRAP
: 0;
248 pc
= cpu
.asregs
.regs
[PC_REGNO
];
249 insts
= cpu
.asregs
.insts
;
251 /* Run instructions here. */
256 /* Fetch the instruction at pc. */
257 inst
= (sim_core_read_aligned_1 (scpu
, cia
, read_map
, pc
) << 8)
258 + sim_core_read_aligned_1 (scpu
, cia
, read_map
, pc
+1);
260 /* Decode instruction. */
261 if (inst
& (1 << 15))
263 if (inst
& (1 << 14))
265 /* This is a Form 3 instruction. */
266 int opcode
= (inst
>> 10 & 0xf);
273 if (cpu
.asregs
.cc
& CC_EQ
)
274 pc
+= INST2OFFSET(inst
);
280 if (! (cpu
.asregs
.cc
& CC_EQ
))
281 pc
+= INST2OFFSET(inst
);
287 if (cpu
.asregs
.cc
& CC_LT
)
288 pc
+= INST2OFFSET(inst
);
293 if (cpu
.asregs
.cc
& CC_GT
)
294 pc
+= INST2OFFSET(inst
);
297 case 0x04: /* bltu */
300 if (cpu
.asregs
.cc
& CC_LTU
)
301 pc
+= INST2OFFSET(inst
);
304 case 0x05: /* bgtu */
307 if (cpu
.asregs
.cc
& CC_GTU
)
308 pc
+= INST2OFFSET(inst
);
314 if (cpu
.asregs
.cc
& (CC_GT
| CC_EQ
))
315 pc
+= INST2OFFSET(inst
);
321 if (cpu
.asregs
.cc
& (CC_LT
| CC_EQ
))
322 pc
+= INST2OFFSET(inst
);
325 case 0x08: /* bgeu */
328 if (cpu
.asregs
.cc
& (CC_GTU
| CC_EQ
))
329 pc
+= INST2OFFSET(inst
);
332 case 0x09: /* bleu */
335 if (cpu
.asregs
.cc
& (CC_LTU
| CC_EQ
))
336 pc
+= INST2OFFSET(inst
);
342 cpu
.asregs
.exception
= SIGILL
;
349 /* This is a Form 2 instruction. */
350 int opcode
= (inst
>> 12 & 0x3);
355 int a
= (inst
>> 8) & 0xf;
356 unsigned av
= cpu
.asregs
.regs
[a
];
357 unsigned v
= (inst
& 0xff);
360 cpu
.asregs
.regs
[a
] = av
+ v
;
365 int a
= (inst
>> 8) & 0xf;
366 unsigned av
= cpu
.asregs
.regs
[a
];
367 unsigned v
= (inst
& 0xff);
370 cpu
.asregs
.regs
[a
] = av
- v
;
375 int a
= (inst
>> 8) & 0xf;
376 unsigned v
= (inst
& 0xff);
379 cpu
.asregs
.regs
[a
] = cpu
.asregs
.sregs
[v
];
384 int a
= (inst
>> 8) & 0xf;
385 unsigned v
= (inst
& 0xff);
388 cpu
.asregs
.sregs
[v
] = cpu
.asregs
.regs
[a
];
393 cpu
.asregs
.exception
= SIGILL
;
400 /* This is a Form 1 instruction. */
401 int opcode
= inst
>> 8;
407 cpu
.asregs
.exception
= SIGILL
;
409 case 0x01: /* ldi.l (immediate) */
411 int reg
= (inst
>> 4) & 0xf;
412 unsigned int val
= EXTRACT_WORD(pc
+2);
415 cpu
.asregs
.regs
[reg
] = val
;
419 case 0x02: /* mov (register-to-register) */
421 int dest
= (inst
>> 4) & 0xf;
422 int src
= (inst
) & 0xf;
425 cpu
.asregs
.regs
[dest
] = cpu
.asregs
.regs
[src
];
428 case 0x03: /* jsra */
430 unsigned int fn
= EXTRACT_WORD(pc
+2);
431 unsigned int sp
= cpu
.asregs
.regs
[1];
434 /* Save a slot for the static chain. */
437 /* Push the return address. */
439 wlat (scpu
, opc
, sp
, pc
+ 6);
441 /* Push the current frame pointer. */
443 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
445 /* Uncache the stack pointer and set the pc and $fp. */
446 cpu
.asregs
.regs
[1] = sp
;
447 cpu
.asregs
.regs
[0] = sp
;
453 unsigned int sp
= cpu
.asregs
.regs
[0];
457 /* Pop the frame pointer. */
458 cpu
.asregs
.regs
[0] = rlat (scpu
, opc
, sp
);
461 /* Pop the return address. */
462 pc
= rlat (scpu
, opc
, sp
) - 2;
465 /* Skip over the static chain slot. */
468 /* Uncache the stack pointer. */
469 cpu
.asregs
.regs
[1] = sp
;
472 case 0x05: /* add.l */
474 int a
= (inst
>> 4) & 0xf;
476 unsigned av
= cpu
.asregs
.regs
[a
];
477 unsigned bv
= cpu
.asregs
.regs
[b
];
480 cpu
.asregs
.regs
[a
] = av
+ bv
;
483 case 0x06: /* push */
485 int a
= (inst
>> 4) & 0xf;
487 int sp
= cpu
.asregs
.regs
[a
] - 4;
490 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[b
]);
491 cpu
.asregs
.regs
[a
] = sp
;
496 int a
= (inst
>> 4) & 0xf;
498 int sp
= cpu
.asregs
.regs
[a
];
501 cpu
.asregs
.regs
[b
] = rlat (scpu
, opc
, sp
);
502 cpu
.asregs
.regs
[a
] = sp
+ 4;
505 case 0x08: /* lda.l */
507 int reg
= (inst
>> 4) & 0xf;
508 unsigned int addr
= EXTRACT_WORD(pc
+2);
511 cpu
.asregs
.regs
[reg
] = rlat (scpu
, opc
, addr
);
515 case 0x09: /* sta.l */
517 int reg
= (inst
>> 4) & 0xf;
518 unsigned int addr
= EXTRACT_WORD(pc
+2);
521 wlat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
525 case 0x0a: /* ld.l (register indirect) */
527 int src
= inst
& 0xf;
528 int dest
= (inst
>> 4) & 0xf;
532 xv
= cpu
.asregs
.regs
[src
];
533 cpu
.asregs
.regs
[dest
] = rlat (scpu
, opc
, xv
);
536 case 0x0b: /* st.l */
538 int dest
= (inst
>> 4) & 0xf;
539 int val
= inst
& 0xf;
542 wlat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
545 case 0x0c: /* ldo.l */
547 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
548 int a
= (inst
>> 4) & 0xf;
552 addr
+= cpu
.asregs
.regs
[b
];
553 cpu
.asregs
.regs
[a
] = rlat (scpu
, opc
, addr
);
557 case 0x0d: /* sto.l */
559 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
560 int a
= (inst
>> 4) & 0xf;
564 addr
+= cpu
.asregs
.regs
[a
];
565 wlat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
571 int a
= (inst
>> 4) & 0xf;
574 int va
= cpu
.asregs
.regs
[a
];
575 int vb
= cpu
.asregs
.regs
[b
];
582 cc
|= (va
< vb
? CC_LT
: 0);
583 cc
|= (va
> vb
? CC_GT
: 0);
584 cc
|= ((unsigned int) va
< (unsigned int) vb
? CC_LTU
: 0);
585 cc
|= ((unsigned int) va
> (unsigned int) vb
? CC_GTU
: 0);
593 case 0x10: /* sex.b */
595 int a
= (inst
>> 4) & 0xf;
597 signed char bv
= cpu
.asregs
.regs
[b
];
600 cpu
.asregs
.regs
[a
] = (int) bv
;
603 case 0x11: /* sex.s */
605 int a
= (inst
>> 4) & 0xf;
607 signed short bv
= cpu
.asregs
.regs
[b
];
610 cpu
.asregs
.regs
[a
] = (int) bv
;
613 case 0x12: /* zex.b */
615 int a
= (inst
>> 4) & 0xf;
617 signed char bv
= cpu
.asregs
.regs
[b
];
620 cpu
.asregs
.regs
[a
] = (int) bv
& 0xff;
623 case 0x13: /* zex.s */
625 int a
= (inst
>> 4) & 0xf;
627 signed short bv
= cpu
.asregs
.regs
[b
];
630 cpu
.asregs
.regs
[a
] = (int) bv
& 0xffff;
633 case 0x14: /* umul.x */
635 int a
= (inst
>> 4) & 0xf;
637 unsigned av
= cpu
.asregs
.regs
[a
];
638 unsigned bv
= cpu
.asregs
.regs
[b
];
639 unsigned long long r
=
640 (unsigned long long) av
* (unsigned long long) bv
;
643 cpu
.asregs
.regs
[a
] = r
>> 32;
646 case 0x15: /* mul.x */
648 int a
= (inst
>> 4) & 0xf;
650 unsigned av
= cpu
.asregs
.regs
[a
];
651 unsigned bv
= cpu
.asregs
.regs
[b
];
653 (signed long long) av
* (signed long long) bv
;
656 cpu
.asregs
.regs
[a
] = r
>> 32;
665 cpu
.asregs
.exception
= SIGILL
;
670 unsigned int fn
= cpu
.asregs
.regs
[(inst
>> 4) & 0xf];
671 unsigned int sp
= cpu
.asregs
.regs
[1];
675 /* Save a slot for the static chain. */
678 /* Push the return address. */
680 wlat (scpu
, opc
, sp
, pc
+ 2);
682 /* Push the current frame pointer. */
684 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
686 /* Uncache the stack pointer and set the fp & pc. */
687 cpu
.asregs
.regs
[1] = sp
;
688 cpu
.asregs
.regs
[0] = sp
;
692 case 0x1a: /* jmpa */
694 unsigned int tgt
= EXTRACT_WORD(pc
+2);
700 case 0x1b: /* ldi.b (immediate) */
702 int reg
= (inst
>> 4) & 0xf;
703 unsigned int val
= EXTRACT_WORD(pc
+2);
706 cpu
.asregs
.regs
[reg
] = val
;
710 case 0x1c: /* ld.b (register indirect) */
712 int src
= inst
& 0xf;
713 int dest
= (inst
>> 4) & 0xf;
717 xv
= cpu
.asregs
.regs
[src
];
718 cpu
.asregs
.regs
[dest
] = rbat (scpu
, opc
, xv
);
721 case 0x1d: /* lda.b */
723 int reg
= (inst
>> 4) & 0xf;
724 unsigned int addr
= EXTRACT_WORD(pc
+2);
727 cpu
.asregs
.regs
[reg
] = rbat (scpu
, opc
, addr
);
731 case 0x1e: /* st.b */
733 int dest
= (inst
>> 4) & 0xf;
734 int val
= inst
& 0xf;
737 wbat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
740 case 0x1f: /* sta.b */
742 int reg
= (inst
>> 4) & 0xf;
743 unsigned int addr
= EXTRACT_WORD(pc
+2);
746 wbat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
750 case 0x20: /* ldi.s (immediate) */
752 int reg
= (inst
>> 4) & 0xf;
754 unsigned int val
= EXTRACT_WORD(pc
+2);
757 cpu
.asregs
.regs
[reg
] = val
;
761 case 0x21: /* ld.s (register indirect) */
763 int src
= inst
& 0xf;
764 int dest
= (inst
>> 4) & 0xf;
768 xv
= cpu
.asregs
.regs
[src
];
769 cpu
.asregs
.regs
[dest
] = rsat (scpu
, opc
, xv
);
772 case 0x22: /* lda.s */
774 int reg
= (inst
>> 4) & 0xf;
775 unsigned int addr
= EXTRACT_WORD(pc
+2);
778 cpu
.asregs
.regs
[reg
] = rsat (scpu
, opc
, addr
);
782 case 0x23: /* st.s */
784 int dest
= (inst
>> 4) & 0xf;
785 int val
= inst
& 0xf;
788 wsat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
791 case 0x24: /* sta.s */
793 int reg
= (inst
>> 4) & 0xf;
794 unsigned int addr
= EXTRACT_WORD(pc
+2);
797 wsat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
803 int reg
= (inst
>> 4) & 0xf;
806 pc
= cpu
.asregs
.regs
[reg
] - 2;
811 int a
= (inst
>> 4) & 0xf;
816 av
= cpu
.asregs
.regs
[a
];
817 bv
= cpu
.asregs
.regs
[b
];
818 cpu
.asregs
.regs
[a
] = av
& bv
;
821 case 0x27: /* lshr */
823 int a
= (inst
>> 4) & 0xf;
825 int av
= cpu
.asregs
.regs
[a
];
826 int bv
= cpu
.asregs
.regs
[b
];
829 cpu
.asregs
.regs
[a
] = (unsigned) ((unsigned) av
>> bv
);
832 case 0x28: /* ashl */
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
] = av
<< bv
;
843 case 0x29: /* sub.l */
845 int a
= (inst
>> 4) & 0xf;
847 unsigned av
= cpu
.asregs
.regs
[a
];
848 unsigned bv
= cpu
.asregs
.regs
[b
];
851 cpu
.asregs
.regs
[a
] = av
- bv
;
856 int a
= (inst
>> 4) & 0xf;
858 int bv
= cpu
.asregs
.regs
[b
];
861 cpu
.asregs
.regs
[a
] = - bv
;
866 int a
= (inst
>> 4) & 0xf;
871 av
= cpu
.asregs
.regs
[a
];
872 bv
= cpu
.asregs
.regs
[b
];
873 cpu
.asregs
.regs
[a
] = av
| bv
;
878 int a
= (inst
>> 4) & 0xf;
880 int bv
= cpu
.asregs
.regs
[b
];
883 cpu
.asregs
.regs
[a
] = 0xffffffff ^ bv
;
886 case 0x2d: /* ashr */
888 int a
= (inst
>> 4) & 0xf;
890 int av
= cpu
.asregs
.regs
[a
];
891 int bv
= cpu
.asregs
.regs
[b
];
894 cpu
.asregs
.regs
[a
] = av
>> bv
;
899 int a
= (inst
>> 4) & 0xf;
904 av
= cpu
.asregs
.regs
[a
];
905 bv
= cpu
.asregs
.regs
[b
];
906 cpu
.asregs
.regs
[a
] = av
^ bv
;
909 case 0x2f: /* mul.l */
911 int a
= (inst
>> 4) & 0xf;
913 unsigned av
= cpu
.asregs
.regs
[a
];
914 unsigned bv
= cpu
.asregs
.regs
[b
];
917 cpu
.asregs
.regs
[a
] = av
* bv
;
922 unsigned int inum
= EXTRACT_WORD(pc
+2);
925 /* Set the special registers appropriately. */
926 cpu
.asregs
.sregs
[2] = 3; /* MOXIE_EX_SWI */
927 cpu
.asregs
.sregs
[3] = inum
;
930 case 0x1: /* SYS_exit */
932 cpu
.asregs
.exception
= SIGQUIT
;
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 cpu
.asregs
.exception
= 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 cpu
.asregs
.exception
= SIGILL
;
1106 } while (!cpu
.asregs
.exception
);
1108 /* Hide away the things we've cached while executing. */
1109 cpu
.asregs
.regs
[PC_REGNO
] = pc
;
1110 cpu
.asregs
.insts
+= insts
; /* instructions done ... */
1114 sim_store_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
1116 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1122 /* misalignment safe */
1123 ival
= moxie_extract_unsigned_integer (memory
, 4);
1124 cpu
.asints
[rn
] = ival
;
1134 sim_fetch_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
1136 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1140 long ival
= cpu
.asints
[rn
];
1142 /* misalignment-safe */
1143 moxie_store_unsigned_integer (memory
, 4, ival
);
1153 free_state (SIM_DESC sd
)
1155 if (STATE_MODULES (sd
) != NULL
)
1156 sim_module_uninstall (sd
);
1157 sim_cpu_free_all (sd
);
1158 sim_state_free (sd
);
1162 sim_open (SIM_OPEN_KIND kind
, host_callback
*cb
, struct bfd
*abfd
, char **argv
)
1164 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
1165 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
1167 /* The cpu data is kept in a separately allocated chunk of memory. */
1168 if (sim_cpu_alloc_all (sd
, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK
)
1174 STATE_WATCHPOINTS (sd
)->pc
= &cpu
.asregs
.regs
[PC_REGNO
];
1175 STATE_WATCHPOINTS (sd
)->sizeof_pc
= sizeof (word
);
1177 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
1183 /* getopt will print the error message so we just have to exit if this fails.
1184 FIXME: Hmmm... in the case of gdb we need getopt to call
1186 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
1192 sim_do_command(sd
," memory region 0x00000000,0x4000000") ;
1193 sim_do_command(sd
," memory region 0xE0000000,0x10000") ;
1195 /* Check for/establish the a reference program image. */
1196 if (sim_analyze_program (sd
,
1197 (STATE_PROG_ARGV (sd
) != NULL
1198 ? *STATE_PROG_ARGV (sd
)
1199 : NULL
), abfd
) != SIM_RC_OK
)
1205 /* Configure/verify the target byte order and other runtime
1206 configuration options. */
1207 if (sim_config (sd
) != SIM_RC_OK
)
1209 sim_module_uninstall (sd
);
1213 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
1215 /* Uninstall the modules to avoid memory leaks,
1216 file descriptor leaks, etc. */
1217 sim_module_uninstall (sd
);
1221 /* CPU specific initialization. */
1222 set_initial_gprs ();
1228 sim_close (SIM_DESC sd
, int quitting
)
1234 /* Load the device tree blob. */
1237 load_dtb (SIM_DESC sd
, const char *filename
)
1240 FILE *f
= fopen (filename
, "rb");
1242 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1245 printf ("WARNING: ``%s'' could not be opened.\n", filename
);
1248 fseek (f
, 0, SEEK_END
);
1250 fseek (f
, 0, SEEK_SET
);
1251 buf
= alloca (size
);
1252 if (size
!= fread (buf
, 1, size
, f
))
1254 printf ("ERROR: error reading ``%s''.\n", filename
);
1257 sim_core_write_buffer (sd
, scpu
, write_map
, buf
, 0xE0000000, size
);
1258 cpu
.asregs
.sregs
[9] = 0xE0000000;
1263 sim_create_inferior (SIM_DESC sd
, struct bfd
*prog_bfd
, char **argv
, char **env
)
1267 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1269 if (prog_bfd
!= NULL
)
1270 cpu
.asregs
.regs
[PC_REGNO
] = bfd_get_start_address (prog_bfd
);
1272 /* Copy args into target memory. */
1274 for (argc
= 0; avp
&& *avp
; avp
++)
1277 /* Target memory looks like this:
1278 0x00000000 zero word
1279 0x00000004 argc word
1280 0x00000008 start of argv
1282 0x0000???? end of argv
1283 0x0000???? zero word
1284 0x0000???? start of data pointed to by argv */
1286 wlat (scpu
, 0, 0, 0);
1287 wlat (scpu
, 0, 4, argc
);
1289 /* tp is the offset of our first argv data. */
1290 tp
= 4 + 4 + argc
* 4 + 4;
1292 for (i
= 0; i
< argc
; i
++)
1294 /* Set the argv value. */
1295 wlat (scpu
, 0, 4 + 4 + i
* 4, tp
);
1297 /* Store the string. */
1298 sim_core_write_buffer (sd
, scpu
, write_map
, argv
[i
],
1299 tp
, strlen(argv
[i
])+1);
1300 tp
+= strlen (argv
[i
]) + 1;
1303 wlat (scpu
, 0, 4 + 4 + i
* 4, 0);
This page took 0.058951 seconds and 5 git commands to generate.