]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/moxie/interp.c
run copyright.sh for 2011.
[thirdparty/binutils-gdb.git] / sim / moxie / interp.c
1 /* Simulator for the moxie processor
2 Copyright (C) 2008, 2009, 2010, 2011 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: /* bad */
418 opc = opcode;
419 TRACE("SIGILL0");
420 cpu.asregs.exception = SIGILL;
421 break;
422 case 0x01: /* ldi.l (immediate) */
423 {
424 int reg = (inst >> 4) & 0xf;
425 TRACE("ldi.l");
426 unsigned int val = EXTRACT_WORD(pc+2);
427 cpu.asregs.regs[reg] = val;
428 pc += 4;
429 }
430 break;
431 case 0x02: /* mov (register-to-register) */
432 {
433 int dest = (inst >> 4) & 0xf;
434 int src = (inst ) & 0xf;
435 TRACE("mov");
436 cpu.asregs.regs[dest] = cpu.asregs.regs[src];
437 }
438 break;
439 case 0x03: /* jsra */
440 {
441 unsigned int fn = EXTRACT_WORD(pc+2);
442 unsigned int sp = cpu.asregs.regs[1];
443 TRACE("jsra");
444 /* Save a slot for the static chain. */
445 sp -= 4;
446
447 /* Push the return address. */
448 sp -= 4;
449 wlat (scpu, opc, sp, pc + 6);
450
451 /* Push the current frame pointer. */
452 sp -= 4;
453 wlat (scpu, opc, sp, cpu.asregs.regs[0]);
454
455 /* Uncache the stack pointer and set the pc and $fp. */
456 cpu.asregs.regs[1] = sp;
457 cpu.asregs.regs[0] = sp;
458 pc = fn - 2;
459 }
460 break;
461 case 0x04: /* ret */
462 {
463 unsigned int sp = cpu.asregs.regs[0];
464
465 TRACE("ret");
466
467 /* Pop the frame pointer. */
468 cpu.asregs.regs[0] = rlat (scpu, opc, sp);
469 sp += 4;
470
471 /* Pop the return address. */
472 pc = rlat (scpu, opc, sp) - 2;
473 sp += 4;
474
475 /* Skip over the static chain slot. */
476 sp += 4;
477
478 /* Uncache the stack pointer. */
479 cpu.asregs.regs[1] = sp;
480 }
481 break;
482 case 0x05: /* add.l */
483 {
484 int a = (inst >> 4) & 0xf;
485 int b = inst & 0xf;
486 unsigned av = cpu.asregs.regs[a];
487 unsigned bv = cpu.asregs.regs[b];
488 TRACE("add.l");
489 cpu.asregs.regs[a] = av + bv;
490 }
491 break;
492 case 0x06: /* push */
493 {
494 int a = (inst >> 4) & 0xf;
495 int b = inst & 0xf;
496 int sp = cpu.asregs.regs[a] - 4;
497 TRACE("push");
498 wlat (scpu, opc, sp, cpu.asregs.regs[b]);
499 cpu.asregs.regs[a] = sp;
500 }
501 break;
502 case 0x07: /* pop */
503 {
504 int a = (inst >> 4) & 0xf;
505 int b = inst & 0xf;
506 int sp = cpu.asregs.regs[a];
507 TRACE("pop");
508 cpu.asregs.regs[b] = rlat (scpu, opc, sp);
509 cpu.asregs.regs[a] = sp + 4;
510 }
511 break;
512 case 0x08: /* lda.l */
513 {
514 int reg = (inst >> 4) & 0xf;
515 unsigned int addr = EXTRACT_WORD(pc+2);
516 TRACE("lda.l");
517 cpu.asregs.regs[reg] = rlat (scpu, opc, addr);
518 pc += 4;
519 }
520 break;
521 case 0x09: /* sta.l */
522 {
523 int reg = (inst >> 4) & 0xf;
524 unsigned int addr = EXTRACT_WORD(pc+2);
525 TRACE("sta.l");
526 wlat (scpu, opc, addr, cpu.asregs.regs[reg]);
527 pc += 4;
528 }
529 break;
530 case 0x0a: /* ld.l (register indirect) */
531 {
532 int src = inst & 0xf;
533 int dest = (inst >> 4) & 0xf;
534 int xv;
535 TRACE("ld.l");
536 xv = cpu.asregs.regs[src];
537 cpu.asregs.regs[dest] = rlat (scpu, opc, xv);
538 }
539 break;
540 case 0x0b: /* st.l */
541 {
542 int dest = (inst >> 4) & 0xf;
543 int val = inst & 0xf;
544 TRACE("st.l");
545 wlat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
546 }
547 break;
548 case 0x0c: /* ldo.l */
549 {
550 unsigned int addr = EXTRACT_WORD(pc+2);
551 int a = (inst >> 4) & 0xf;
552 int b = inst & 0xf;
553 TRACE("ldo.l");
554 addr += cpu.asregs.regs[b];
555 cpu.asregs.regs[a] = rlat (scpu, opc, addr);
556 pc += 4;
557 }
558 break;
559 case 0x0d: /* sto.l */
560 {
561 unsigned int addr = EXTRACT_WORD(pc+2);
562 int a = (inst >> 4) & 0xf;
563 int b = inst & 0xf;
564 TRACE("sto.l");
565 addr += cpu.asregs.regs[a];
566 wlat (scpu, opc, addr, cpu.asregs.regs[b]);
567 pc += 4;
568 }
569 break;
570 case 0x0e: /* cmp */
571 {
572 int a = (inst >> 4) & 0xf;
573 int b = inst & 0xf;
574 int cc = 0;
575 int va = cpu.asregs.regs[a];
576 int vb = cpu.asregs.regs[b];
577
578 TRACE("cmp");
579
580 if (va == vb)
581 cc = CC_EQ;
582 else
583 {
584 cc |= (va < vb ? CC_LT : 0);
585 cc |= (va > vb ? CC_GT : 0);
586 cc |= ((unsigned int) va < (unsigned int) vb ? CC_LTU : 0);
587 cc |= ((unsigned int) va > (unsigned int) vb ? CC_GTU : 0);
588 }
589
590 cpu.asregs.cc = cc;
591 }
592 break;
593 case 0x0f: /* nop */
594 break;
595 case 0x10: /* bad */
596 case 0x11: /* bad */
597 case 0x12: /* bad */
598 case 0x13: /* bad */
599 case 0x14: /* bad */
600 case 0x15: /* bad */
601 case 0x16: /* bad */
602 case 0x17: /* bad */
603 case 0x18: /* bad */
604 {
605 opc = opcode;
606 TRACE("SIGILL0");
607 cpu.asregs.exception = SIGILL;
608 break;
609 }
610 case 0x19: /* jsr */
611 {
612 unsigned int fn = cpu.asregs.regs[(inst >> 4) & 0xf];
613 unsigned int sp = cpu.asregs.regs[1];
614
615 TRACE("jsr");
616
617 /* Save a slot for the static chain. */
618 sp -= 4;
619
620 /* Push the return address. */
621 sp -= 4;
622 wlat (scpu, opc, sp, pc + 2);
623
624 /* Push the current frame pointer. */
625 sp -= 4;
626 wlat (scpu, opc, sp, cpu.asregs.regs[0]);
627
628 /* Uncache the stack pointer and set the fp & pc. */
629 cpu.asregs.regs[1] = sp;
630 cpu.asregs.regs[0] = sp;
631 pc = fn - 2;
632 }
633 break;
634 case 0x1a: /* jmpa */
635 {
636 unsigned int tgt = EXTRACT_WORD(pc+2);
637 TRACE("jmpa");
638 pc = tgt - 2;
639 }
640 break;
641 case 0x1b: /* ldi.b (immediate) */
642 {
643 int reg = (inst >> 4) & 0xf;
644
645 unsigned int val = EXTRACT_WORD(pc+2);
646 TRACE("ldi.b");
647 cpu.asregs.regs[reg] = val;
648 pc += 4;
649 }
650 break;
651 case 0x1c: /* ld.b (register indirect) */
652 {
653 int src = inst & 0xf;
654 int dest = (inst >> 4) & 0xf;
655 int xv;
656 TRACE("ld.b");
657 xv = cpu.asregs.regs[src];
658 cpu.asregs.regs[dest] = rbat (scpu, opc, xv);
659 }
660 break;
661 case 0x1d: /* lda.b */
662 {
663 int reg = (inst >> 4) & 0xf;
664 unsigned int addr = EXTRACT_WORD(pc+2);
665 TRACE("lda.b");
666 cpu.asregs.regs[reg] = rbat (scpu, opc, addr);
667 pc += 4;
668 }
669 break;
670 case 0x1e: /* st.b */
671 {
672 int dest = (inst >> 4) & 0xf;
673 int val = inst & 0xf;
674 TRACE("st.b");
675 wbat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
676 }
677 break;
678 case 0x1f: /* sta.b */
679 {
680 int reg = (inst >> 4) & 0xf;
681 unsigned int addr = EXTRACT_WORD(pc+2);
682 TRACE("sta.b");
683 wbat (scpu, opc, addr, cpu.asregs.regs[reg]);
684 pc += 4;
685 }
686 break;
687 case 0x20: /* ldi.s (immediate) */
688 {
689 int reg = (inst >> 4) & 0xf;
690
691 unsigned int val = EXTRACT_WORD(pc+2);
692 TRACE("ldi.s");
693 cpu.asregs.regs[reg] = val;
694 pc += 4;
695 }
696 break;
697 case 0x21: /* ld.s (register indirect) */
698 {
699 int src = inst & 0xf;
700 int dest = (inst >> 4) & 0xf;
701 int xv;
702 TRACE("ld.s");
703 xv = cpu.asregs.regs[src];
704 cpu.asregs.regs[dest] = rsat (scpu, opc, xv);
705 }
706 break;
707 case 0x22: /* lda.s */
708 {
709 int reg = (inst >> 4) & 0xf;
710 unsigned int addr = EXTRACT_WORD(pc+2);
711 TRACE("lda.s");
712 cpu.asregs.regs[reg] = rsat (scpu, opc, addr);
713 pc += 4;
714 }
715 break;
716 case 0x23: /* st.s */
717 {
718 int dest = (inst >> 4) & 0xf;
719 int val = inst & 0xf;
720 TRACE("st.s");
721 wsat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
722 }
723 break;
724 case 0x24: /* sta.s */
725 {
726 int reg = (inst >> 4) & 0xf;
727 unsigned int addr = EXTRACT_WORD(pc+2);
728 TRACE("sta.s");
729 wsat (scpu, opc, addr, cpu.asregs.regs[reg]);
730 pc += 4;
731 }
732 break;
733 case 0x25: /* jmp */
734 {
735 int reg = (inst >> 4) & 0xf;
736 TRACE("jmp");
737 pc = cpu.asregs.regs[reg] - 2;
738 }
739 break;
740 case 0x26: /* and */
741 {
742 int a = (inst >> 4) & 0xf;
743 int b = inst & 0xf;
744 int av, bv;
745 TRACE("and");
746 av = cpu.asregs.regs[a];
747 bv = cpu.asregs.regs[b];
748 cpu.asregs.regs[a] = av & bv;
749 }
750 break;
751 case 0x27: /* lshr */
752 {
753 int a = (inst >> 4) & 0xf;
754 int b = inst & 0xf;
755 int av = cpu.asregs.regs[a];
756 int bv = cpu.asregs.regs[b];
757 TRACE("lshr");
758 cpu.asregs.regs[a] = (unsigned) ((unsigned) av >> bv);
759 }
760 break;
761 case 0x28: /* ashl */
762 {
763 int a = (inst >> 4) & 0xf;
764 int b = inst & 0xf;
765 int av = cpu.asregs.regs[a];
766 int bv = cpu.asregs.regs[b];
767 TRACE("ashl");
768 cpu.asregs.regs[a] = av << bv;
769 }
770 break;
771 case 0x29: /* sub.l */
772 {
773 int a = (inst >> 4) & 0xf;
774 int b = inst & 0xf;
775 unsigned av = cpu.asregs.regs[a];
776 unsigned bv = cpu.asregs.regs[b];
777 TRACE("sub.l");
778 cpu.asregs.regs[a] = av - bv;
779 }
780 break;
781 case 0x2a: /* neg */
782 {
783 int a = (inst >> 4) & 0xf;
784 int b = inst & 0xf;
785 int bv = cpu.asregs.regs[b];
786 TRACE("neg");
787 cpu.asregs.regs[a] = - bv;
788 }
789 break;
790 case 0x2b: /* or */
791 {
792 int a = (inst >> 4) & 0xf;
793 int b = inst & 0xf;
794 int av, bv;
795 TRACE("or");
796 av = cpu.asregs.regs[a];
797 bv = cpu.asregs.regs[b];
798 cpu.asregs.regs[a] = av | bv;
799 }
800 break;
801 case 0x2c: /* not */
802 {
803 int a = (inst >> 4) & 0xf;
804 int b = inst & 0xf;
805 int bv = cpu.asregs.regs[b];
806 TRACE("not");
807 cpu.asregs.regs[a] = 0xffffffff ^ bv;
808 }
809 break;
810 case 0x2d: /* ashr */
811 {
812 int a = (inst >> 4) & 0xf;
813 int b = inst & 0xf;
814 int av = cpu.asregs.regs[a];
815 int bv = cpu.asregs.regs[b];
816 TRACE("ashr");
817 cpu.asregs.regs[a] = av >> bv;
818 }
819 break;
820 case 0x2e: /* xor */
821 {
822 int a = (inst >> 4) & 0xf;
823 int b = inst & 0xf;
824 int av, bv;
825 TRACE("xor");
826 av = cpu.asregs.regs[a];
827 bv = cpu.asregs.regs[b];
828 cpu.asregs.regs[a] = av ^ bv;
829 }
830 break;
831 case 0x2f: /* mul.l */
832 {
833 int a = (inst >> 4) & 0xf;
834 int b = inst & 0xf;
835 unsigned av = cpu.asregs.regs[a];
836 unsigned bv = cpu.asregs.regs[b];
837 TRACE("mul.l");
838 cpu.asregs.regs[a] = av * bv;
839 }
840 break;
841 case 0x30: /* swi */
842 {
843 unsigned int inum = EXTRACT_WORD(pc+2);
844 TRACE("swi");
845 /* Set the special registers appropriately. */
846 cpu.asregs.sregs[2] = 3; /* MOXIE_EX_SWI */
847 cpu.asregs.sregs[3] = inum;
848 switch (inum)
849 {
850 case 0x1: /* SYS_exit */
851 {
852 cpu.asregs.exception = SIGQUIT;
853 break;
854 }
855 case 0x2: /* SYS_open */
856 {
857 char fname[1024];
858 int mode = (int) convert_target_flags ((unsigned) cpu.asregs.regs[3]);
859 int perm = (int) cpu.asregs.regs[4];
860 int fd = open (fname, mode, perm);
861 sim_core_read_buffer (sd, scpu, read_map, fname,
862 cpu.asregs.regs[2], 1024);
863 /* FIXME - set errno */
864 cpu.asregs.regs[2] = fd;
865 break;
866 }
867 case 0x4: /* SYS_read */
868 {
869 int fd = cpu.asregs.regs[2];
870 unsigned len = (unsigned) cpu.asregs.regs[4];
871 char *buf = malloc (len);
872 cpu.asregs.regs[2] = read (fd, buf, len);
873 sim_core_write_buffer (sd, scpu, write_map, buf,
874 cpu.asregs.regs[3], len);
875 free (buf);
876 break;
877 }
878 case 0x5: /* SYS_write */
879 {
880 char *str;
881 /* String length is at 0x12($fp) */
882 unsigned count, len = (unsigned) cpu.asregs.regs[4];
883 str = malloc (len);
884 sim_core_read_buffer (sd, scpu, read_map, str,
885 cpu.asregs.regs[3], len);
886 count = write (cpu.asregs.regs[2], str, len);
887 free (str);
888 cpu.asregs.regs[2] = count;
889 break;
890 }
891 case 0xffffffff: /* Linux System Call */
892 {
893 unsigned int handler = cpu.asregs.sregs[1];
894 unsigned int sp = cpu.asregs.regs[1];
895
896 /* Save a slot for the static chain. */
897 sp -= 4;
898
899 /* Push the return address. */
900 sp -= 4;
901 wlat (scpu, opc, sp, pc + 6);
902
903 /* Push the current frame pointer. */
904 sp -= 4;
905 wlat (scpu, opc, sp, cpu.asregs.regs[0]);
906
907 /* Uncache the stack pointer and set the fp & pc. */
908 cpu.asregs.regs[1] = sp;
909 cpu.asregs.regs[0] = sp;
910 pc = handler - 6;
911 }
912 default:
913 break;
914 }
915 pc += 4;
916 }
917 break;
918 case 0x31: /* div.l */
919 {
920 int a = (inst >> 4) & 0xf;
921 int b = inst & 0xf;
922 int av = cpu.asregs.regs[a];
923 int bv = cpu.asregs.regs[b];
924 TRACE("div.l");
925 cpu.asregs.regs[a] = av / bv;
926 }
927 break;
928 case 0x32: /* udiv.l */
929 {
930 int a = (inst >> 4) & 0xf;
931 int b = inst & 0xf;
932 unsigned int av = cpu.asregs.regs[a];
933 unsigned int bv = cpu.asregs.regs[b];
934 TRACE("udiv.l");
935 cpu.asregs.regs[a] = (av / bv);
936 }
937 break;
938 case 0x33: /* mod.l */
939 {
940 int a = (inst >> 4) & 0xf;
941 int b = inst & 0xf;
942 int av = cpu.asregs.regs[a];
943 int bv = cpu.asregs.regs[b];
944 TRACE("mod.l");
945 cpu.asregs.regs[a] = av % bv;
946 }
947 break;
948 case 0x34: /* umod.l */
949 {
950 int a = (inst >> 4) & 0xf;
951 int b = inst & 0xf;
952 unsigned int av = cpu.asregs.regs[a];
953 unsigned int bv = cpu.asregs.regs[b];
954 TRACE("umod.l");
955 cpu.asregs.regs[a] = (av % bv);
956 }
957 break;
958 case 0x35: /* brk */
959 TRACE("brk");
960 cpu.asregs.exception = SIGTRAP;
961 pc -= 2; /* Adjust pc */
962 break;
963 case 0x36: /* ldo.b */
964 {
965 unsigned int addr = EXTRACT_WORD(pc+2);
966 int a = (inst >> 4) & 0xf;
967 int b = inst & 0xf;
968 TRACE("ldo.b");
969 addr += cpu.asregs.regs[b];
970 cpu.asregs.regs[a] = rbat (scpu, opc, addr);
971 pc += 4;
972 }
973 break;
974 case 0x37: /* sto.b */
975 {
976 unsigned int addr = EXTRACT_WORD(pc+2);
977 int a = (inst >> 4) & 0xf;
978 int b = inst & 0xf;
979 TRACE("sto.b");
980 addr += cpu.asregs.regs[a];
981 wbat (scpu, opc, addr, cpu.asregs.regs[b]);
982 pc += 4;
983 }
984 break;
985 case 0x38: /* ldo.s */
986 {
987 unsigned int addr = EXTRACT_WORD(pc+2);
988 int a = (inst >> 4) & 0xf;
989 int b = inst & 0xf;
990 TRACE("ldo.s");
991 addr += cpu.asregs.regs[b];
992 cpu.asregs.regs[a] = rsat (scpu, opc, addr);
993 pc += 4;
994 }
995 break;
996 case 0x39: /* sto.s */
997 {
998 unsigned int addr = EXTRACT_WORD(pc+2);
999 int a = (inst >> 4) & 0xf;
1000 int b = inst & 0xf;
1001 TRACE("sto.s");
1002 addr += cpu.asregs.regs[a];
1003 wsat (scpu, opc, addr, cpu.asregs.regs[b]);
1004 pc += 4;
1005 }
1006 break;
1007 default:
1008 opc = opcode;
1009 TRACE("SIGILL1");
1010 cpu.asregs.exception = SIGILL;
1011 break;
1012 }
1013 }
1014
1015 insts++;
1016 pc += 2;
1017
1018 } while (!cpu.asregs.exception);
1019
1020 /* Hide away the things we've cached while executing. */
1021 cpu.asregs.regs[PC_REGNO] = pc;
1022 cpu.asregs.insts += insts; /* instructions done ... */
1023
1024 signal (SIGINT, sigsave);
1025 }
1026
1027 int
1028 sim_write (sd, addr, buffer, size)
1029 SIM_DESC sd;
1030 SIM_ADDR addr;
1031 const unsigned char * buffer;
1032 int size;
1033 {
1034 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1035
1036 sim_core_write_buffer (sd, scpu, write_map, buffer, addr, size);
1037
1038 return size;
1039 }
1040
1041 int
1042 sim_read (sd, addr, buffer, size)
1043 SIM_DESC sd;
1044 SIM_ADDR addr;
1045 unsigned char * buffer;
1046 int size;
1047 {
1048 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1049
1050 sim_core_read_buffer (sd, scpu, read_map, buffer, addr, size);
1051
1052 return size;
1053 }
1054
1055
1056 int
1057 sim_store_register (sd, rn, memory, length)
1058 SIM_DESC sd;
1059 int rn;
1060 unsigned char * memory;
1061 int length;
1062 {
1063 if (rn < NUM_MOXIE_REGS && rn >= 0)
1064 {
1065 if (length == 4)
1066 {
1067 long ival;
1068
1069 /* misalignment safe */
1070 ival = moxie_extract_unsigned_integer (memory, 4);
1071 cpu.asints[rn] = ival;
1072 }
1073
1074 return 4;
1075 }
1076 else
1077 return 0;
1078 }
1079
1080 int
1081 sim_fetch_register (sd, rn, memory, length)
1082 SIM_DESC sd;
1083 int rn;
1084 unsigned char * memory;
1085 int length;
1086 {
1087 if (rn < NUM_MOXIE_REGS && rn >= 0)
1088 {
1089 if (length == 4)
1090 {
1091 long ival = cpu.asints[rn];
1092
1093 /* misalignment-safe */
1094 moxie_store_unsigned_integer (memory, 4, ival);
1095 }
1096
1097 return 4;
1098 }
1099 else
1100 return 0;
1101 }
1102
1103
1104 int
1105 sim_trace (sd)
1106 SIM_DESC sd;
1107 {
1108 if (tracefile == 0)
1109 tracefile = fopen("trace.csv", "wb");
1110
1111 tracing = 1;
1112
1113 sim_resume (sd, 0, 0);
1114
1115 tracing = 0;
1116
1117 return 1;
1118 }
1119
1120 void
1121 sim_stop_reason (sd, reason, sigrc)
1122 SIM_DESC sd;
1123 enum sim_stop * reason;
1124 int * sigrc;
1125 {
1126 if (cpu.asregs.exception == SIGQUIT)
1127 {
1128 * reason = sim_exited;
1129 * sigrc = cpu.asregs.regs[2];
1130 }
1131 else
1132 {
1133 * reason = sim_stopped;
1134 * sigrc = cpu.asregs.exception;
1135 }
1136 }
1137
1138
1139 int
1140 sim_stop (sd)
1141 SIM_DESC sd;
1142 {
1143 cpu.asregs.exception = SIGINT;
1144 return 1;
1145 }
1146
1147
1148 void
1149 sim_info (sd, verbose)
1150 SIM_DESC sd;
1151 int verbose;
1152 {
1153 callback->printf_filtered (callback, "\n\n# instructions executed %llu\n",
1154 cpu.asregs.insts);
1155 }
1156
1157
1158 SIM_DESC
1159 sim_open (kind, cb, abfd, argv)
1160 SIM_OPEN_KIND kind;
1161 host_callback * cb;
1162 struct bfd * abfd;
1163 char ** argv;
1164 {
1165 SIM_DESC sd = sim_state_alloc (kind, cb);
1166 printf ("0x%x 0x%x\n", sd, STATE_MAGIC(sd));
1167 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
1168
1169 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
1170 return 0;
1171
1172 sim_do_command(sd," memory region 0x00000000,0x4000000") ;
1173 sim_do_command(sd," memory region 0xE0000000,0x10000") ;
1174
1175 myname = argv[0];
1176 callback = cb;
1177
1178 if (kind == SIM_OPEN_STANDALONE)
1179 issue_messages = 1;
1180
1181 set_initial_gprs (); /* Reset the GPR registers. */
1182
1183 /* Configure/verify the target byte order and other runtime
1184 configuration options. */
1185 if (sim_config (sd) != SIM_RC_OK)
1186 {
1187 sim_module_uninstall (sd);
1188 return 0;
1189 }
1190
1191 if (sim_post_argv_init (sd) != SIM_RC_OK)
1192 {
1193 /* Uninstall the modules to avoid memory leaks,
1194 file descriptor leaks, etc. */
1195 sim_module_uninstall (sd);
1196 return 0;
1197 }
1198
1199 return sd;
1200 }
1201
1202 void
1203 sim_close (sd, quitting)
1204 SIM_DESC sd;
1205 int quitting;
1206 {
1207 /* nothing to do */
1208 }
1209
1210
1211 /* Load the device tree blob. */
1212
1213 static void
1214 load_dtb (SIM_DESC sd, const char *filename)
1215 {
1216 int size = 0;
1217 FILE *f = fopen (filename, "rb");
1218 char *buf;
1219 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1220 if (f == NULL)
1221 {
1222 printf ("WARNING: ``%s'' could not be opened.\n", filename);
1223 return;
1224 }
1225 fseek (f, 0, SEEK_END);
1226 size = ftell(f);
1227 fseek (f, 0, SEEK_SET);
1228 buf = alloca (size);
1229 if (size != fread (buf, 1, size, f))
1230 {
1231 printf ("ERROR: error reading ``%s''.\n", filename);
1232 return;
1233 }
1234 sim_core_write_buffer (sd, scpu, write_map, buf, 0xE0000000, size);
1235 cpu.asregs.sregs[9] = 0xE0000000;
1236 fclose (f);
1237 }
1238
1239 SIM_RC
1240 sim_load (sd, prog, abfd, from_tty)
1241 SIM_DESC sd;
1242 char * prog;
1243 bfd * abfd;
1244 int from_tty;
1245 {
1246
1247 /* Do the right thing for ELF executables; this turns out to be
1248 just about the right thing for any object format that:
1249 - we crack using BFD routines
1250 - follows the traditional UNIX text/data/bss layout
1251 - calls the bss section ".bss". */
1252
1253 extern bfd * sim_load_file (); /* ??? Don't know where this should live. */
1254 bfd * prog_bfd;
1255
1256 {
1257 bfd * handle;
1258 handle = bfd_openr (prog, 0); /* could be "moxie" */
1259
1260 if (!handle)
1261 {
1262 printf("``%s'' could not be opened.\n", prog);
1263 return SIM_RC_FAIL;
1264 }
1265
1266 /* Makes sure that we have an object file, also cleans gets the
1267 section headers in place. */
1268 if (!bfd_check_format (handle, bfd_object))
1269 {
1270 /* wasn't an object file */
1271 bfd_close (handle);
1272 printf ("``%s'' is not appropriate object file.\n", prog);
1273 return SIM_RC_FAIL;
1274 }
1275
1276 /* Clean up after ourselves. */
1277 bfd_close (handle);
1278 }
1279
1280 /* from sh -- dac */
1281 prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
1282 sim_kind == SIM_OPEN_DEBUG,
1283 0, sim_write);
1284 if (prog_bfd == NULL)
1285 return SIM_RC_FAIL;
1286
1287 if (abfd == NULL)
1288 bfd_close (prog_bfd);
1289
1290 return SIM_RC_OK;
1291 }
1292
1293 SIM_RC
1294 sim_create_inferior (sd, prog_bfd, argv, env)
1295 SIM_DESC sd;
1296 struct bfd * prog_bfd;
1297 char ** argv;
1298 char ** env;
1299 {
1300 char ** avp;
1301 int l, argc, i, tp;
1302 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1303
1304 /* Set the initial register set. */
1305 l = issue_messages;
1306 issue_messages = 0;
1307 set_initial_gprs ();
1308 issue_messages = l;
1309
1310 if (prog_bfd != NULL)
1311 cpu.asregs.regs[PC_REGNO] = bfd_get_start_address (prog_bfd);
1312
1313 /* Copy args into target memory. */
1314 avp = argv;
1315 for (argc = 0; avp && *avp; avp++)
1316 argc++;
1317
1318 /* Target memory looks like this:
1319 0x00000000 zero word
1320 0x00000004 argc word
1321 0x00000008 start of argv
1322 .
1323 0x0000???? end of argv
1324 0x0000???? zero word
1325 0x0000???? start of data pointed to by argv */
1326
1327 wlat (scpu, 0, 0, 0);
1328 wlat (scpu, 0, 4, argc);
1329
1330 /* tp is the offset of our first argv data. */
1331 tp = 4 + 4 + argc * 4 + 4;
1332
1333 for (i = 0; i < argc; i++)
1334 {
1335 /* Set the argv value. */
1336 wlat (scpu, 0, 4 + 4 + i * 4, tp);
1337
1338 /* Store the string. */
1339 sim_core_write_buffer (sd, scpu, write_map, argv[i],
1340 tp, strlen(argv[i])+1);
1341 tp += strlen (argv[i]) + 1;
1342 }
1343
1344 wlat (scpu, 0, 4 + 4 + i * 4, 0);
1345
1346 load_dtb (sd, DTB);
1347
1348 return SIM_RC_OK;
1349 }
1350
1351 void
1352 sim_kill (sd)
1353 SIM_DESC sd;
1354 {
1355 if (tracefile)
1356 fclose(tracefile);
1357 }
1358
1359 void
1360 sim_do_command (sd, cmd)
1361 SIM_DESC sd;
1362 char * cmd;
1363 {
1364 if (sim_args_command (sd, cmd) != SIM_RC_OK)
1365 sim_io_printf (sd,
1366 "Error: \"%s\" is not a valid moxie simulator command.\n",
1367 cmd);
1368 }
1369
1370 void
1371 sim_set_callbacks (ptr)
1372 host_callback * ptr;
1373 {
1374 callback = ptr;
1375 }