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