Fix sim breakage
[deliverable/binutils-gdb.git] / sim / moxie / interp.c
CommitLineData
fdd6fa61 1/* Simulator for the moxie processor
ecd75fc8 2 Copyright (C) 2008-2014 Free Software Foundation, Inc.
fdd6fa61
AG
3 Contributed by Anthony Green
4
5This file is part of GDB, the GNU debugger.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
a6c2b87e
MF
20#include "config.h"
21#include <fcntl.h>
fdd6fa61
AG
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
5c27d164
AG
33#include "sim-main.h"
34#include "sim-base.h"
35
fdd6fa61
AG
36typedef int word;
37typedef unsigned int uword;
38
39host_callback * callback;
40
41FILE *tracefile;
42
86566200
AG
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
5c27d164
AG
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)))
fdd6fa61
AG
52
53unsigned long
54moxie_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
77void
78moxie_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. */
95static 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. */
114struct 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;
fdd6fa61
AG
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
129union
130{
131 struct moxie_regset asregs;
132 word asints [1]; /* but accessed larger... */
133} cpu;
134
135static char *myname;
136static SIM_OPEN_KIND sim_kind;
137static int issue_messages = 0;
138
fdd6fa61 139void
5c27d164 140sim_size (int s)
fdd6fa61 141{
fdd6fa61
AG
142}
143
fdd6fa61
AG
144static void
145set_initial_gprs ()
146{
147 int i;
148 long space;
fdd6fa61 149
fdd6fa61
AG
150 /* Set up machine just out of reset. */
151 cpu.asregs.regs[PC_REGNO] = 0;
152
fdd6fa61
AG
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
fdd6fa61
AG
160/* Write a 1 byte value to memory. */
161
162static void INLINE
5c27d164 163wbat (sim_cpu *scpu, word pc, word x, word v)
fdd6fa61 164{
5c27d164
AG
165 address_word cia = CIA_GET (scpu);
166
167 sim_core_write_aligned_1 (scpu, cia, write_map, x, v);
fdd6fa61
AG
168}
169
170/* Write a 2 byte value to memory. */
171
172static void INLINE
5c27d164 173wsat (sim_cpu *scpu, word pc, word x, word v)
fdd6fa61 174{
5c27d164
AG
175 address_word cia = CIA_GET (scpu);
176
177 sim_core_write_aligned_2 (scpu, cia, write_map, x, v);
fdd6fa61
AG
178}
179
180/* Write a 4 byte value to memory. */
181
182static void INLINE
5c27d164 183wlat (sim_cpu *scpu, word pc, word x, word v)
fdd6fa61 184{
5c27d164
AG
185 address_word cia = CIA_GET (scpu);
186
187 sim_core_write_aligned_4 (scpu, cia, write_map, x, v);
fdd6fa61
AG
188}
189
190/* Read 2 bytes from memory. */
191
192static int INLINE
5c27d164 193rsat (sim_cpu *scpu, word pc, word x)
fdd6fa61 194{
5c27d164
AG
195 address_word cia = CIA_GET (scpu);
196
197 return (sim_core_read_aligned_2 (scpu, cia, read_map, x));
fdd6fa61
AG
198}
199
200/* Read 1 byte from memory. */
201
202static int INLINE
5c27d164 203rbat (sim_cpu *scpu, word pc, word x)
fdd6fa61 204{
5c27d164
AG
205 address_word cia = CIA_GET (scpu);
206
207 return (sim_core_read_aligned_1 (scpu, cia, read_map, x));
fdd6fa61
AG
208}
209
210/* Read 4 bytes from memory. */
211
212static int INLINE
5c27d164 213rlat (sim_cpu *scpu, word pc, word x)
fdd6fa61 214{
5c27d164
AG
215 address_word cia = CIA_GET (scpu);
216
217 return (sim_core_read_aligned_4 (scpu, cia, read_map, x));
fdd6fa61
AG
218}
219
220#define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; }
221
222unsigned int
223convert_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
245static int tracing = 0;
246
247void
248sim_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;
5c27d164
AG
255 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
256 address_word cia = CIA_GET (scpu);
fdd6fa61 257
fdd6fa61
AG
258 cpu.asregs.exception = step ? SIGTRAP: 0;
259 pc = cpu.asregs.regs[PC_REGNO];
260 insts = cpu.asregs.insts;
fdd6fa61
AG
261
262 /* Run instructions here. */
263 do
264 {
265 opc = pc;
266
267 /* Fetch the instruction at pc. */
5c27d164
AG
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);
fdd6fa61
AG
270
271 /* Decode instruction. */
272 if (inst & (1 << 15))
273 {
274 if (inst & (1 << 14))
275 {
276 /* This is a Form 3 instruction. */
86566200
AG
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)
78ca4e81 285 pc += INST2OFFSET(inst);
86566200
AG
286 }
287 break;
288 case 0x01: /* bne */
289 {
290 TRACE("bne");
291 if (! (cpu.asregs.cc & CC_EQ))
78ca4e81 292 pc += INST2OFFSET(inst);
86566200
AG
293 }
294 break;
295 case 0x02: /* blt */
296 {
297 TRACE("blt");
298 if (cpu.asregs.cc & CC_LT)
78ca4e81 299 pc += INST2OFFSET(inst);
86566200
AG
300 } break;
301 case 0x03: /* bgt */
302 {
303 TRACE("bgt");
304 if (cpu.asregs.cc & CC_GT)
78ca4e81 305 pc += INST2OFFSET(inst);
86566200
AG
306 }
307 break;
308 case 0x04: /* bltu */
309 {
310 TRACE("bltu");
311 if (cpu.asregs.cc & CC_LTU)
78ca4e81 312 pc += INST2OFFSET(inst);
86566200
AG
313 }
314 break;
315 case 0x05: /* bgtu */
316 {
317 TRACE("bgtu");
318 if (cpu.asregs.cc & CC_GTU)
78ca4e81 319 pc += INST2OFFSET(inst);
86566200
AG
320 }
321 break;
322 case 0x06: /* bge */
323 {
324 TRACE("bge");
325 if (cpu.asregs.cc & (CC_GT | CC_EQ))
78ca4e81 326 pc += INST2OFFSET(inst);
86566200
AG
327 }
328 break;
329 case 0x07: /* ble */
330 {
331 TRACE("ble");
332 if (cpu.asregs.cc & (CC_LT | CC_EQ))
78ca4e81 333 pc += INST2OFFSET(inst);
86566200
AG
334 }
335 break;
336 case 0x08: /* bgeu */
337 {
338 TRACE("bgeu");
339 if (cpu.asregs.cc & (CC_GTU | CC_EQ))
78ca4e81 340 pc += INST2OFFSET(inst);
86566200
AG
341 }
342 break;
343 case 0x09: /* bleu */
344 {
345 TRACE("bleu");
346 if (cpu.asregs.cc & (CC_LTU | CC_EQ))
78ca4e81 347 pc += INST2OFFSET(inst);
86566200
AG
348 }
349 break;
350 default:
351 {
352 TRACE("SIGILL3");
353 cpu.asregs.exception = SIGILL;
354 break;
355 }
356 }
fdd6fa61
AG
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 }
77176dfc 389 break;
fdd6fa61
AG
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 }
77176dfc 397 break;
fdd6fa61
AG
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 {
32d49b7b
AG
411 case 0x00: /* bad */
412 opc = opcode;
413 TRACE("SIGILL0");
414 cpu.asregs.exception = SIGILL;
fdd6fa61
AG
415 break;
416 case 0x01: /* ldi.l (immediate) */
417 {
418 int reg = (inst >> 4) & 0xf;
419 TRACE("ldi.l");
5c27d164 420 unsigned int val = EXTRACT_WORD(pc+2);
fdd6fa61
AG
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 {
5c27d164 435 unsigned int fn = EXTRACT_WORD(pc+2);
fdd6fa61
AG
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;
5c27d164 443 wlat (scpu, opc, sp, pc + 6);
fdd6fa61
AG
444
445 /* Push the current frame pointer. */
446 sp -= 4;
5c27d164 447 wlat (scpu, opc, sp, cpu.asregs.regs[0]);
fdd6fa61
AG
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. */
5c27d164 462 cpu.asregs.regs[0] = rlat (scpu, opc, sp);
fdd6fa61
AG
463 sp += 4;
464
465 /* Pop the return address. */
5c27d164 466 pc = rlat (scpu, opc, sp) - 2;
fdd6fa61
AG
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");
5c27d164 492 wlat (scpu, opc, sp, cpu.asregs.regs[b]);
fdd6fa61
AG
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");
5c27d164 502 cpu.asregs.regs[b] = rlat (scpu, opc, sp);
fdd6fa61
AG
503 cpu.asregs.regs[a] = sp + 4;
504 }
505 break;
506 case 0x08: /* lda.l */
507 {
508 int reg = (inst >> 4) & 0xf;
5c27d164 509 unsigned int addr = EXTRACT_WORD(pc+2);
fdd6fa61 510 TRACE("lda.l");
5c27d164 511 cpu.asregs.regs[reg] = rlat (scpu, opc, addr);
fdd6fa61
AG
512 pc += 4;
513 }
514 break;
515 case 0x09: /* sta.l */
516 {
517 int reg = (inst >> 4) & 0xf;
5c27d164 518 unsigned int addr = EXTRACT_WORD(pc+2);
fdd6fa61 519 TRACE("sta.l");
5c27d164 520 wlat (scpu, opc, addr, cpu.asregs.regs[reg]);
fdd6fa61
AG
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];
5c27d164 531 cpu.asregs.regs[dest] = rlat (scpu, opc, xv);
fdd6fa61
AG
532 }
533 break;
534 case 0x0b: /* st.l */
535 {
536 int dest = (inst >> 4) & 0xf;
537 int val = inst & 0xf;
538 TRACE("st.l");
5c27d164 539 wlat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
fdd6fa61
AG
540 }
541 break;
542 case 0x0c: /* ldo.l */
543 {
5c27d164 544 unsigned int addr = EXTRACT_WORD(pc+2);
fdd6fa61
AG
545 int a = (inst >> 4) & 0xf;
546 int b = inst & 0xf;
547 TRACE("ldo.l");
548 addr += cpu.asregs.regs[b];
5c27d164 549 cpu.asregs.regs[a] = rlat (scpu, opc, addr);
fdd6fa61
AG
550 pc += 4;
551 }
552 break;
553 case 0x0d: /* sto.l */
554 {
5c27d164 555 unsigned int addr = EXTRACT_WORD(pc+2);
fdd6fa61
AG
556 int a = (inst >> 4) & 0xf;
557 int b = inst & 0xf;
558 TRACE("sto.l");
559 addr += cpu.asregs.regs[a];
5c27d164 560 wlat (scpu, opc, addr, cpu.asregs.regs[b]);
fdd6fa61
AG
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;
32d49b7b
AG
587 case 0x0f: /* nop */
588 break;
589 case 0x10: /* bad */
590 case 0x11: /* bad */
591 case 0x12: /* bad */
592 case 0x13: /* bad */
593 case 0x14: /* bad */
594 case 0x15: /* bad */
595 case 0x16: /* bad */
596 case 0x17: /* bad */
597 case 0x18: /* bad */
fdd6fa61 598 {
86566200
AG
599 opc = opcode;
600 TRACE("SIGILL0");
601 cpu.asregs.exception = SIGILL;
602 break;
fdd6fa61 603 }
fdd6fa61
AG
604 case 0x19: /* jsr */
605 {
606 unsigned int fn = cpu.asregs.regs[(inst >> 4) & 0xf];
607 unsigned int sp = cpu.asregs.regs[1];
608
609 TRACE("jsr");
610
611 /* Save a slot for the static chain. */
612 sp -= 4;
613
614 /* Push the return address. */
615 sp -= 4;
5c27d164 616 wlat (scpu, opc, sp, pc + 2);
fdd6fa61
AG
617
618 /* Push the current frame pointer. */
619 sp -= 4;
5c27d164 620 wlat (scpu, opc, sp, cpu.asregs.regs[0]);
fdd6fa61
AG
621
622 /* Uncache the stack pointer and set the fp & pc. */
623 cpu.asregs.regs[1] = sp;
624 cpu.asregs.regs[0] = sp;
625 pc = fn - 2;
626 }
627 break;
628 case 0x1a: /* jmpa */
629 {
5c27d164 630 unsigned int tgt = EXTRACT_WORD(pc+2);
fdd6fa61
AG
631 TRACE("jmpa");
632 pc = tgt - 2;
633 }
634 break;
635 case 0x1b: /* ldi.b (immediate) */
636 {
637 int reg = (inst >> 4) & 0xf;
638
5c27d164 639 unsigned int val = EXTRACT_WORD(pc+2);
fdd6fa61
AG
640 TRACE("ldi.b");
641 cpu.asregs.regs[reg] = val;
642 pc += 4;
643 }
644 break;
645 case 0x1c: /* ld.b (register indirect) */
646 {
647 int src = inst & 0xf;
648 int dest = (inst >> 4) & 0xf;
649 int xv;
650 TRACE("ld.b");
651 xv = cpu.asregs.regs[src];
5c27d164 652 cpu.asregs.regs[dest] = rbat (scpu, opc, xv);
fdd6fa61
AG
653 }
654 break;
655 case 0x1d: /* lda.b */
656 {
657 int reg = (inst >> 4) & 0xf;
5c27d164 658 unsigned int addr = EXTRACT_WORD(pc+2);
fdd6fa61 659 TRACE("lda.b");
5c27d164 660 cpu.asregs.regs[reg] = rbat (scpu, opc, addr);
fdd6fa61
AG
661 pc += 4;
662 }
663 break;
664 case 0x1e: /* st.b */
665 {
666 int dest = (inst >> 4) & 0xf;
667 int val = inst & 0xf;
668 TRACE("st.b");
5c27d164 669 wbat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
fdd6fa61
AG
670 }
671 break;
672 case 0x1f: /* sta.b */
673 {
674 int reg = (inst >> 4) & 0xf;
5c27d164 675 unsigned int addr = EXTRACT_WORD(pc+2);
fdd6fa61 676 TRACE("sta.b");
5c27d164 677 wbat (scpu, opc, addr, cpu.asregs.regs[reg]);
fdd6fa61
AG
678 pc += 4;
679 }
680 break;
681 case 0x20: /* ldi.s (immediate) */
682 {
683 int reg = (inst >> 4) & 0xf;
684
5c27d164 685 unsigned int val = EXTRACT_WORD(pc+2);
fdd6fa61
AG
686 TRACE("ldi.s");
687 cpu.asregs.regs[reg] = val;
688 pc += 4;
689 }
690 break;
691 case 0x21: /* ld.s (register indirect) */
692 {
693 int src = inst & 0xf;
694 int dest = (inst >> 4) & 0xf;
695 int xv;
696 TRACE("ld.s");
697 xv = cpu.asregs.regs[src];
5c27d164 698 cpu.asregs.regs[dest] = rsat (scpu, opc, xv);
fdd6fa61
AG
699 }
700 break;
701 case 0x22: /* lda.s */
702 {
703 int reg = (inst >> 4) & 0xf;
5c27d164 704 unsigned int addr = EXTRACT_WORD(pc+2);
fdd6fa61 705 TRACE("lda.s");
5c27d164 706 cpu.asregs.regs[reg] = rsat (scpu, opc, addr);
fdd6fa61
AG
707 pc += 4;
708 }
709 break;
710 case 0x23: /* st.s */
711 {
712 int dest = (inst >> 4) & 0xf;
713 int val = inst & 0xf;
714 TRACE("st.s");
5c27d164 715 wsat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
fdd6fa61
AG
716 }
717 break;
718 case 0x24: /* sta.s */
719 {
720 int reg = (inst >> 4) & 0xf;
5c27d164 721 unsigned int addr = EXTRACT_WORD(pc+2);
fdd6fa61 722 TRACE("sta.s");
5c27d164 723 wsat (scpu, opc, addr, cpu.asregs.regs[reg]);
fdd6fa61
AG
724 pc += 4;
725 }
726 break;
727 case 0x25: /* jmp */
728 {
729 int reg = (inst >> 4) & 0xf;
730 TRACE("jmp");
731 pc = cpu.asregs.regs[reg] - 2;
732 }
733 break;
734 case 0x26: /* and */
735 {
736 int a = (inst >> 4) & 0xf;
737 int b = inst & 0xf;
738 int av, bv;
739 TRACE("and");
740 av = cpu.asregs.regs[a];
741 bv = cpu.asregs.regs[b];
742 cpu.asregs.regs[a] = av & bv;
743 }
744 break;
745 case 0x27: /* lshr */
746 {
747 int a = (inst >> 4) & 0xf;
748 int b = inst & 0xf;
749 int av = cpu.asregs.regs[a];
750 int bv = cpu.asregs.regs[b];
751 TRACE("lshr");
752 cpu.asregs.regs[a] = (unsigned) ((unsigned) av >> bv);
753 }
754 break;
755 case 0x28: /* ashl */
756 {
757 int a = (inst >> 4) & 0xf;
758 int b = inst & 0xf;
759 int av = cpu.asregs.regs[a];
760 int bv = cpu.asregs.regs[b];
761 TRACE("ashl");
762 cpu.asregs.regs[a] = av << bv;
763 }
764 break;
765 case 0x29: /* sub.l */
766 {
767 int a = (inst >> 4) & 0xf;
768 int b = inst & 0xf;
769 unsigned av = cpu.asregs.regs[a];
770 unsigned bv = cpu.asregs.regs[b];
771 TRACE("sub.l");
772 cpu.asregs.regs[a] = av - bv;
773 }
774 break;
775 case 0x2a: /* neg */
776 {
777 int a = (inst >> 4) & 0xf;
778 int b = inst & 0xf;
779 int bv = cpu.asregs.regs[b];
780 TRACE("neg");
781 cpu.asregs.regs[a] = - bv;
782 }
783 break;
784 case 0x2b: /* or */
785 {
786 int a = (inst >> 4) & 0xf;
787 int b = inst & 0xf;
788 int av, bv;
789 TRACE("or");
790 av = cpu.asregs.regs[a];
791 bv = cpu.asregs.regs[b];
792 cpu.asregs.regs[a] = av | bv;
793 }
794 break;
795 case 0x2c: /* not */
796 {
797 int a = (inst >> 4) & 0xf;
798 int b = inst & 0xf;
799 int bv = cpu.asregs.regs[b];
800 TRACE("not");
801 cpu.asregs.regs[a] = 0xffffffff ^ bv;
802 }
803 break;
804 case 0x2d: /* ashr */
805 {
806 int a = (inst >> 4) & 0xf;
807 int b = inst & 0xf;
808 int av = cpu.asregs.regs[a];
809 int bv = cpu.asregs.regs[b];
810 TRACE("ashr");
811 cpu.asregs.regs[a] = av >> bv;
812 }
813 break;
814 case 0x2e: /* xor */
815 {
816 int a = (inst >> 4) & 0xf;
817 int b = inst & 0xf;
818 int av, bv;
819 TRACE("xor");
820 av = cpu.asregs.regs[a];
821 bv = cpu.asregs.regs[b];
822 cpu.asregs.regs[a] = av ^ bv;
823 }
824 break;
825 case 0x2f: /* mul.l */
826 {
827 int a = (inst >> 4) & 0xf;
828 int b = inst & 0xf;
829 unsigned av = cpu.asregs.regs[a];
830 unsigned bv = cpu.asregs.regs[b];
831 TRACE("mul.l");
832 cpu.asregs.regs[a] = av * bv;
833 }
834 break;
835 case 0x30: /* swi */
836 {
5c27d164 837 unsigned int inum = EXTRACT_WORD(pc+2);
fdd6fa61 838 TRACE("swi");
5c27d164
AG
839 /* Set the special registers appropriately. */
840 cpu.asregs.sregs[2] = 3; /* MOXIE_EX_SWI */
841 cpu.asregs.sregs[3] = inum;
fdd6fa61
AG
842 switch (inum)
843 {
844 case 0x1: /* SYS_exit */
845 {
846 cpu.asregs.exception = SIGQUIT;
847 break;
848 }
849 case 0x2: /* SYS_open */
850 {
5c27d164 851 char fname[1024];
fdd6fa61 852 int mode = (int) convert_target_flags ((unsigned) cpu.asregs.regs[3]);
7a321525 853 int perm = (int) cpu.asregs.regs[4];
fdd6fa61 854 int fd = open (fname, mode, perm);
5c27d164
AG
855 sim_core_read_buffer (sd, scpu, read_map, fname,
856 cpu.asregs.regs[2], 1024);
fdd6fa61
AG
857 /* FIXME - set errno */
858 cpu.asregs.regs[2] = fd;
859 break;
860 }
861 case 0x4: /* SYS_read */
862 {
863 int fd = cpu.asregs.regs[2];
7a321525 864 unsigned len = (unsigned) cpu.asregs.regs[4];
5c27d164 865 char *buf = malloc (len);
fdd6fa61 866 cpu.asregs.regs[2] = read (fd, buf, len);
5c27d164
AG
867 sim_core_write_buffer (sd, scpu, write_map, buf,
868 cpu.asregs.regs[3], len);
869 free (buf);
fdd6fa61
AG
870 break;
871 }
872 case 0x5: /* SYS_write */
873 {
5c27d164 874 char *str;
fdd6fa61 875 /* String length is at 0x12($fp) */
7a321525 876 unsigned count, len = (unsigned) cpu.asregs.regs[4];
5c27d164
AG
877 str = malloc (len);
878 sim_core_read_buffer (sd, scpu, read_map, str,
879 cpu.asregs.regs[3], len);
fdd6fa61 880 count = write (cpu.asregs.regs[2], str, len);
5c27d164 881 free (str);
fdd6fa61
AG
882 cpu.asregs.regs[2] = count;
883 break;
884 }
7a321525
AG
885 case 0xffffffff: /* Linux System Call */
886 {
887 unsigned int handler = cpu.asregs.sregs[1];
888 unsigned int sp = cpu.asregs.regs[1];
7a321525
AG
889
890 /* Save a slot for the static chain. */
891 sp -= 4;
892
893 /* Push the return address. */
894 sp -= 4;
5c27d164 895 wlat (scpu, opc, sp, pc + 6);
7a321525
AG
896
897 /* Push the current frame pointer. */
898 sp -= 4;
5c27d164 899 wlat (scpu, opc, sp, cpu.asregs.regs[0]);
7a321525
AG
900
901 /* Uncache the stack pointer and set the fp & pc. */
902 cpu.asregs.regs[1] = sp;
903 cpu.asregs.regs[0] = sp;
904 pc = handler - 6;
905 }
fdd6fa61
AG
906 default:
907 break;
908 }
909 pc += 4;
910 }
911 break;
912 case 0x31: /* div.l */
913 {
914 int a = (inst >> 4) & 0xf;
915 int b = inst & 0xf;
916 int av = cpu.asregs.regs[a];
917 int bv = cpu.asregs.regs[b];
918 TRACE("div.l");
919 cpu.asregs.regs[a] = av / bv;
920 }
921 break;
922 case 0x32: /* udiv.l */
923 {
924 int a = (inst >> 4) & 0xf;
925 int b = inst & 0xf;
926 unsigned int av = cpu.asregs.regs[a];
927 unsigned int bv = cpu.asregs.regs[b];
928 TRACE("udiv.l");
929 cpu.asregs.regs[a] = (av / bv);
930 }
931 break;
932 case 0x33: /* mod.l */
933 {
934 int a = (inst >> 4) & 0xf;
935 int b = inst & 0xf;
936 int av = cpu.asregs.regs[a];
937 int bv = cpu.asregs.regs[b];
938 TRACE("mod.l");
939 cpu.asregs.regs[a] = av % bv;
940 }
941 break;
942 case 0x34: /* umod.l */
943 {
944 int a = (inst >> 4) & 0xf;
945 int b = inst & 0xf;
946 unsigned int av = cpu.asregs.regs[a];
947 unsigned int bv = cpu.asregs.regs[b];
948 TRACE("umod.l");
949 cpu.asregs.regs[a] = (av % bv);
950 }
951 break;
952 case 0x35: /* brk */
953 TRACE("brk");
954 cpu.asregs.exception = SIGTRAP;
955 pc -= 2; /* Adjust pc */
956 break;
957 case 0x36: /* ldo.b */
958 {
5c27d164 959 unsigned int addr = EXTRACT_WORD(pc+2);
fdd6fa61
AG
960 int a = (inst >> 4) & 0xf;
961 int b = inst & 0xf;
962 TRACE("ldo.b");
963 addr += cpu.asregs.regs[b];
5c27d164 964 cpu.asregs.regs[a] = rbat (scpu, opc, addr);
fdd6fa61
AG
965 pc += 4;
966 }
967 break;
968 case 0x37: /* sto.b */
969 {
5c27d164 970 unsigned int addr = EXTRACT_WORD(pc+2);
fdd6fa61
AG
971 int a = (inst >> 4) & 0xf;
972 int b = inst & 0xf;
973 TRACE("sto.b");
974 addr += cpu.asregs.regs[a];
5c27d164 975 wbat (scpu, opc, addr, cpu.asregs.regs[b]);
fdd6fa61
AG
976 pc += 4;
977 }
978 break;
979 case 0x38: /* ldo.s */
980 {
5c27d164 981 unsigned int addr = EXTRACT_WORD(pc+2);
fdd6fa61
AG
982 int a = (inst >> 4) & 0xf;
983 int b = inst & 0xf;
984 TRACE("ldo.s");
985 addr += cpu.asregs.regs[b];
5c27d164 986 cpu.asregs.regs[a] = rsat (scpu, opc, addr);
fdd6fa61
AG
987 pc += 4;
988 }
989 break;
990 case 0x39: /* sto.s */
991 {
5c27d164 992 unsigned int addr = EXTRACT_WORD(pc+2);
fdd6fa61
AG
993 int a = (inst >> 4) & 0xf;
994 int b = inst & 0xf;
995 TRACE("sto.s");
996 addr += cpu.asregs.regs[a];
5c27d164 997 wsat (scpu, opc, addr, cpu.asregs.regs[b]);
fdd6fa61
AG
998 pc += 4;
999 }
1000 break;
1001 default:
1002 opc = opcode;
1003 TRACE("SIGILL1");
1004 cpu.asregs.exception = SIGILL;
1005 break;
1006 }
1007 }
1008
1009 insts++;
1010 pc += 2;
1011
1012 } while (!cpu.asregs.exception);
1013
1014 /* Hide away the things we've cached while executing. */
1015 cpu.asregs.regs[PC_REGNO] = pc;
1016 cpu.asregs.insts += insts; /* instructions done ... */
fdd6fa61
AG
1017}
1018
1019int
1020sim_write (sd, addr, buffer, size)
1021 SIM_DESC sd;
1022 SIM_ADDR addr;
5558e7e6 1023 const unsigned char * buffer;
fdd6fa61
AG
1024 int size;
1025{
5c27d164
AG
1026 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1027
1028 sim_core_write_buffer (sd, scpu, write_map, buffer, addr, size);
1029
fdd6fa61
AG
1030 return size;
1031}
1032
1033int
1034sim_read (sd, addr, buffer, size)
1035 SIM_DESC sd;
1036 SIM_ADDR addr;
1037 unsigned char * buffer;
1038 int size;
1039{
5c27d164
AG
1040 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1041
1042 sim_core_read_buffer (sd, scpu, read_map, buffer, addr, size);
fdd6fa61
AG
1043
1044 return size;
1045}
1046
1047
1048int
1049sim_store_register (sd, rn, memory, length)
1050 SIM_DESC sd;
1051 int rn;
1052 unsigned char * memory;
1053 int length;
1054{
fdd6fa61
AG
1055 if (rn < NUM_MOXIE_REGS && rn >= 0)
1056 {
1057 if (length == 4)
1058 {
1059 long ival;
1060
1061 /* misalignment safe */
1062 ival = moxie_extract_unsigned_integer (memory, 4);
1063 cpu.asints[rn] = ival;
1064 }
1065
1066 return 4;
1067 }
1068 else
1069 return 0;
1070}
1071
1072int
1073sim_fetch_register (sd, rn, memory, length)
1074 SIM_DESC sd;
1075 int rn;
1076 unsigned char * memory;
1077 int length;
1078{
fdd6fa61
AG
1079 if (rn < NUM_MOXIE_REGS && rn >= 0)
1080 {
1081 if (length == 4)
1082 {
1083 long ival = cpu.asints[rn];
1084
1085 /* misalignment-safe */
1086 moxie_store_unsigned_integer (memory, 4, ival);
1087 }
1088
1089 return 4;
1090 }
1091 else
1092 return 0;
1093}
1094
1095
1096int
1097sim_trace (sd)
1098 SIM_DESC sd;
1099{
1100 if (tracefile == 0)
1101 tracefile = fopen("trace.csv", "wb");
1102
1103 tracing = 1;
1104
1105 sim_resume (sd, 0, 0);
1106
1107 tracing = 0;
1108
1109 return 1;
1110}
1111
1112void
1113sim_stop_reason (sd, reason, sigrc)
1114 SIM_DESC sd;
1115 enum sim_stop * reason;
1116 int * sigrc;
1117{
1118 if (cpu.asregs.exception == SIGQUIT)
1119 {
1120 * reason = sim_exited;
1121 * sigrc = cpu.asregs.regs[2];
1122 }
1123 else
1124 {
1125 * reason = sim_stopped;
1126 * sigrc = cpu.asregs.exception;
1127 }
1128}
1129
1130
1131int
1132sim_stop (sd)
1133 SIM_DESC sd;
1134{
1135 cpu.asregs.exception = SIGINT;
1136 return 1;
1137}
1138
1139
1140void
1141sim_info (sd, verbose)
1142 SIM_DESC sd;
1143 int verbose;
1144{
1145 callback->printf_filtered (callback, "\n\n# instructions executed %llu\n",
1146 cpu.asregs.insts);
1147}
1148
1149
1150SIM_DESC
1151sim_open (kind, cb, abfd, argv)
1152 SIM_OPEN_KIND kind;
1153 host_callback * cb;
1154 struct bfd * abfd;
1155 char ** argv;
1156{
5c27d164 1157 SIM_DESC sd = sim_state_alloc (kind, cb);
5c27d164
AG
1158 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
1159
1160 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
1161 return 0;
1162
1163 sim_do_command(sd," memory region 0x00000000,0x4000000") ;
1164 sim_do_command(sd," memory region 0xE0000000,0x10000") ;
1165
fdd6fa61
AG
1166 myname = argv[0];
1167 callback = cb;
1168
1169 if (kind == SIM_OPEN_STANDALONE)
1170 issue_messages = 1;
1171
fdd6fa61
AG
1172 set_initial_gprs (); /* Reset the GPR registers. */
1173
b8dcd182 1174 /* Configure/verify the target byte order and other runtime
11db68fd 1175 configuration options. */
b8dcd182
AG
1176 if (sim_config (sd) != SIM_RC_OK)
1177 {
1178 sim_module_uninstall (sd);
1179 return 0;
1180 }
1181
1182 if (sim_post_argv_init (sd) != SIM_RC_OK)
1183 {
1184 /* Uninstall the modules to avoid memory leaks,
1185 file descriptor leaks, etc. */
1186 sim_module_uninstall (sd);
1187 return 0;
1188 }
1189
5c27d164 1190 return sd;
fdd6fa61
AG
1191}
1192
1193void
1194sim_close (sd, quitting)
1195 SIM_DESC sd;
1196 int quitting;
1197{
1198 /* nothing to do */
1199}
1200
5c27d164
AG
1201
1202/* Load the device tree blob. */
1203
1204static void
1205load_dtb (SIM_DESC sd, const char *filename)
1206{
1207 int size = 0;
1208 FILE *f = fopen (filename, "rb");
1209 char *buf;
1210 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1211 if (f == NULL)
1212 {
1213 printf ("WARNING: ``%s'' could not be opened.\n", filename);
1214 return;
1215 }
1216 fseek (f, 0, SEEK_END);
1217 size = ftell(f);
1218 fseek (f, 0, SEEK_SET);
1219 buf = alloca (size);
1220 if (size != fread (buf, 1, size, f))
1221 {
1222 printf ("ERROR: error reading ``%s''.\n", filename);
1223 return;
1224 }
1225 sim_core_write_buffer (sd, scpu, write_map, buf, 0xE0000000, size);
1226 cpu.asregs.sregs[9] = 0xE0000000;
1227 fclose (f);
1228}
1229
fdd6fa61
AG
1230SIM_RC
1231sim_load (sd, prog, abfd, from_tty)
1232 SIM_DESC sd;
b2b255bd 1233 const char * prog;
fdd6fa61
AG
1234 bfd * abfd;
1235 int from_tty;
1236{
1237
1238 /* Do the right thing for ELF executables; this turns out to be
1239 just about the right thing for any object format that:
1240 - we crack using BFD routines
1241 - follows the traditional UNIX text/data/bss layout
1242 - calls the bss section ".bss". */
1243
1244 extern bfd * sim_load_file (); /* ??? Don't know where this should live. */
1245 bfd * prog_bfd;
1246
1247 {
1248 bfd * handle;
1249 handle = bfd_openr (prog, 0); /* could be "moxie" */
1250
1251 if (!handle)
1252 {
1253 printf("``%s'' could not be opened.\n", prog);
1254 return SIM_RC_FAIL;
1255 }
1256
1257 /* Makes sure that we have an object file, also cleans gets the
1258 section headers in place. */
1259 if (!bfd_check_format (handle, bfd_object))
1260 {
1261 /* wasn't an object file */
1262 bfd_close (handle);
1263 printf ("``%s'' is not appropriate object file.\n", prog);
1264 return SIM_RC_FAIL;
1265 }
1266
1267 /* Clean up after ourselves. */
1268 bfd_close (handle);
1269 }
1270
1271 /* from sh -- dac */
1272 prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
1273 sim_kind == SIM_OPEN_DEBUG,
1274 0, sim_write);
1275 if (prog_bfd == NULL)
1276 return SIM_RC_FAIL;
1277
1278 if (abfd == NULL)
1279 bfd_close (prog_bfd);
1280
1281 return SIM_RC_OK;
1282}
1283
1284SIM_RC
1285sim_create_inferior (sd, prog_bfd, argv, env)
1286 SIM_DESC sd;
1287 struct bfd * prog_bfd;
1288 char ** argv;
1289 char ** env;
1290{
1291 char ** avp;
1292 int l, argc, i, tp;
5c27d164 1293 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
fdd6fa61
AG
1294
1295 /* Set the initial register set. */
1296 l = issue_messages;
1297 issue_messages = 0;
1298 set_initial_gprs ();
1299 issue_messages = l;
1300
bc56c8fa
JK
1301 if (prog_bfd != NULL)
1302 cpu.asregs.regs[PC_REGNO] = bfd_get_start_address (prog_bfd);
fdd6fa61
AG
1303
1304 /* Copy args into target memory. */
1305 avp = argv;
bc56c8fa 1306 for (argc = 0; avp && *avp; avp++)
fdd6fa61
AG
1307 argc++;
1308
1309 /* Target memory looks like this:
1310 0x00000000 zero word
1311 0x00000004 argc word
1312 0x00000008 start of argv
1313 .
1314 0x0000???? end of argv
1315 0x0000???? zero word
1316 0x0000???? start of data pointed to by argv */
1317
5c27d164
AG
1318 wlat (scpu, 0, 0, 0);
1319 wlat (scpu, 0, 4, argc);
fdd6fa61
AG
1320
1321 /* tp is the offset of our first argv data. */
1322 tp = 4 + 4 + argc * 4 + 4;
1323
1324 for (i = 0; i < argc; i++)
1325 {
1326 /* Set the argv value. */
5c27d164 1327 wlat (scpu, 0, 4 + 4 + i * 4, tp);
fdd6fa61
AG
1328
1329 /* Store the string. */
5c27d164
AG
1330 sim_core_write_buffer (sd, scpu, write_map, argv[i],
1331 tp, strlen(argv[i])+1);
fdd6fa61
AG
1332 tp += strlen (argv[i]) + 1;
1333 }
1334
5c27d164
AG
1335 wlat (scpu, 0, 4 + 4 + i * 4, 0);
1336
1337 load_dtb (sd, DTB);
fdd6fa61
AG
1338
1339 return SIM_RC_OK;
1340}
1341
1342void
1343sim_kill (sd)
1344 SIM_DESC sd;
1345{
1346 if (tracefile)
1347 fclose(tracefile);
1348}
1349
1350void
1351sim_do_command (sd, cmd)
1352 SIM_DESC sd;
60d847df 1353 const char *cmd;
fdd6fa61 1354{
5c27d164
AG
1355 if (sim_args_command (sd, cmd) != SIM_RC_OK)
1356 sim_io_printf (sd,
1357 "Error: \"%s\" is not a valid moxie simulator command.\n",
fdd6fa61 1358 cmd);
fdd6fa61
AG
1359}
1360
1361void
1362sim_set_callbacks (ptr)
1363 host_callback * ptr;
1364{
1365 callback = ptr;
1366}
This page took 0.392113 seconds and 4 git commands to generate.