cd1bbeb73bb6a43f719fd2b78c344276497fabef
[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 /* Configure/verify the target byte order and other runtime
1180 configuration options. */
1181 if (sim_config (sd) != SIM_RC_OK)
1182 {
1183 sim_module_uninstall (sd);
1184 return 0;
1185 }
1186
1187 if (sim_post_argv_init (sd) != SIM_RC_OK)
1188 {
1189 /* Uninstall the modules to avoid memory leaks,
1190 file descriptor leaks, etc. */
1191 sim_module_uninstall (sd);
1192 return 0;
1193 }
1194
1195 return sd;
1196 }
1197
1198 void
1199 sim_close (sd, quitting)
1200 SIM_DESC sd;
1201 int quitting;
1202 {
1203 /* nothing to do */
1204 }
1205
1206
1207 /* Load the device tree blob. */
1208
1209 static void
1210 load_dtb (SIM_DESC sd, const char *filename)
1211 {
1212 int size = 0;
1213 FILE *f = fopen (filename, "rb");
1214 char *buf;
1215 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1216 if (f == NULL)
1217 {
1218 printf ("WARNING: ``%s'' could not be opened.\n", filename);
1219 return;
1220 }
1221 fseek (f, 0, SEEK_END);
1222 size = ftell(f);
1223 fseek (f, 0, SEEK_SET);
1224 buf = alloca (size);
1225 if (size != fread (buf, 1, size, f))
1226 {
1227 printf ("ERROR: error reading ``%s''.\n", filename);
1228 return;
1229 }
1230 sim_core_write_buffer (sd, scpu, write_map, buf, 0xE0000000, size);
1231 cpu.asregs.sregs[9] = 0xE0000000;
1232 fclose (f);
1233 }
1234
1235 SIM_RC
1236 sim_load (sd, prog, abfd, from_tty)
1237 SIM_DESC sd;
1238 char * prog;
1239 bfd * abfd;
1240 int from_tty;
1241 {
1242
1243 /* Do the right thing for ELF executables; this turns out to be
1244 just about the right thing for any object format that:
1245 - we crack using BFD routines
1246 - follows the traditional UNIX text/data/bss layout
1247 - calls the bss section ".bss". */
1248
1249 extern bfd * sim_load_file (); /* ??? Don't know where this should live. */
1250 bfd * prog_bfd;
1251
1252 {
1253 bfd * handle;
1254 handle = bfd_openr (prog, 0); /* could be "moxie" */
1255
1256 if (!handle)
1257 {
1258 printf("``%s'' could not be opened.\n", prog);
1259 return SIM_RC_FAIL;
1260 }
1261
1262 /* Makes sure that we have an object file, also cleans gets the
1263 section headers in place. */
1264 if (!bfd_check_format (handle, bfd_object))
1265 {
1266 /* wasn't an object file */
1267 bfd_close (handle);
1268 printf ("``%s'' is not appropriate object file.\n", prog);
1269 return SIM_RC_FAIL;
1270 }
1271
1272 /* Clean up after ourselves. */
1273 bfd_close (handle);
1274 }
1275
1276 /* from sh -- dac */
1277 prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
1278 sim_kind == SIM_OPEN_DEBUG,
1279 0, sim_write);
1280 if (prog_bfd == NULL)
1281 return SIM_RC_FAIL;
1282
1283 if (abfd == NULL)
1284 bfd_close (prog_bfd);
1285
1286 return SIM_RC_OK;
1287 }
1288
1289 SIM_RC
1290 sim_create_inferior (sd, prog_bfd, argv, env)
1291 SIM_DESC sd;
1292 struct bfd * prog_bfd;
1293 char ** argv;
1294 char ** env;
1295 {
1296 char ** avp;
1297 int l, argc, i, tp;
1298 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1299
1300 /* Set the initial register set. */
1301 l = issue_messages;
1302 issue_messages = 0;
1303 set_initial_gprs ();
1304 issue_messages = l;
1305
1306 cpu.asregs.regs[PC_REGNO] = bfd_get_start_address (prog_bfd);
1307
1308 /* Copy args into target memory. */
1309 avp = argv;
1310 for (argc = 0; *avp; avp++)
1311 argc++;
1312
1313 /* Target memory looks like this:
1314 0x00000000 zero word
1315 0x00000004 argc word
1316 0x00000008 start of argv
1317 .
1318 0x0000???? end of argv
1319 0x0000???? zero word
1320 0x0000???? start of data pointed to by argv */
1321
1322 wlat (scpu, 0, 0, 0);
1323 wlat (scpu, 0, 4, argc);
1324
1325 /* tp is the offset of our first argv data. */
1326 tp = 4 + 4 + argc * 4 + 4;
1327
1328 for (i = 0; i < argc; i++)
1329 {
1330 /* Set the argv value. */
1331 wlat (scpu, 0, 4 + 4 + i * 4, tp);
1332
1333 /* Store the string. */
1334 sim_core_write_buffer (sd, scpu, write_map, argv[i],
1335 tp, strlen(argv[i])+1);
1336 tp += strlen (argv[i]) + 1;
1337 }
1338
1339 wlat (scpu, 0, 4 + 4 + i * 4, 0);
1340
1341 load_dtb (sd, DTB);
1342
1343 return SIM_RC_OK;
1344 }
1345
1346 void
1347 sim_kill (sd)
1348 SIM_DESC sd;
1349 {
1350 if (tracefile)
1351 fclose(tracefile);
1352 }
1353
1354 void
1355 sim_do_command (sd, cmd)
1356 SIM_DESC sd;
1357 char * cmd;
1358 {
1359 if (sim_args_command (sd, cmd) != SIM_RC_OK)
1360 sim_io_printf (sd,
1361 "Error: \"%s\" is not a valid moxie simulator command.\n",
1362 cmd);
1363 }
1364
1365 void
1366 sim_set_callbacks (ptr)
1367 host_callback * ptr;
1368 {
1369 callback = ptr;
1370 }
This page took 0.054433 seconds and 3 git commands to generate.