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