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