8b8879f13b3e5555f6eba961200a7f83f77f29d7
[deliverable/binutils-gdb.git] / sim / moxie / interp.c
1 /* Simulator for the moxie processor
2 Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
3 Contributed by Anthony Green
4
5 This file is part of GDB, the GNU debugger.
6
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.
11
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.
16
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/>. */
19
20 #include <signal.h>
21 #include <stdlib.h>
22 #include "sysdep.h"
23 #include <sys/times.h>
24 #include <sys/param.h>
25 #include <netinet/in.h> /* for byte ordering macros */
26 #include "bfd.h"
27 #include "gdb/callback.h"
28 #include "libiberty.h"
29 #include "gdb/remote-sim.h"
30
31 #include "sim-main.h"
32 #include "sim-base.h"
33
34 typedef int word;
35 typedef unsigned int uword;
36
37 host_callback * callback;
38
39 FILE *tracefile;
40
41 /* Extract the signed 10-bit offset from a 16-bit branch
42 instruction. */
43 #define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
44
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)))
50
51 unsigned long
52 moxie_extract_unsigned_integer (addr, len)
53 unsigned char * addr;
54 int len;
55 {
56 unsigned long retval;
57 unsigned char * p;
58 unsigned char * startaddr = (unsigned char *)addr;
59 unsigned char * endaddr = startaddr + len;
60
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));
64
65 /* Start at the most significant end of the integer, and work towards
66 the least significant. */
67 retval = 0;
68
69 for (p = endaddr; p > startaddr;)
70 retval = (retval << 8) | * -- p;
71
72 return retval;
73 }
74
75 void
76 moxie_store_unsigned_integer (addr, len, val)
77 unsigned char * addr;
78 int len;
79 unsigned long val;
80 {
81 unsigned char * p;
82 unsigned char * startaddr = (unsigned char *)addr;
83 unsigned char * endaddr = startaddr + len;
84
85 for (p = endaddr; p > startaddr;)
86 {
87 * -- p = val & 0xff;
88 val >>= 8;
89 }
90 }
91
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" };
96
97 /* The machine state.
98
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. */
105
106 #define NUM_MOXIE_REGS 17 /* Including PC */
107 #define NUM_MOXIE_SREGS 256 /* The special registers */
108 #define PC_REGNO 16
109
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. */
112 struct moxie_regset
113 {
114 word regs[NUM_MOXIE_REGS + 1]; /* primary registers */
115 word sregs[256]; /* special registers */
116 word cc; /* the condition code reg */
117 int exception;
118 unsigned long long insts; /* instruction counter */
119 };
120
121 #define CC_GT 1<<0
122 #define CC_LT 1<<1
123 #define CC_EQ 1<<2
124 #define CC_GTU 1<<3
125 #define CC_LTU 1<<4
126
127 union
128 {
129 struct moxie_regset asregs;
130 word asints [1]; /* but accessed larger... */
131 } cpu;
132
133 static char *myname;
134 static SIM_OPEN_KIND sim_kind;
135 static int issue_messages = 0;
136
137 void
138 sim_size (int s)
139 {
140 }
141
142 static void
143 set_initial_gprs ()
144 {
145 int i;
146 long space;
147
148 /* Set up machine just out of reset. */
149 cpu.asregs.regs[PC_REGNO] = 0;
150
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;
156 }
157
158 static void
159 interrupt ()
160 {
161 cpu.asregs.exception = SIGINT;
162 }
163
164 /* Write a 1 byte value to memory. */
165
166 static void INLINE
167 wbat (sim_cpu *scpu, word pc, word x, word v)
168 {
169 address_word cia = CIA_GET (scpu);
170
171 sim_core_write_aligned_1 (scpu, cia, write_map, x, v);
172 }
173
174 /* Write a 2 byte value to memory. */
175
176 static void INLINE
177 wsat (sim_cpu *scpu, word pc, word x, word v)
178 {
179 address_word cia = CIA_GET (scpu);
180
181 sim_core_write_aligned_2 (scpu, cia, write_map, x, v);
182 }
183
184 /* Write a 4 byte value to memory. */
185
186 static void INLINE
187 wlat (sim_cpu *scpu, word pc, word x, word v)
188 {
189 address_word cia = CIA_GET (scpu);
190
191 sim_core_write_aligned_4 (scpu, cia, write_map, x, v);
192 }
193
194 /* Read 2 bytes from memory. */
195
196 static int INLINE
197 rsat (sim_cpu *scpu, word pc, word x)
198 {
199 address_word cia = CIA_GET (scpu);
200
201 return (sim_core_read_aligned_2 (scpu, cia, read_map, x));
202 }
203
204 /* Read 1 byte from memory. */
205
206 static int INLINE
207 rbat (sim_cpu *scpu, word pc, word x)
208 {
209 address_word cia = CIA_GET (scpu);
210
211 return (sim_core_read_aligned_1 (scpu, cia, read_map, x));
212 }
213
214 /* Read 4 bytes from memory. */
215
216 static int INLINE
217 rlat (sim_cpu *scpu, word pc, word x)
218 {
219 address_word cia = CIA_GET (scpu);
220
221 return (sim_core_read_aligned_4 (scpu, cia, read_map, x));
222 }
223
224 #define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; }
225
226 unsigned int
227 convert_target_flags (unsigned int tflags)
228 {
229 unsigned int hflags = 0x0;
230
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);
238
239 if (tflags != 0x0)
240 fprintf (stderr,
241 "Simulator Error: problem converting target open flags for host. 0x%x\n",
242 tflags);
243
244 return hflags;
245 }
246
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]);
248
249 static int tracing = 0;
250
251 void
252 sim_resume (sd, step, siggnal)
253 SIM_DESC sd;
254 int step, siggnal;
255 {
256 word pc, opc;
257 unsigned long long insts;
258 unsigned short inst;
259 void (* sigsave)();
260 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
261 address_word cia = CIA_GET (scpu);
262
263 sigsave = signal (SIGINT, interrupt);
264 cpu.asregs.exception = step ? SIGTRAP: 0;
265 pc = cpu.asregs.regs[PC_REGNO];
266 insts = cpu.asregs.insts;
267
268 /* Run instructions here. */
269 do
270 {
271 opc = pc;
272
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);
276
277 /* Decode instruction. */
278 if (inst & (1 << 15))
279 {
280 if (inst & (1 << 14))
281 {
282 /* This is a Form 3 instruction. */
283 int opcode = (inst >> 10 & 0xf);
284
285 switch (opcode)
286 {
287 case 0x00: /* beq */
288 {
289 TRACE("beq");
290 if (cpu.asregs.cc & CC_EQ)
291 pc += INST2OFFSET(inst) - 2;
292 }
293 break;
294 case 0x01: /* bne */
295 {
296 TRACE("bne");
297 if (! (cpu.asregs.cc & CC_EQ))
298 pc += INST2OFFSET(inst) - 2;
299 }
300 break;
301 case 0x02: /* blt */
302 {
303 TRACE("blt");
304 if (cpu.asregs.cc & CC_LT)
305 pc += INST2OFFSET(inst) - 2;
306 } break;
307 case 0x03: /* bgt */
308 {
309 TRACE("bgt");
310 if (cpu.asregs.cc & CC_GT)
311 pc += INST2OFFSET(inst) - 2;
312 }
313 break;
314 case 0x04: /* bltu */
315 {
316 TRACE("bltu");
317 if (cpu.asregs.cc & CC_LTU)
318 pc += INST2OFFSET(inst) - 2;
319 }
320 break;
321 case 0x05: /* bgtu */
322 {
323 TRACE("bgtu");
324 if (cpu.asregs.cc & CC_GTU)
325 pc += INST2OFFSET(inst) - 2;
326 }
327 break;
328 case 0x06: /* bge */
329 {
330 TRACE("bge");
331 if (cpu.asregs.cc & (CC_GT | CC_EQ))
332 pc += INST2OFFSET(inst) - 2;
333 }
334 break;
335 case 0x07: /* ble */
336 {
337 TRACE("ble");
338 if (cpu.asregs.cc & (CC_LT | CC_EQ))
339 pc += INST2OFFSET(inst) - 2;
340 }
341 break;
342 case 0x08: /* bgeu */
343 {
344 TRACE("bgeu");
345 if (cpu.asregs.cc & (CC_GTU | CC_EQ))
346 pc += INST2OFFSET(inst) - 2;
347 }
348 break;
349 case 0x09: /* bleu */
350 {
351 TRACE("bleu");
352 if (cpu.asregs.cc & (CC_LTU | CC_EQ))
353 pc += INST2OFFSET(inst) - 2;
354 }
355 break;
356 default:
357 {
358 TRACE("SIGILL3");
359 cpu.asregs.exception = SIGILL;
360 break;
361 }
362 }
363 }
364 else
365 {
366 /* This is a Form 2 instruction. */
367 int opcode = (inst >> 12 & 0x3);
368 switch (opcode)
369 {
370 case 0x00: /* inc */
371 {
372 int a = (inst >> 8) & 0xf;
373 unsigned av = cpu.asregs.regs[a];
374 unsigned v = (inst & 0xff);
375 TRACE("inc");
376 cpu.asregs.regs[a] = av + v;
377 }
378 break;
379 case 0x01: /* dec */
380 {
381 int a = (inst >> 8) & 0xf;
382 unsigned av = cpu.asregs.regs[a];
383 unsigned v = (inst & 0xff);
384 TRACE("dec");
385 cpu.asregs.regs[a] = av - v;
386 }
387 break;
388 case 0x02: /* gsr */
389 {
390 int a = (inst >> 8) & 0xf;
391 unsigned v = (inst & 0xff);
392 TRACE("gsr");
393 cpu.asregs.regs[a] = cpu.asregs.sregs[v];
394 }
395 break;
396 case 0x03: /* ssr */
397 {
398 int a = (inst >> 8) & 0xf;
399 unsigned v = (inst & 0xff);
400 TRACE("ssr");
401 cpu.asregs.sregs[v] = cpu.asregs.regs[a];
402 }
403 break;
404 default:
405 TRACE("SIGILL2");
406 cpu.asregs.exception = SIGILL;
407 break;
408 }
409 }
410 }
411 else
412 {
413 /* This is a Form 1 instruction. */
414 int opcode = inst >> 8;
415 switch (opcode)
416 {
417 case 0x00: /* nop */
418 break;
419 case 0x01: /* ldi.l (immediate) */
420 {
421 int reg = (inst >> 4) & 0xf;
422 TRACE("ldi.l");
423 unsigned int val = EXTRACT_WORD(pc+2);
424 cpu.asregs.regs[reg] = val;
425 pc += 4;
426 }
427 break;
428 case 0x02: /* mov (register-to-register) */
429 {
430 int dest = (inst >> 4) & 0xf;
431 int src = (inst ) & 0xf;
432 TRACE("mov");
433 cpu.asregs.regs[dest] = cpu.asregs.regs[src];
434 }
435 break;
436 case 0x03: /* jsra */
437 {
438 unsigned int fn = EXTRACT_WORD(pc+2);
439 unsigned int sp = cpu.asregs.regs[1];
440 TRACE("jsra");
441 /* Save a slot for the static chain. */
442 sp -= 4;
443
444 /* Push the return address. */
445 sp -= 4;
446 wlat (scpu, opc, sp, pc + 6);
447
448 /* Push the current frame pointer. */
449 sp -= 4;
450 wlat (scpu, opc, sp, cpu.asregs.regs[0]);
451
452 /* Uncache the stack pointer and set the pc and $fp. */
453 cpu.asregs.regs[1] = sp;
454 cpu.asregs.regs[0] = sp;
455 pc = fn - 2;
456 }
457 break;
458 case 0x04: /* ret */
459 {
460 unsigned int sp = cpu.asregs.regs[0];
461
462 TRACE("ret");
463
464 /* Pop the frame pointer. */
465 cpu.asregs.regs[0] = rlat (scpu, opc, sp);
466 sp += 4;
467
468 /* Pop the return address. */
469 pc = rlat (scpu, opc, sp) - 2;
470 sp += 4;
471
472 /* Skip over the static chain slot. */
473 sp += 4;
474
475 /* Uncache the stack pointer. */
476 cpu.asregs.regs[1] = sp;
477 }
478 break;
479 case 0x05: /* add.l */
480 {
481 int a = (inst >> 4) & 0xf;
482 int b = inst & 0xf;
483 unsigned av = cpu.asregs.regs[a];
484 unsigned bv = cpu.asregs.regs[b];
485 TRACE("add.l");
486 cpu.asregs.regs[a] = av + bv;
487 }
488 break;
489 case 0x06: /* push */
490 {
491 int a = (inst >> 4) & 0xf;
492 int b = inst & 0xf;
493 int sp = cpu.asregs.regs[a] - 4;
494 TRACE("push");
495 wlat (scpu, opc, sp, cpu.asregs.regs[b]);
496 cpu.asregs.regs[a] = sp;
497 }
498 break;
499 case 0x07: /* pop */
500 {
501 int a = (inst >> 4) & 0xf;
502 int b = inst & 0xf;
503 int sp = cpu.asregs.regs[a];
504 TRACE("pop");
505 cpu.asregs.regs[b] = rlat (scpu, opc, sp);
506 cpu.asregs.regs[a] = sp + 4;
507 }
508 break;
509 case 0x08: /* lda.l */
510 {
511 int reg = (inst >> 4) & 0xf;
512 unsigned int addr = EXTRACT_WORD(pc+2);
513 TRACE("lda.l");
514 cpu.asregs.regs[reg] = rlat (scpu, opc, addr);
515 pc += 4;
516 }
517 break;
518 case 0x09: /* sta.l */
519 {
520 int reg = (inst >> 4) & 0xf;
521 unsigned int addr = EXTRACT_WORD(pc+2);
522 TRACE("sta.l");
523 wlat (scpu, opc, addr, cpu.asregs.regs[reg]);
524 pc += 4;
525 }
526 break;
527 case 0x0a: /* ld.l (register indirect) */
528 {
529 int src = inst & 0xf;
530 int dest = (inst >> 4) & 0xf;
531 int xv;
532 TRACE("ld.l");
533 xv = cpu.asregs.regs[src];
534 cpu.asregs.regs[dest] = rlat (scpu, opc, xv);
535 }
536 break;
537 case 0x0b: /* st.l */
538 {
539 int dest = (inst >> 4) & 0xf;
540 int val = inst & 0xf;
541 TRACE("st.l");
542 wlat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
543 }
544 break;
545 case 0x0c: /* ldo.l */
546 {
547 unsigned int addr = EXTRACT_WORD(pc+2);
548 int a = (inst >> 4) & 0xf;
549 int b = inst & 0xf;
550 TRACE("ldo.l");
551 addr += cpu.asregs.regs[b];
552 cpu.asregs.regs[a] = rlat (scpu, opc, addr);
553 pc += 4;
554 }
555 break;
556 case 0x0d: /* sto.l */
557 {
558 unsigned int addr = EXTRACT_WORD(pc+2);
559 int a = (inst >> 4) & 0xf;
560 int b = inst & 0xf;
561 TRACE("sto.l");
562 addr += cpu.asregs.regs[a];
563 wlat (scpu, opc, addr, cpu.asregs.regs[b]);
564 pc += 4;
565 }
566 break;
567 case 0x0e: /* cmp */
568 {
569 int a = (inst >> 4) & 0xf;
570 int b = inst & 0xf;
571 int cc = 0;
572 int va = cpu.asregs.regs[a];
573 int vb = cpu.asregs.regs[b];
574
575 TRACE("cmp");
576
577 if (va == vb)
578 cc = CC_EQ;
579 else
580 {
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);
585 }
586
587 cpu.asregs.cc = cc;
588 }
589 break;
590 case 0x0f:
591 case 0x10:
592 case 0x11:
593 case 0x12:
594 case 0x13:
595 case 0x14:
596 case 0x15:
597 case 0x16:
598 case 0x17:
599 case 0x18:
600 {
601 opc = opcode;
602 TRACE("SIGILL0");
603 cpu.asregs.exception = SIGILL;
604 break;
605 }
606 case 0x19: /* jsr */
607 {
608 unsigned int fn = cpu.asregs.regs[(inst >> 4) & 0xf];
609 unsigned int sp = cpu.asregs.regs[1];
610
611 TRACE("jsr");
612
613 /* Save a slot for the static chain. */
614 sp -= 4;
615
616 /* Push the return address. */
617 sp -= 4;
618 wlat (scpu, opc, sp, pc + 2);
619
620 /* Push the current frame pointer. */
621 sp -= 4;
622 wlat (scpu, opc, sp, cpu.asregs.regs[0]);
623
624 /* Uncache the stack pointer and set the fp & pc. */
625 cpu.asregs.regs[1] = sp;
626 cpu.asregs.regs[0] = sp;
627 pc = fn - 2;
628 }
629 break;
630 case 0x1a: /* jmpa */
631 {
632 unsigned int tgt = EXTRACT_WORD(pc+2);
633 TRACE("jmpa");
634 pc = tgt - 2;
635 }
636 break;
637 case 0x1b: /* ldi.b (immediate) */
638 {
639 int reg = (inst >> 4) & 0xf;
640
641 unsigned int val = EXTRACT_WORD(pc+2);
642 TRACE("ldi.b");
643 cpu.asregs.regs[reg] = val;
644 pc += 4;
645 }
646 break;
647 case 0x1c: /* ld.b (register indirect) */
648 {
649 int src = inst & 0xf;
650 int dest = (inst >> 4) & 0xf;
651 int xv;
652 TRACE("ld.b");
653 xv = cpu.asregs.regs[src];
654 cpu.asregs.regs[dest] = rbat (scpu, opc, xv);
655 }
656 break;
657 case 0x1d: /* lda.b */
658 {
659 int reg = (inst >> 4) & 0xf;
660 unsigned int addr = EXTRACT_WORD(pc+2);
661 TRACE("lda.b");
662 cpu.asregs.regs[reg] = rbat (scpu, opc, addr);
663 pc += 4;
664 }
665 break;
666 case 0x1e: /* st.b */
667 {
668 int dest = (inst >> 4) & 0xf;
669 int val = inst & 0xf;
670 TRACE("st.b");
671 wbat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
672 }
673 break;
674 case 0x1f: /* sta.b */
675 {
676 int reg = (inst >> 4) & 0xf;
677 unsigned int addr = EXTRACT_WORD(pc+2);
678 TRACE("sta.b");
679 wbat (scpu, opc, addr, cpu.asregs.regs[reg]);
680 pc += 4;
681 }
682 break;
683 case 0x20: /* ldi.s (immediate) */
684 {
685 int reg = (inst >> 4) & 0xf;
686
687 unsigned int val = EXTRACT_WORD(pc+2);
688 TRACE("ldi.s");
689 cpu.asregs.regs[reg] = val;
690 pc += 4;
691 }
692 break;
693 case 0x21: /* ld.s (register indirect) */
694 {
695 int src = inst & 0xf;
696 int dest = (inst >> 4) & 0xf;
697 int xv;
698 TRACE("ld.s");
699 xv = cpu.asregs.regs[src];
700 cpu.asregs.regs[dest] = rsat (scpu, opc, xv);
701 }
702 break;
703 case 0x22: /* lda.s */
704 {
705 int reg = (inst >> 4) & 0xf;
706 unsigned int addr = EXTRACT_WORD(pc+2);
707 TRACE("lda.s");
708 cpu.asregs.regs[reg] = rsat (scpu, opc, addr);
709 pc += 4;
710 }
711 break;
712 case 0x23: /* st.s */
713 {
714 int dest = (inst >> 4) & 0xf;
715 int val = inst & 0xf;
716 TRACE("st.s");
717 wsat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
718 }
719 break;
720 case 0x24: /* sta.s */
721 {
722 int reg = (inst >> 4) & 0xf;
723 unsigned int addr = EXTRACT_WORD(pc+2);
724 TRACE("sta.s");
725 wsat (scpu, opc, addr, cpu.asregs.regs[reg]);
726 pc += 4;
727 }
728 break;
729 case 0x25: /* jmp */
730 {
731 int reg = (inst >> 4) & 0xf;
732 TRACE("jmp");
733 pc = cpu.asregs.regs[reg] - 2;
734 }
735 break;
736 case 0x26: /* and */
737 {
738 int a = (inst >> 4) & 0xf;
739 int b = inst & 0xf;
740 int av, bv;
741 TRACE("and");
742 av = cpu.asregs.regs[a];
743 bv = cpu.asregs.regs[b];
744 cpu.asregs.regs[a] = av & bv;
745 }
746 break;
747 case 0x27: /* lshr */
748 {
749 int a = (inst >> 4) & 0xf;
750 int b = inst & 0xf;
751 int av = cpu.asregs.regs[a];
752 int bv = cpu.asregs.regs[b];
753 TRACE("lshr");
754 cpu.asregs.regs[a] = (unsigned) ((unsigned) av >> bv);
755 }
756 break;
757 case 0x28: /* ashl */
758 {
759 int a = (inst >> 4) & 0xf;
760 int b = inst & 0xf;
761 int av = cpu.asregs.regs[a];
762 int bv = cpu.asregs.regs[b];
763 TRACE("ashl");
764 cpu.asregs.regs[a] = av << bv;
765 }
766 break;
767 case 0x29: /* sub.l */
768 {
769 int a = (inst >> 4) & 0xf;
770 int b = inst & 0xf;
771 unsigned av = cpu.asregs.regs[a];
772 unsigned bv = cpu.asregs.regs[b];
773 TRACE("sub.l");
774 cpu.asregs.regs[a] = av - bv;
775 }
776 break;
777 case 0x2a: /* neg */
778 {
779 int a = (inst >> 4) & 0xf;
780 int b = inst & 0xf;
781 int bv = cpu.asregs.regs[b];
782 TRACE("neg");
783 cpu.asregs.regs[a] = - bv;
784 }
785 break;
786 case 0x2b: /* or */
787 {
788 int a = (inst >> 4) & 0xf;
789 int b = inst & 0xf;
790 int av, bv;
791 TRACE("or");
792 av = cpu.asregs.regs[a];
793 bv = cpu.asregs.regs[b];
794 cpu.asregs.regs[a] = av | bv;
795 }
796 break;
797 case 0x2c: /* not */
798 {
799 int a = (inst >> 4) & 0xf;
800 int b = inst & 0xf;
801 int bv = cpu.asregs.regs[b];
802 TRACE("not");
803 cpu.asregs.regs[a] = 0xffffffff ^ bv;
804 }
805 break;
806 case 0x2d: /* ashr */
807 {
808 int a = (inst >> 4) & 0xf;
809 int b = inst & 0xf;
810 int av = cpu.asregs.regs[a];
811 int bv = cpu.asregs.regs[b];
812 TRACE("ashr");
813 cpu.asregs.regs[a] = av >> bv;
814 }
815 break;
816 case 0x2e: /* xor */
817 {
818 int a = (inst >> 4) & 0xf;
819 int b = inst & 0xf;
820 int av, bv;
821 TRACE("xor");
822 av = cpu.asregs.regs[a];
823 bv = cpu.asregs.regs[b];
824 cpu.asregs.regs[a] = av ^ bv;
825 }
826 break;
827 case 0x2f: /* mul.l */
828 {
829 int a = (inst >> 4) & 0xf;
830 int b = inst & 0xf;
831 unsigned av = cpu.asregs.regs[a];
832 unsigned bv = cpu.asregs.regs[b];
833 TRACE("mul.l");
834 cpu.asregs.regs[a] = av * bv;
835 }
836 break;
837 case 0x30: /* swi */
838 {
839 unsigned int inum = EXTRACT_WORD(pc+2);
840 TRACE("swi");
841 /* Set the special registers appropriately. */
842 cpu.asregs.sregs[2] = 3; /* MOXIE_EX_SWI */
843 cpu.asregs.sregs[3] = inum;
844 switch (inum)
845 {
846 case 0x1: /* SYS_exit */
847 {
848 cpu.asregs.exception = SIGQUIT;
849 break;
850 }
851 case 0x2: /* SYS_open */
852 {
853 char fname[1024];
854 int mode = (int) convert_target_flags ((unsigned) cpu.asregs.regs[3]);
855 int perm = (int) cpu.asregs.regs[4];
856 int fd = open (fname, mode, perm);
857 sim_core_read_buffer (sd, scpu, read_map, fname,
858 cpu.asregs.regs[2], 1024);
859 /* FIXME - set errno */
860 cpu.asregs.regs[2] = fd;
861 break;
862 }
863 case 0x4: /* SYS_read */
864 {
865 int fd = cpu.asregs.regs[2];
866 unsigned len = (unsigned) cpu.asregs.regs[4];
867 char *buf = malloc (len);
868 cpu.asregs.regs[2] = read (fd, buf, len);
869 sim_core_write_buffer (sd, scpu, write_map, buf,
870 cpu.asregs.regs[3], len);
871 free (buf);
872 break;
873 }
874 case 0x5: /* SYS_write */
875 {
876 char *str;
877 /* String length is at 0x12($fp) */
878 unsigned count, len = (unsigned) cpu.asregs.regs[4];
879 str = malloc (len);
880 sim_core_read_buffer (sd, scpu, read_map, str,
881 cpu.asregs.regs[3], len);
882 count = write (cpu.asregs.regs[2], str, len);
883 free (str);
884 cpu.asregs.regs[2] = count;
885 break;
886 }
887 case 0xffffffff: /* Linux System Call */
888 {
889 unsigned int handler = cpu.asregs.sregs[1];
890 unsigned int sp = cpu.asregs.regs[1];
891
892 /* Save a slot for the static chain. */
893 sp -= 4;
894
895 /* Push the return address. */
896 sp -= 4;
897 wlat (scpu, opc, sp, pc + 6);
898
899 /* Push the current frame pointer. */
900 sp -= 4;
901 wlat (scpu, opc, sp, cpu.asregs.regs[0]);
902
903 /* Uncache the stack pointer and set the fp & pc. */
904 cpu.asregs.regs[1] = sp;
905 cpu.asregs.regs[0] = sp;
906 pc = handler - 6;
907 }
908 default:
909 break;
910 }
911 pc += 4;
912 }
913 break;
914 case 0x31: /* div.l */
915 {
916 int a = (inst >> 4) & 0xf;
917 int b = inst & 0xf;
918 int av = cpu.asregs.regs[a];
919 int bv = cpu.asregs.regs[b];
920 TRACE("div.l");
921 cpu.asregs.regs[a] = av / bv;
922 }
923 break;
924 case 0x32: /* udiv.l */
925 {
926 int a = (inst >> 4) & 0xf;
927 int b = inst & 0xf;
928 unsigned int av = cpu.asregs.regs[a];
929 unsigned int bv = cpu.asregs.regs[b];
930 TRACE("udiv.l");
931 cpu.asregs.regs[a] = (av / bv);
932 }
933 break;
934 case 0x33: /* mod.l */
935 {
936 int a = (inst >> 4) & 0xf;
937 int b = inst & 0xf;
938 int av = cpu.asregs.regs[a];
939 int bv = cpu.asregs.regs[b];
940 TRACE("mod.l");
941 cpu.asregs.regs[a] = av % bv;
942 }
943 break;
944 case 0x34: /* umod.l */
945 {
946 int a = (inst >> 4) & 0xf;
947 int b = inst & 0xf;
948 unsigned int av = cpu.asregs.regs[a];
949 unsigned int bv = cpu.asregs.regs[b];
950 TRACE("umod.l");
951 cpu.asregs.regs[a] = (av % bv);
952 }
953 break;
954 case 0x35: /* brk */
955 TRACE("brk");
956 cpu.asregs.exception = SIGTRAP;
957 pc -= 2; /* Adjust pc */
958 break;
959 case 0x36: /* ldo.b */
960 {
961 unsigned int addr = EXTRACT_WORD(pc+2);
962 int a = (inst >> 4) & 0xf;
963 int b = inst & 0xf;
964 TRACE("ldo.b");
965 addr += cpu.asregs.regs[b];
966 cpu.asregs.regs[a] = rbat (scpu, opc, addr);
967 pc += 4;
968 }
969 break;
970 case 0x37: /* sto.b */
971 {
972 unsigned int addr = EXTRACT_WORD(pc+2);
973 int a = (inst >> 4) & 0xf;
974 int b = inst & 0xf;
975 TRACE("sto.b");
976 addr += cpu.asregs.regs[a];
977 wbat (scpu, opc, addr, cpu.asregs.regs[b]);
978 pc += 4;
979 }
980 break;
981 case 0x38: /* ldo.s */
982 {
983 unsigned int addr = EXTRACT_WORD(pc+2);
984 int a = (inst >> 4) & 0xf;
985 int b = inst & 0xf;
986 TRACE("ldo.s");
987 addr += cpu.asregs.regs[b];
988 cpu.asregs.regs[a] = rsat (scpu, opc, addr);
989 pc += 4;
990 }
991 break;
992 case 0x39: /* sto.s */
993 {
994 unsigned int addr = EXTRACT_WORD(pc+2);
995 int a = (inst >> 4) & 0xf;
996 int b = inst & 0xf;
997 TRACE("sto.s");
998 addr += cpu.asregs.regs[a];
999 wsat (scpu, opc, addr, cpu.asregs.regs[b]);
1000 pc += 4;
1001 }
1002 break;
1003 default:
1004 opc = opcode;
1005 TRACE("SIGILL1");
1006 cpu.asregs.exception = SIGILL;
1007 break;
1008 }
1009 }
1010
1011 insts++;
1012 pc += 2;
1013
1014 } while (!cpu.asregs.exception);
1015
1016 /* Hide away the things we've cached while executing. */
1017 cpu.asregs.regs[PC_REGNO] = pc;
1018 cpu.asregs.insts += insts; /* instructions done ... */
1019
1020 signal (SIGINT, sigsave);
1021 }
1022
1023 int
1024 sim_write (sd, addr, buffer, size)
1025 SIM_DESC sd;
1026 SIM_ADDR addr;
1027 unsigned char * buffer;
1028 int size;
1029 {
1030 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1031
1032 sim_core_write_buffer (sd, scpu, write_map, buffer, addr, size);
1033
1034 return size;
1035 }
1036
1037 int
1038 sim_read (sd, addr, buffer, size)
1039 SIM_DESC sd;
1040 SIM_ADDR addr;
1041 unsigned char * buffer;
1042 int size;
1043 {
1044 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1045
1046 sim_core_read_buffer (sd, scpu, read_map, buffer, addr, size);
1047
1048 return size;
1049 }
1050
1051
1052 int
1053 sim_store_register (sd, rn, memory, length)
1054 SIM_DESC sd;
1055 int rn;
1056 unsigned char * memory;
1057 int length;
1058 {
1059 if (rn < NUM_MOXIE_REGS && rn >= 0)
1060 {
1061 if (length == 4)
1062 {
1063 long ival;
1064
1065 /* misalignment safe */
1066 ival = moxie_extract_unsigned_integer (memory, 4);
1067 cpu.asints[rn] = ival;
1068 }
1069
1070 return 4;
1071 }
1072 else
1073 return 0;
1074 }
1075
1076 int
1077 sim_fetch_register (sd, rn, memory, length)
1078 SIM_DESC sd;
1079 int rn;
1080 unsigned char * memory;
1081 int length;
1082 {
1083 if (rn < NUM_MOXIE_REGS && rn >= 0)
1084 {
1085 if (length == 4)
1086 {
1087 long ival = cpu.asints[rn];
1088
1089 /* misalignment-safe */
1090 moxie_store_unsigned_integer (memory, 4, ival);
1091 }
1092
1093 return 4;
1094 }
1095 else
1096 return 0;
1097 }
1098
1099
1100 int
1101 sim_trace (sd)
1102 SIM_DESC sd;
1103 {
1104 if (tracefile == 0)
1105 tracefile = fopen("trace.csv", "wb");
1106
1107 tracing = 1;
1108
1109 sim_resume (sd, 0, 0);
1110
1111 tracing = 0;
1112
1113 return 1;
1114 }
1115
1116 void
1117 sim_stop_reason (sd, reason, sigrc)
1118 SIM_DESC sd;
1119 enum sim_stop * reason;
1120 int * sigrc;
1121 {
1122 if (cpu.asregs.exception == SIGQUIT)
1123 {
1124 * reason = sim_exited;
1125 * sigrc = cpu.asregs.regs[2];
1126 }
1127 else
1128 {
1129 * reason = sim_stopped;
1130 * sigrc = cpu.asregs.exception;
1131 }
1132 }
1133
1134
1135 int
1136 sim_stop (sd)
1137 SIM_DESC sd;
1138 {
1139 cpu.asregs.exception = SIGINT;
1140 return 1;
1141 }
1142
1143
1144 void
1145 sim_info (sd, verbose)
1146 SIM_DESC sd;
1147 int verbose;
1148 {
1149 callback->printf_filtered (callback, "\n\n# instructions executed %llu\n",
1150 cpu.asregs.insts);
1151 }
1152
1153
1154 SIM_DESC
1155 sim_open (kind, cb, abfd, argv)
1156 SIM_OPEN_KIND kind;
1157 host_callback * cb;
1158 struct bfd * abfd;
1159 char ** argv;
1160 {
1161 SIM_DESC sd = sim_state_alloc (kind, cb);
1162 printf ("0x%x 0x%x\n", sd, STATE_MAGIC(sd));
1163 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
1164
1165 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
1166 return 0;
1167
1168 sim_do_command(sd," memory region 0x00000000,0x4000000") ;
1169 sim_do_command(sd," memory region 0xE0000000,0x10000") ;
1170
1171 myname = argv[0];
1172 callback = cb;
1173
1174 if (kind == SIM_OPEN_STANDALONE)
1175 issue_messages = 1;
1176
1177 set_initial_gprs (); /* Reset the GPR registers. */
1178
1179 return sd;
1180 }
1181
1182 void
1183 sim_close (sd, quitting)
1184 SIM_DESC sd;
1185 int quitting;
1186 {
1187 /* nothing to do */
1188 }
1189
1190
1191 /* Load the device tree blob. */
1192
1193 static void
1194 load_dtb (SIM_DESC sd, const char *filename)
1195 {
1196 int size = 0;
1197 FILE *f = fopen (filename, "rb");
1198 char *buf;
1199 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1200 if (f == NULL)
1201 {
1202 printf ("WARNING: ``%s'' could not be opened.\n", filename);
1203 return;
1204 }
1205 fseek (f, 0, SEEK_END);
1206 size = ftell(f);
1207 fseek (f, 0, SEEK_SET);
1208 buf = alloca (size);
1209 if (size != fread (buf, 1, size, f))
1210 {
1211 printf ("ERROR: error reading ``%s''.\n", filename);
1212 return;
1213 }
1214 sim_core_write_buffer (sd, scpu, write_map, buf, 0xE0000000, size);
1215 cpu.asregs.sregs[9] = 0xE0000000;
1216 fclose (f);
1217 }
1218
1219 SIM_RC
1220 sim_load (sd, prog, abfd, from_tty)
1221 SIM_DESC sd;
1222 char * prog;
1223 bfd * abfd;
1224 int from_tty;
1225 {
1226
1227 /* Do the right thing for ELF executables; this turns out to be
1228 just about the right thing for any object format that:
1229 - we crack using BFD routines
1230 - follows the traditional UNIX text/data/bss layout
1231 - calls the bss section ".bss". */
1232
1233 extern bfd * sim_load_file (); /* ??? Don't know where this should live. */
1234 bfd * prog_bfd;
1235
1236 {
1237 bfd * handle;
1238 handle = bfd_openr (prog, 0); /* could be "moxie" */
1239
1240 if (!handle)
1241 {
1242 printf("``%s'' could not be opened.\n", prog);
1243 return SIM_RC_FAIL;
1244 }
1245
1246 /* Makes sure that we have an object file, also cleans gets the
1247 section headers in place. */
1248 if (!bfd_check_format (handle, bfd_object))
1249 {
1250 /* wasn't an object file */
1251 bfd_close (handle);
1252 printf ("``%s'' is not appropriate object file.\n", prog);
1253 return SIM_RC_FAIL;
1254 }
1255
1256 /* Clean up after ourselves. */
1257 bfd_close (handle);
1258 }
1259
1260 /* from sh -- dac */
1261 prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
1262 sim_kind == SIM_OPEN_DEBUG,
1263 0, sim_write);
1264 if (prog_bfd == NULL)
1265 return SIM_RC_FAIL;
1266
1267 if (abfd == NULL)
1268 bfd_close (prog_bfd);
1269
1270 return SIM_RC_OK;
1271 }
1272
1273 SIM_RC
1274 sim_create_inferior (sd, prog_bfd, argv, env)
1275 SIM_DESC sd;
1276 struct bfd * prog_bfd;
1277 char ** argv;
1278 char ** env;
1279 {
1280 char ** avp;
1281 int l, argc, i, tp;
1282 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1283
1284 /* Set the initial register set. */
1285 l = issue_messages;
1286 issue_messages = 0;
1287 set_initial_gprs ();
1288 issue_messages = l;
1289
1290 cpu.asregs.regs[PC_REGNO] = bfd_get_start_address (prog_bfd);
1291
1292 /* Copy args into target memory. */
1293 avp = argv;
1294 for (argc = 0; *avp; avp++)
1295 argc++;
1296
1297 /* Target memory looks like this:
1298 0x00000000 zero word
1299 0x00000004 argc word
1300 0x00000008 start of argv
1301 .
1302 0x0000???? end of argv
1303 0x0000???? zero word
1304 0x0000???? start of data pointed to by argv */
1305
1306 wlat (scpu, 0, 0, 0);
1307 wlat (scpu, 0, 4, argc);
1308
1309 /* tp is the offset of our first argv data. */
1310 tp = 4 + 4 + argc * 4 + 4;
1311
1312 for (i = 0; i < argc; i++)
1313 {
1314 /* Set the argv value. */
1315 wlat (scpu, 0, 4 + 4 + i * 4, tp);
1316
1317 /* Store the string. */
1318 sim_core_write_buffer (sd, scpu, write_map, argv[i],
1319 tp, strlen(argv[i])+1);
1320 tp += strlen (argv[i]) + 1;
1321 }
1322
1323 wlat (scpu, 0, 4 + 4 + i * 4, 0);
1324
1325 load_dtb (sd, DTB);
1326
1327 return SIM_RC_OK;
1328 }
1329
1330 void
1331 sim_kill (sd)
1332 SIM_DESC sd;
1333 {
1334 if (tracefile)
1335 fclose(tracefile);
1336 }
1337
1338 void
1339 sim_do_command (sd, cmd)
1340 SIM_DESC sd;
1341 char * cmd;
1342 {
1343 if (sim_args_command (sd, cmd) != SIM_RC_OK)
1344 sim_io_printf (sd,
1345 "Error: \"%s\" is not a valid moxie simulator command.\n",
1346 cmd);
1347 }
1348
1349 void
1350 sim_set_callbacks (ptr)
1351 host_callback * ptr;
1352 {
1353 callback = ptr;
1354 }
This page took 0.062934 seconds and 3 git commands to generate.