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