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 (addr
, len
)
62 unsigned char * startaddr
= (unsigned char *)addr
;
63 unsigned char * endaddr
= startaddr
+ len
;
65 if (len
> (int) sizeof (unsigned long))
66 printf ("That operation is not available on integers of more than %d bytes.",
67 sizeof (unsigned long));
69 /* Start at the most significant end of the integer, and work towards
70 the least significant. */
73 for (p
= endaddr
; p
> startaddr
;)
74 retval
= (retval
<< 8) | * -- p
;
80 moxie_store_unsigned_integer (addr
, len
, val
)
86 unsigned char * startaddr
= (unsigned char *)addr
;
87 unsigned char * endaddr
= startaddr
+ len
;
89 for (p
= endaddr
; p
> startaddr
;)
96 /* moxie register names. */
97 static const char *reg_names
[16] =
98 { "$fp", "$sp", "$r0", "$r1", "$r2", "$r3", "$r4", "$r5",
99 "$r6", "$r7", "$r8", "$r9", "$r10", "$r11", "$r12", "$r13" };
101 /* The machine state.
103 This state is maintained in host byte order. The fetch/store
104 register functions must translate between host byte order and the
105 target processor byte order. Keeping this data in target byte
106 order simplifies the register read/write functions. Keeping this
107 data in native order improves the performance of the simulator.
108 Simulation speed is deemed more important. */
110 #define NUM_MOXIE_REGS 17 /* Including PC */
111 #define NUM_MOXIE_SREGS 256 /* The special registers */
114 /* The ordering of the moxie_regset structure is matched in the
115 gdb/config/moxie/tm-moxie.h file in the REGISTER_NAMES macro. */
116 /* TODO: This should be moved to sim-main.h:_sim_cpu. */
119 word regs
[NUM_MOXIE_REGS
+ 1]; /* primary registers */
120 word sregs
[256]; /* special registers */
121 word cc
; /* the condition code reg */
123 unsigned long long insts
; /* instruction counter */
132 /* TODO: This should be moved to sim-main.h:_sim_cpu. */
135 struct moxie_regset asregs
;
136 word asints
[1]; /* but accessed larger... */
140 set_initial_gprs (void)
145 /* Set up machine just out of reset. */
146 cpu
.asregs
.regs
[PC_REGNO
] = 0;
148 /* Clean out the register contents. */
149 for (i
= 0; i
< NUM_MOXIE_REGS
; i
++)
150 cpu
.asregs
.regs
[i
] = 0;
151 for (i
= 0; i
< NUM_MOXIE_SREGS
; i
++)
152 cpu
.asregs
.sregs
[i
] = 0;
155 /* Write a 1 byte value to memory. */
158 wbat (sim_cpu
*scpu
, word pc
, word x
, word v
)
160 address_word cia
= CIA_GET (scpu
);
162 sim_core_write_aligned_1 (scpu
, cia
, write_map
, x
, v
);
165 /* Write a 2 byte value to memory. */
168 wsat (sim_cpu
*scpu
, word pc
, word x
, word v
)
170 address_word cia
= CIA_GET (scpu
);
172 sim_core_write_aligned_2 (scpu
, cia
, write_map
, x
, v
);
175 /* Write a 4 byte value to memory. */
178 wlat (sim_cpu
*scpu
, word pc
, word x
, word v
)
180 address_word cia
= CIA_GET (scpu
);
182 sim_core_write_aligned_4 (scpu
, cia
, write_map
, x
, v
);
185 /* Read 2 bytes from memory. */
188 rsat (sim_cpu
*scpu
, word pc
, word x
)
190 address_word cia
= CIA_GET (scpu
);
192 return (sim_core_read_aligned_2 (scpu
, cia
, read_map
, x
));
195 /* Read 1 byte from memory. */
198 rbat (sim_cpu
*scpu
, word pc
, word x
)
200 address_word cia
= CIA_GET (scpu
);
202 return (sim_core_read_aligned_1 (scpu
, cia
, read_map
, x
));
205 /* Read 4 bytes from memory. */
208 rlat (sim_cpu
*scpu
, word pc
, word x
)
210 address_word cia
= CIA_GET (scpu
);
212 return (sim_core_read_aligned_4 (scpu
, cia
, read_map
, x
));
215 #define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; }
218 convert_target_flags (unsigned int tflags
)
220 unsigned int hflags
= 0x0;
222 CHECK_FLAG(0x0001, O_WRONLY
);
223 CHECK_FLAG(0x0002, O_RDWR
);
224 CHECK_FLAG(0x0008, O_APPEND
);
225 CHECK_FLAG(0x0200, O_CREAT
);
226 CHECK_FLAG(0x0400, O_TRUNC
);
227 CHECK_FLAG(0x0800, O_EXCL
);
228 CHECK_FLAG(0x2000, O_SYNC
);
232 "Simulator Error: problem converting target open flags for host. 0x%x\n",
238 /* TODO: Move to sim-trace.h. */
239 static FILE *tracefile
;
240 static const int tracing
= 0;
241 #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]);
244 sim_resume (sd
, step
, siggnal
)
249 unsigned long long insts
;
251 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
252 address_word cia
= CIA_GET (scpu
);
254 cpu
.asregs
.exception
= step
? SIGTRAP
: 0;
255 pc
= cpu
.asregs
.regs
[PC_REGNO
];
256 insts
= cpu
.asregs
.insts
;
258 /* Run instructions here. */
263 /* Fetch the instruction at pc. */
264 inst
= (sim_core_read_aligned_1 (scpu
, cia
, read_map
, pc
) << 8)
265 + sim_core_read_aligned_1 (scpu
, cia
, read_map
, pc
+1);
267 /* Decode instruction. */
268 if (inst
& (1 << 15))
270 if (inst
& (1 << 14))
272 /* This is a Form 3 instruction. */
273 int opcode
= (inst
>> 10 & 0xf);
280 if (cpu
.asregs
.cc
& CC_EQ
)
281 pc
+= INST2OFFSET(inst
);
287 if (! (cpu
.asregs
.cc
& CC_EQ
))
288 pc
+= INST2OFFSET(inst
);
294 if (cpu
.asregs
.cc
& CC_LT
)
295 pc
+= INST2OFFSET(inst
);
300 if (cpu
.asregs
.cc
& CC_GT
)
301 pc
+= INST2OFFSET(inst
);
304 case 0x04: /* bltu */
307 if (cpu
.asregs
.cc
& CC_LTU
)
308 pc
+= INST2OFFSET(inst
);
311 case 0x05: /* bgtu */
314 if (cpu
.asregs
.cc
& CC_GTU
)
315 pc
+= INST2OFFSET(inst
);
321 if (cpu
.asregs
.cc
& (CC_GT
| CC_EQ
))
322 pc
+= INST2OFFSET(inst
);
328 if (cpu
.asregs
.cc
& (CC_LT
| CC_EQ
))
329 pc
+= INST2OFFSET(inst
);
332 case 0x08: /* bgeu */
335 if (cpu
.asregs
.cc
& (CC_GTU
| CC_EQ
))
336 pc
+= INST2OFFSET(inst
);
339 case 0x09: /* bleu */
342 if (cpu
.asregs
.cc
& (CC_LTU
| CC_EQ
))
343 pc
+= INST2OFFSET(inst
);
349 cpu
.asregs
.exception
= SIGILL
;
356 /* This is a Form 2 instruction. */
357 int opcode
= (inst
>> 12 & 0x3);
362 int a
= (inst
>> 8) & 0xf;
363 unsigned av
= cpu
.asregs
.regs
[a
];
364 unsigned v
= (inst
& 0xff);
367 cpu
.asregs
.regs
[a
] = av
+ v
;
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 v
= (inst
& 0xff);
386 cpu
.asregs
.regs
[a
] = cpu
.asregs
.sregs
[v
];
391 int a
= (inst
>> 8) & 0xf;
392 unsigned v
= (inst
& 0xff);
395 cpu
.asregs
.sregs
[v
] = cpu
.asregs
.regs
[a
];
400 cpu
.asregs
.exception
= SIGILL
;
407 /* This is a Form 1 instruction. */
408 int opcode
= inst
>> 8;
414 cpu
.asregs
.exception
= SIGILL
;
416 case 0x01: /* ldi.l (immediate) */
418 int reg
= (inst
>> 4) & 0xf;
421 unsigned int val
= EXTRACT_WORD(pc
+2);
422 cpu
.asregs
.regs
[reg
] = val
;
426 case 0x02: /* mov (register-to-register) */
428 int dest
= (inst
>> 4) & 0xf;
429 int src
= (inst
) & 0xf;
432 cpu
.asregs
.regs
[dest
] = cpu
.asregs
.regs
[src
];
435 case 0x03: /* jsra */
437 unsigned int fn
= EXTRACT_WORD(pc
+2);
438 unsigned int sp
= cpu
.asregs
.regs
[1];
441 /* Save a slot for the static chain. */
444 /* Push the return address. */
446 wlat (scpu
, opc
, sp
, pc
+ 6);
448 /* Push the current frame pointer. */
450 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
452 /* Uncache the stack pointer and set the pc and $fp. */
453 cpu
.asregs
.regs
[1] = sp
;
454 cpu
.asregs
.regs
[0] = sp
;
460 unsigned int sp
= cpu
.asregs
.regs
[0];
464 /* Pop the frame pointer. */
465 cpu
.asregs
.regs
[0] = rlat (scpu
, opc
, sp
);
468 /* Pop the return address. */
469 pc
= rlat (scpu
, opc
, sp
) - 2;
472 /* Skip over the static chain slot. */
475 /* Uncache the stack pointer. */
476 cpu
.asregs
.regs
[1] = sp
;
479 case 0x05: /* add.l */
481 int a
= (inst
>> 4) & 0xf;
483 unsigned av
= cpu
.asregs
.regs
[a
];
484 unsigned bv
= cpu
.asregs
.regs
[b
];
487 cpu
.asregs
.regs
[a
] = av
+ bv
;
490 case 0x06: /* push */
492 int a
= (inst
>> 4) & 0xf;
494 int sp
= cpu
.asregs
.regs
[a
] - 4;
497 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[b
]);
498 cpu
.asregs
.regs
[a
] = sp
;
503 int a
= (inst
>> 4) & 0xf;
505 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);
518 cpu
.asregs
.regs
[reg
] = rlat (scpu
, opc
, addr
);
522 case 0x09: /* sta.l */
524 int reg
= (inst
>> 4) & 0xf;
525 unsigned int addr
= EXTRACT_WORD(pc
+2);
528 wlat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
532 case 0x0a: /* ld.l (register indirect) */
534 int src
= inst
& 0xf;
535 int dest
= (inst
>> 4) & 0xf;
539 xv
= cpu
.asregs
.regs
[src
];
540 cpu
.asregs
.regs
[dest
] = rlat (scpu
, opc
, xv
);
543 case 0x0b: /* st.l */
545 int dest
= (inst
>> 4) & 0xf;
546 int val
= inst
& 0xf;
549 wlat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
552 case 0x0c: /* ldo.l */
554 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
555 int a
= (inst
>> 4) & 0xf;
559 addr
+= cpu
.asregs
.regs
[b
];
560 cpu
.asregs
.regs
[a
] = rlat (scpu
, opc
, addr
);
564 case 0x0d: /* sto.l */
566 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
567 int a
= (inst
>> 4) & 0xf;
571 addr
+= cpu
.asregs
.regs
[a
];
572 wlat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
578 int a
= (inst
>> 4) & 0xf;
581 int va
= cpu
.asregs
.regs
[a
];
582 int vb
= cpu
.asregs
.regs
[b
];
589 cc
|= (va
< vb
? CC_LT
: 0);
590 cc
|= (va
> vb
? CC_GT
: 0);
591 cc
|= ((unsigned int) va
< (unsigned int) vb
? CC_LTU
: 0);
592 cc
|= ((unsigned int) va
> (unsigned int) vb
? CC_GTU
: 0);
600 case 0x10: /* sex.b */
602 int a
= (inst
>> 4) & 0xf;
604 signed char bv
= cpu
.asregs
.regs
[b
];
607 cpu
.asregs
.regs
[a
] = (int) bv
;
610 case 0x11: /* sex.s */
612 int a
= (inst
>> 4) & 0xf;
614 signed short bv
= cpu
.asregs
.regs
[b
];
617 cpu
.asregs
.regs
[a
] = (int) bv
;
620 case 0x12: /* zex.b */
622 int a
= (inst
>> 4) & 0xf;
624 signed char bv
= cpu
.asregs
.regs
[b
];
627 cpu
.asregs
.regs
[a
] = (int) bv
& 0xff;
630 case 0x13: /* zex.s */
632 int a
= (inst
>> 4) & 0xf;
634 signed short bv
= cpu
.asregs
.regs
[b
];
637 cpu
.asregs
.regs
[a
] = (int) bv
& 0xffff;
640 case 0x14: /* umul.x */
642 int a
= (inst
>> 4) & 0xf;
644 unsigned av
= cpu
.asregs
.regs
[a
];
645 unsigned bv
= cpu
.asregs
.regs
[b
];
646 unsigned long long r
=
647 (unsigned long long) av
* (unsigned long long) bv
;
650 cpu
.asregs
.regs
[a
] = r
>> 32;
653 case 0x15: /* mul.x */
655 int a
= (inst
>> 4) & 0xf;
657 unsigned av
= cpu
.asregs
.regs
[a
];
658 unsigned bv
= cpu
.asregs
.regs
[b
];
660 (signed long long) av
* (signed long long) bv
;
663 cpu
.asregs
.regs
[a
] = r
>> 32;
672 cpu
.asregs
.exception
= SIGILL
;
677 unsigned int fn
= cpu
.asregs
.regs
[(inst
>> 4) & 0xf];
678 unsigned int sp
= cpu
.asregs
.regs
[1];
682 /* Save a slot for the static chain. */
685 /* Push the return address. */
687 wlat (scpu
, opc
, sp
, pc
+ 2);
689 /* Push the current frame pointer. */
691 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
693 /* Uncache the stack pointer and set the fp & pc. */
694 cpu
.asregs
.regs
[1] = sp
;
695 cpu
.asregs
.regs
[0] = sp
;
699 case 0x1a: /* jmpa */
701 unsigned int tgt
= EXTRACT_WORD(pc
+2);
707 case 0x1b: /* ldi.b (immediate) */
709 int reg
= (inst
>> 4) & 0xf;
710 unsigned int val
= EXTRACT_WORD(pc
+2);
713 cpu
.asregs
.regs
[reg
] = val
;
717 case 0x1c: /* ld.b (register indirect) */
719 int src
= inst
& 0xf;
720 int dest
= (inst
>> 4) & 0xf;
724 xv
= cpu
.asregs
.regs
[src
];
725 cpu
.asregs
.regs
[dest
] = rbat (scpu
, opc
, xv
);
728 case 0x1d: /* lda.b */
730 int reg
= (inst
>> 4) & 0xf;
731 unsigned int addr
= EXTRACT_WORD(pc
+2);
734 cpu
.asregs
.regs
[reg
] = rbat (scpu
, opc
, addr
);
738 case 0x1e: /* st.b */
740 int dest
= (inst
>> 4) & 0xf;
741 int val
= inst
& 0xf;
744 wbat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
747 case 0x1f: /* sta.b */
749 int reg
= (inst
>> 4) & 0xf;
750 unsigned int addr
= EXTRACT_WORD(pc
+2);
753 wbat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
757 case 0x20: /* ldi.s (immediate) */
759 int reg
= (inst
>> 4) & 0xf;
761 unsigned int val
= EXTRACT_WORD(pc
+2);
764 cpu
.asregs
.regs
[reg
] = val
;
768 case 0x21: /* ld.s (register indirect) */
770 int src
= inst
& 0xf;
771 int dest
= (inst
>> 4) & 0xf;
775 xv
= cpu
.asregs
.regs
[src
];
776 cpu
.asregs
.regs
[dest
] = rsat (scpu
, opc
, xv
);
779 case 0x22: /* lda.s */
781 int reg
= (inst
>> 4) & 0xf;
782 unsigned int addr
= EXTRACT_WORD(pc
+2);
785 cpu
.asregs
.regs
[reg
] = rsat (scpu
, opc
, addr
);
789 case 0x23: /* st.s */
791 int dest
= (inst
>> 4) & 0xf;
792 int val
= inst
& 0xf;
795 wsat (scpu
, opc
, cpu
.asregs
.regs
[dest
], cpu
.asregs
.regs
[val
]);
798 case 0x24: /* sta.s */
800 int reg
= (inst
>> 4) & 0xf;
801 unsigned int addr
= EXTRACT_WORD(pc
+2);
804 wsat (scpu
, opc
, addr
, cpu
.asregs
.regs
[reg
]);
810 int reg
= (inst
>> 4) & 0xf;
813 pc
= cpu
.asregs
.regs
[reg
] - 2;
818 int a
= (inst
>> 4) & 0xf;
823 av
= cpu
.asregs
.regs
[a
];
824 bv
= cpu
.asregs
.regs
[b
];
825 cpu
.asregs
.regs
[a
] = av
& bv
;
828 case 0x27: /* lshr */
830 int a
= (inst
>> 4) & 0xf;
832 int av
= cpu
.asregs
.regs
[a
];
833 int bv
= cpu
.asregs
.regs
[b
];
836 cpu
.asregs
.regs
[a
] = (unsigned) ((unsigned) av
>> bv
);
839 case 0x28: /* ashl */
841 int a
= (inst
>> 4) & 0xf;
843 int av
= cpu
.asregs
.regs
[a
];
844 int bv
= cpu
.asregs
.regs
[b
];
847 cpu
.asregs
.regs
[a
] = av
<< bv
;
850 case 0x29: /* sub.l */
852 int a
= (inst
>> 4) & 0xf;
854 unsigned av
= cpu
.asregs
.regs
[a
];
855 unsigned bv
= cpu
.asregs
.regs
[b
];
858 cpu
.asregs
.regs
[a
] = av
- bv
;
863 int a
= (inst
>> 4) & 0xf;
865 int bv
= cpu
.asregs
.regs
[b
];
868 cpu
.asregs
.regs
[a
] = - bv
;
873 int a
= (inst
>> 4) & 0xf;
878 av
= cpu
.asregs
.regs
[a
];
879 bv
= cpu
.asregs
.regs
[b
];
880 cpu
.asregs
.regs
[a
] = av
| bv
;
885 int a
= (inst
>> 4) & 0xf;
887 int bv
= cpu
.asregs
.regs
[b
];
890 cpu
.asregs
.regs
[a
] = 0xffffffff ^ bv
;
893 case 0x2d: /* ashr */
895 int a
= (inst
>> 4) & 0xf;
897 int av
= cpu
.asregs
.regs
[a
];
898 int bv
= cpu
.asregs
.regs
[b
];
901 cpu
.asregs
.regs
[a
] = av
>> bv
;
906 int a
= (inst
>> 4) & 0xf;
911 av
= cpu
.asregs
.regs
[a
];
912 bv
= cpu
.asregs
.regs
[b
];
913 cpu
.asregs
.regs
[a
] = av
^ bv
;
916 case 0x2f: /* mul.l */
918 int a
= (inst
>> 4) & 0xf;
920 unsigned av
= cpu
.asregs
.regs
[a
];
921 unsigned bv
= cpu
.asregs
.regs
[b
];
924 cpu
.asregs
.regs
[a
] = av
* bv
;
929 unsigned int inum
= EXTRACT_WORD(pc
+2);
932 /* Set the special registers appropriately. */
933 cpu
.asregs
.sregs
[2] = 3; /* MOXIE_EX_SWI */
934 cpu
.asregs
.sregs
[3] = inum
;
937 case 0x1: /* SYS_exit */
939 cpu
.asregs
.exception
= SIGQUIT
;
942 case 0x2: /* SYS_open */
945 int mode
= (int) convert_target_flags ((unsigned) cpu
.asregs
.regs
[3]);
946 int perm
= (int) cpu
.asregs
.regs
[4];
947 int fd
= open (fname
, mode
, perm
);
948 sim_core_read_buffer (sd
, scpu
, read_map
, fname
,
949 cpu
.asregs
.regs
[2], 1024);
950 /* FIXME - set errno */
951 cpu
.asregs
.regs
[2] = fd
;
954 case 0x4: /* SYS_read */
956 int fd
= cpu
.asregs
.regs
[2];
957 unsigned len
= (unsigned) cpu
.asregs
.regs
[4];
958 char *buf
= malloc (len
);
959 cpu
.asregs
.regs
[2] = read (fd
, buf
, len
);
960 sim_core_write_buffer (sd
, scpu
, write_map
, buf
,
961 cpu
.asregs
.regs
[3], len
);
965 case 0x5: /* SYS_write */
968 /* String length is at 0x12($fp) */
969 unsigned count
, len
= (unsigned) cpu
.asregs
.regs
[4];
971 sim_core_read_buffer (sd
, scpu
, read_map
, str
,
972 cpu
.asregs
.regs
[3], len
);
973 count
= write (cpu
.asregs
.regs
[2], str
, len
);
975 cpu
.asregs
.regs
[2] = count
;
978 case 0xffffffff: /* Linux System Call */
980 unsigned int handler
= cpu
.asregs
.sregs
[1];
981 unsigned int sp
= cpu
.asregs
.regs
[1];
983 /* Save a slot for the static chain. */
986 /* Push the return address. */
988 wlat (scpu
, opc
, sp
, pc
+ 6);
990 /* Push the current frame pointer. */
992 wlat (scpu
, opc
, sp
, cpu
.asregs
.regs
[0]);
994 /* Uncache the stack pointer and set the fp & pc. */
995 cpu
.asregs
.regs
[1] = sp
;
996 cpu
.asregs
.regs
[0] = sp
;
1005 case 0x31: /* div.l */
1007 int a
= (inst
>> 4) & 0xf;
1009 int av
= cpu
.asregs
.regs
[a
];
1010 int bv
= cpu
.asregs
.regs
[b
];
1013 cpu
.asregs
.regs
[a
] = av
/ bv
;
1016 case 0x32: /* udiv.l */
1018 int a
= (inst
>> 4) & 0xf;
1020 unsigned int av
= cpu
.asregs
.regs
[a
];
1021 unsigned int bv
= cpu
.asregs
.regs
[b
];
1024 cpu
.asregs
.regs
[a
] = (av
/ bv
);
1027 case 0x33: /* mod.l */
1029 int a
= (inst
>> 4) & 0xf;
1031 int av
= cpu
.asregs
.regs
[a
];
1032 int bv
= cpu
.asregs
.regs
[b
];
1035 cpu
.asregs
.regs
[a
] = av
% bv
;
1038 case 0x34: /* umod.l */
1040 int a
= (inst
>> 4) & 0xf;
1042 unsigned int av
= cpu
.asregs
.regs
[a
];
1043 unsigned int bv
= cpu
.asregs
.regs
[b
];
1046 cpu
.asregs
.regs
[a
] = (av
% bv
);
1049 case 0x35: /* brk */
1051 cpu
.asregs
.exception
= SIGTRAP
;
1052 pc
-= 2; /* Adjust pc */
1054 case 0x36: /* ldo.b */
1056 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
1057 int a
= (inst
>> 4) & 0xf;
1061 addr
+= cpu
.asregs
.regs
[b
];
1062 cpu
.asregs
.regs
[a
] = rbat (scpu
, opc
, addr
);
1066 case 0x37: /* sto.b */
1068 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
1069 int a
= (inst
>> 4) & 0xf;
1073 addr
+= cpu
.asregs
.regs
[a
];
1074 wbat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
1078 case 0x38: /* ldo.s */
1080 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
1081 int a
= (inst
>> 4) & 0xf;
1085 addr
+= cpu
.asregs
.regs
[b
];
1086 cpu
.asregs
.regs
[a
] = rsat (scpu
, opc
, addr
);
1090 case 0x39: /* sto.s */
1092 unsigned int addr
= EXTRACT_OFFSET(pc
+2);
1093 int a
= (inst
>> 4) & 0xf;
1097 addr
+= cpu
.asregs
.regs
[a
];
1098 wsat (scpu
, opc
, addr
, cpu
.asregs
.regs
[b
]);
1105 cpu
.asregs
.exception
= SIGILL
;
1113 } while (!cpu
.asregs
.exception
);
1115 /* Hide away the things we've cached while executing. */
1116 cpu
.asregs
.regs
[PC_REGNO
] = pc
;
1117 cpu
.asregs
.insts
+= insts
; /* instructions done ... */
1121 sim_store_register (sd
, rn
, memory
, length
)
1124 unsigned char * memory
;
1127 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1133 /* misalignment safe */
1134 ival
= moxie_extract_unsigned_integer (memory
, 4);
1135 cpu
.asints
[rn
] = ival
;
1145 sim_fetch_register (sd
, rn
, memory
, length
)
1148 unsigned char * memory
;
1151 if (rn
< NUM_MOXIE_REGS
&& rn
>= 0)
1155 long ival
= cpu
.asints
[rn
];
1157 /* misalignment-safe */
1158 moxie_store_unsigned_integer (memory
, 4, ival
);
1168 free_state (SIM_DESC sd
)
1170 if (STATE_MODULES (sd
) != NULL
)
1171 sim_module_uninstall (sd
);
1172 sim_cpu_free_all (sd
);
1173 sim_state_free (sd
);
1177 sim_open (kind
, cb
, abfd
, argv
)
1183 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
1184 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
1186 /* The cpu data is kept in a separately allocated chunk of memory. */
1187 if (sim_cpu_alloc_all (sd
, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK
)
1193 STATE_WATCHPOINTS (sd
)->pc
= &cpu
.asregs
.regs
[PC_REGNO
];
1194 STATE_WATCHPOINTS (sd
)->sizeof_pc
= sizeof (word
);
1196 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
1202 /* getopt will print the error message so we just have to exit if this fails.
1203 FIXME: Hmmm... in the case of gdb we need getopt to call
1205 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
1211 sim_do_command(sd
," memory region 0x00000000,0x4000000") ;
1212 sim_do_command(sd
," memory region 0xE0000000,0x10000") ;
1214 /* Check for/establish the a reference program image. */
1215 if (sim_analyze_program (sd
,
1216 (STATE_PROG_ARGV (sd
) != NULL
1217 ? *STATE_PROG_ARGV (sd
)
1218 : NULL
), abfd
) != SIM_RC_OK
)
1224 /* Configure/verify the target byte order and other runtime
1225 configuration options. */
1226 if (sim_config (sd
) != SIM_RC_OK
)
1228 sim_module_uninstall (sd
);
1232 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
1234 /* Uninstall the modules to avoid memory leaks,
1235 file descriptor leaks, etc. */
1236 sim_module_uninstall (sd
);
1240 /* CPU specific initialization. */
1241 set_initial_gprs ();
1247 sim_close (sd
, quitting
)
1255 /* Load the device tree blob. */
1258 load_dtb (SIM_DESC sd
, const char *filename
)
1261 FILE *f
= fopen (filename
, "rb");
1263 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1266 printf ("WARNING: ``%s'' could not be opened.\n", filename
);
1269 fseek (f
, 0, SEEK_END
);
1271 fseek (f
, 0, SEEK_SET
);
1272 buf
= alloca (size
);
1273 if (size
!= fread (buf
, 1, size
, f
))
1275 printf ("ERROR: error reading ``%s''.\n", filename
);
1278 sim_core_write_buffer (sd
, scpu
, write_map
, buf
, 0xE0000000, size
);
1279 cpu
.asregs
.sregs
[9] = 0xE0000000;
1284 sim_create_inferior (sd
, prog_bfd
, argv
, env
)
1286 struct bfd
* prog_bfd
;
1292 sim_cpu
*scpu
= STATE_CPU (sd
, 0); /* FIXME */
1294 if (prog_bfd
!= NULL
)
1295 cpu
.asregs
.regs
[PC_REGNO
] = bfd_get_start_address (prog_bfd
);
1297 /* Copy args into target memory. */
1299 for (argc
= 0; avp
&& *avp
; avp
++)
1302 /* Target memory looks like this:
1303 0x00000000 zero word
1304 0x00000004 argc word
1305 0x00000008 start of argv
1307 0x0000???? end of argv
1308 0x0000???? zero word
1309 0x0000???? start of data pointed to by argv */
1311 wlat (scpu
, 0, 0, 0);
1312 wlat (scpu
, 0, 4, argc
);
1314 /* tp is the offset of our first argv data. */
1315 tp
= 4 + 4 + argc
* 4 + 4;
1317 for (i
= 0; i
< argc
; i
++)
1319 /* Set the argv value. */
1320 wlat (scpu
, 0, 4 + 4 + i
* 4, tp
);
1322 /* Store the string. */
1323 sim_core_write_buffer (sd
, scpu
, write_map
, argv
[i
],
1324 tp
, strlen(argv
[i
])+1);
1325 tp
+= strlen (argv
[i
]) + 1;
1328 wlat (scpu
, 0, 4 + 4 + i
* 4, 0);
This page took 0.057387 seconds and 5 git commands to generate.