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