]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/moxie/interp.c
sim: mn10300: add a basic testsuite
[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 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 */
117 int exception;
fdd6fa61
AG
118 unsigned long long insts; /* instruction counter */
119};
120
121#define CC_GT 1<<0
122#define CC_LT 1<<1
123#define CC_EQ 1<<2
124#define CC_GTU 1<<3
125#define CC_LTU 1<<4
126
cc8ab1de 127/* TODO: This should be moved to sim-main.h:_sim_cpu. */
fdd6fa61
AG
128union
129{
130 struct moxie_regset asregs;
131 word asints [1]; /* but accessed larger... */
132} cpu;
133
fdd6fa61 134static void
cc8ab1de 135set_initial_gprs (void)
fdd6fa61
AG
136{
137 int i;
138 long space;
fdd6fa61 139
fdd6fa61
AG
140 /* Set up machine just out of reset. */
141 cpu.asregs.regs[PC_REGNO] = 0;
142
fdd6fa61
AG
143 /* Clean out the register contents. */
144 for (i = 0; i < NUM_MOXIE_REGS; i++)
145 cpu.asregs.regs[i] = 0;
146 for (i = 0; i < NUM_MOXIE_SREGS; i++)
147 cpu.asregs.sregs[i] = 0;
148}
149
fdd6fa61
AG
150/* Write a 1 byte value to memory. */
151
1bf57e9a 152static INLINE void
5c27d164 153wbat (sim_cpu *scpu, word pc, word x, word v)
fdd6fa61 154{
5c27d164
AG
155 address_word cia = CIA_GET (scpu);
156
157 sim_core_write_aligned_1 (scpu, cia, write_map, x, v);
fdd6fa61
AG
158}
159
160/* Write a 2 byte value to memory. */
161
1bf57e9a 162static INLINE void
5c27d164 163wsat (sim_cpu *scpu, word pc, word x, word v)
fdd6fa61 164{
5c27d164
AG
165 address_word cia = CIA_GET (scpu);
166
167 sim_core_write_aligned_2 (scpu, cia, write_map, x, v);
fdd6fa61
AG
168}
169
170/* Write a 4 byte value to memory. */
171
1bf57e9a 172static INLINE void
5c27d164 173wlat (sim_cpu *scpu, word pc, word x, word v)
fdd6fa61 174{
5c27d164
AG
175 address_word cia = CIA_GET (scpu);
176
177 sim_core_write_aligned_4 (scpu, cia, write_map, x, v);
fdd6fa61
AG
178}
179
180/* Read 2 bytes from memory. */
181
1bf57e9a 182static INLINE int
5c27d164 183rsat (sim_cpu *scpu, word pc, word x)
fdd6fa61 184{
5c27d164
AG
185 address_word cia = CIA_GET (scpu);
186
187 return (sim_core_read_aligned_2 (scpu, cia, read_map, x));
fdd6fa61
AG
188}
189
190/* Read 1 byte from memory. */
191
1bf57e9a 192static INLINE int
5c27d164 193rbat (sim_cpu *scpu, word pc, word x)
fdd6fa61 194{
5c27d164
AG
195 address_word cia = CIA_GET (scpu);
196
197 return (sim_core_read_aligned_1 (scpu, cia, read_map, x));
fdd6fa61
AG
198}
199
200/* Read 4 bytes from memory. */
201
1bf57e9a 202static INLINE int
5c27d164 203rlat (sim_cpu *scpu, word pc, word x)
fdd6fa61 204{
5c27d164
AG
205 address_word cia = CIA_GET (scpu);
206
207 return (sim_core_read_aligned_4 (scpu, cia, read_map, x));
fdd6fa61
AG
208}
209
210#define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; }
211
1bf57e9a 212static unsigned int
fdd6fa61
AG
213convert_target_flags (unsigned int tflags)
214{
215 unsigned int hflags = 0x0;
216
217 CHECK_FLAG(0x0001, O_WRONLY);
218 CHECK_FLAG(0x0002, O_RDWR);
219 CHECK_FLAG(0x0008, O_APPEND);
220 CHECK_FLAG(0x0200, O_CREAT);
221 CHECK_FLAG(0x0400, O_TRUNC);
222 CHECK_FLAG(0x0800, O_EXCL);
223 CHECK_FLAG(0x2000, O_SYNC);
224
225 if (tflags != 0x0)
226 fprintf (stderr,
227 "Simulator Error: problem converting target open flags for host. 0x%x\n",
228 tflags);
229
230 return hflags;
231}
232
cc8ab1de
MF
233/* TODO: Move to sim-trace.h. */
234static FILE *tracefile;
235static const int tracing = 0;
fdd6fa61
AG
236#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]);
237
fdd6fa61 238void
1bf57e9a 239sim_resume (SIM_DESC sd, int step, int siggnal)
fdd6fa61
AG
240{
241 word pc, opc;
242 unsigned long long insts;
243 unsigned short inst;
5c27d164
AG
244 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
245 address_word cia = CIA_GET (scpu);
fdd6fa61 246
fdd6fa61
AG
247 cpu.asregs.exception = step ? SIGTRAP: 0;
248 pc = cpu.asregs.regs[PC_REGNO];
249 insts = cpu.asregs.insts;
fdd6fa61
AG
250
251 /* Run instructions here. */
252 do
253 {
254 opc = pc;
255
256 /* Fetch the instruction at pc. */
5c27d164
AG
257 inst = (sim_core_read_aligned_1 (scpu, cia, read_map, pc) << 8)
258 + sim_core_read_aligned_1 (scpu, cia, read_map, pc+1);
fdd6fa61
AG
259
260 /* Decode instruction. */
261 if (inst & (1 << 15))
262 {
263 if (inst & (1 << 14))
264 {
265 /* This is a Form 3 instruction. */
86566200
AG
266 int opcode = (inst >> 10 & 0xf);
267
268 switch (opcode)
269 {
270 case 0x00: /* beq */
271 {
272 TRACE("beq");
273 if (cpu.asregs.cc & CC_EQ)
78ca4e81 274 pc += INST2OFFSET(inst);
86566200
AG
275 }
276 break;
277 case 0x01: /* bne */
278 {
279 TRACE("bne");
280 if (! (cpu.asregs.cc & CC_EQ))
78ca4e81 281 pc += INST2OFFSET(inst);
86566200
AG
282 }
283 break;
284 case 0x02: /* blt */
285 {
286 TRACE("blt");
287 if (cpu.asregs.cc & CC_LT)
78ca4e81 288 pc += INST2OFFSET(inst);
86566200
AG
289 } break;
290 case 0x03: /* bgt */
291 {
292 TRACE("bgt");
293 if (cpu.asregs.cc & CC_GT)
78ca4e81 294 pc += INST2OFFSET(inst);
86566200
AG
295 }
296 break;
297 case 0x04: /* bltu */
298 {
299 TRACE("bltu");
300 if (cpu.asregs.cc & CC_LTU)
78ca4e81 301 pc += INST2OFFSET(inst);
86566200
AG
302 }
303 break;
304 case 0x05: /* bgtu */
305 {
306 TRACE("bgtu");
307 if (cpu.asregs.cc & CC_GTU)
78ca4e81 308 pc += INST2OFFSET(inst);
86566200
AG
309 }
310 break;
311 case 0x06: /* bge */
312 {
313 TRACE("bge");
314 if (cpu.asregs.cc & (CC_GT | CC_EQ))
78ca4e81 315 pc += INST2OFFSET(inst);
86566200
AG
316 }
317 break;
318 case 0x07: /* ble */
319 {
320 TRACE("ble");
321 if (cpu.asregs.cc & (CC_LT | CC_EQ))
78ca4e81 322 pc += INST2OFFSET(inst);
86566200
AG
323 }
324 break;
325 case 0x08: /* bgeu */
326 {
327 TRACE("bgeu");
328 if (cpu.asregs.cc & (CC_GTU | CC_EQ))
78ca4e81 329 pc += INST2OFFSET(inst);
86566200
AG
330 }
331 break;
332 case 0x09: /* bleu */
333 {
334 TRACE("bleu");
335 if (cpu.asregs.cc & (CC_LTU | CC_EQ))
78ca4e81 336 pc += INST2OFFSET(inst);
86566200
AG
337 }
338 break;
339 default:
340 {
341 TRACE("SIGILL3");
342 cpu.asregs.exception = SIGILL;
343 break;
344 }
345 }
fdd6fa61
AG
346 }
347 else
348 {
349 /* This is a Form 2 instruction. */
350 int opcode = (inst >> 12 & 0x3);
351 switch (opcode)
352 {
353 case 0x00: /* inc */
354 {
355 int a = (inst >> 8) & 0xf;
356 unsigned av = cpu.asregs.regs[a];
357 unsigned v = (inst & 0xff);
3ba611c3 358
fdd6fa61
AG
359 TRACE("inc");
360 cpu.asregs.regs[a] = av + v;
361 }
362 break;
363 case 0x01: /* dec */
364 {
365 int a = (inst >> 8) & 0xf;
366 unsigned av = cpu.asregs.regs[a];
367 unsigned v = (inst & 0xff);
3ba611c3 368
fdd6fa61
AG
369 TRACE("dec");
370 cpu.asregs.regs[a] = av - v;
371 }
372 break;
373 case 0x02: /* gsr */
374 {
375 int a = (inst >> 8) & 0xf;
376 unsigned v = (inst & 0xff);
3ba611c3 377
fdd6fa61
AG
378 TRACE("gsr");
379 cpu.asregs.regs[a] = cpu.asregs.sregs[v];
380 }
77176dfc 381 break;
fdd6fa61
AG
382 case 0x03: /* ssr */
383 {
384 int a = (inst >> 8) & 0xf;
385 unsigned v = (inst & 0xff);
3ba611c3 386
fdd6fa61
AG
387 TRACE("ssr");
388 cpu.asregs.sregs[v] = cpu.asregs.regs[a];
389 }
77176dfc 390 break;
fdd6fa61
AG
391 default:
392 TRACE("SIGILL2");
393 cpu.asregs.exception = SIGILL;
394 break;
395 }
396 }
397 }
398 else
399 {
400 /* This is a Form 1 instruction. */
401 int opcode = inst >> 8;
402 switch (opcode)
403 {
32d49b7b
AG
404 case 0x00: /* bad */
405 opc = opcode;
406 TRACE("SIGILL0");
407 cpu.asregs.exception = SIGILL;
fdd6fa61
AG
408 break;
409 case 0x01: /* ldi.l (immediate) */
410 {
411 int reg = (inst >> 4) & 0xf;
1bf57e9a 412 unsigned int val = EXTRACT_WORD(pc+2);
3ba611c3 413
fdd6fa61 414 TRACE("ldi.l");
fdd6fa61
AG
415 cpu.asregs.regs[reg] = val;
416 pc += 4;
417 }
418 break;
419 case 0x02: /* mov (register-to-register) */
420 {
421 int dest = (inst >> 4) & 0xf;
422 int src = (inst ) & 0xf;
3ba611c3 423
fdd6fa61
AG
424 TRACE("mov");
425 cpu.asregs.regs[dest] = cpu.asregs.regs[src];
426 }
427 break;
428 case 0x03: /* jsra */
429 {
5c27d164 430 unsigned int fn = EXTRACT_WORD(pc+2);
fdd6fa61 431 unsigned int sp = cpu.asregs.regs[1];
3ba611c3 432
fdd6fa61
AG
433 TRACE("jsra");
434 /* Save a slot for the static chain. */
435 sp -= 4;
436
437 /* Push the return address. */
438 sp -= 4;
5c27d164 439 wlat (scpu, opc, sp, pc + 6);
fdd6fa61
AG
440
441 /* Push the current frame pointer. */
442 sp -= 4;
5c27d164 443 wlat (scpu, opc, sp, cpu.asregs.regs[0]);
fdd6fa61
AG
444
445 /* Uncache the stack pointer and set the pc and $fp. */
446 cpu.asregs.regs[1] = sp;
447 cpu.asregs.regs[0] = sp;
448 pc = fn - 2;
449 }
450 break;
451 case 0x04: /* ret */
452 {
453 unsigned int sp = cpu.asregs.regs[0];
454
455 TRACE("ret");
456
457 /* Pop the frame pointer. */
5c27d164 458 cpu.asregs.regs[0] = rlat (scpu, opc, sp);
fdd6fa61
AG
459 sp += 4;
460
461 /* Pop the return address. */
5c27d164 462 pc = rlat (scpu, opc, sp) - 2;
fdd6fa61
AG
463 sp += 4;
464
465 /* Skip over the static chain slot. */
466 sp += 4;
467
468 /* Uncache the stack pointer. */
469 cpu.asregs.regs[1] = sp;
470 }
471 break;
472 case 0x05: /* add.l */
473 {
474 int a = (inst >> 4) & 0xf;
475 int b = inst & 0xf;
476 unsigned av = cpu.asregs.regs[a];
477 unsigned bv = cpu.asregs.regs[b];
3ba611c3 478
fdd6fa61
AG
479 TRACE("add.l");
480 cpu.asregs.regs[a] = av + bv;
481 }
482 break;
483 case 0x06: /* push */
484 {
485 int a = (inst >> 4) & 0xf;
486 int b = inst & 0xf;
487 int sp = cpu.asregs.regs[a] - 4;
3ba611c3 488
fdd6fa61 489 TRACE("push");
5c27d164 490 wlat (scpu, opc, sp, cpu.asregs.regs[b]);
fdd6fa61
AG
491 cpu.asregs.regs[a] = sp;
492 }
493 break;
494 case 0x07: /* pop */
495 {
496 int a = (inst >> 4) & 0xf;
497 int b = inst & 0xf;
498 int sp = cpu.asregs.regs[a];
3ba611c3 499
fdd6fa61 500 TRACE("pop");
5c27d164 501 cpu.asregs.regs[b] = rlat (scpu, opc, sp);
fdd6fa61
AG
502 cpu.asregs.regs[a] = sp + 4;
503 }
504 break;
505 case 0x08: /* lda.l */
506 {
507 int reg = (inst >> 4) & 0xf;
5c27d164 508 unsigned int addr = EXTRACT_WORD(pc+2);
3ba611c3 509
fdd6fa61 510 TRACE("lda.l");
5c27d164 511 cpu.asregs.regs[reg] = rlat (scpu, opc, addr);
fdd6fa61
AG
512 pc += 4;
513 }
514 break;
515 case 0x09: /* sta.l */
516 {
517 int reg = (inst >> 4) & 0xf;
5c27d164 518 unsigned int addr = EXTRACT_WORD(pc+2);
3ba611c3 519
fdd6fa61 520 TRACE("sta.l");
5c27d164 521 wlat (scpu, opc, addr, cpu.asregs.regs[reg]);
fdd6fa61
AG
522 pc += 4;
523 }
524 break;
525 case 0x0a: /* ld.l (register indirect) */
526 {
527 int src = inst & 0xf;
528 int dest = (inst >> 4) & 0xf;
529 int xv;
3ba611c3 530
fdd6fa61
AG
531 TRACE("ld.l");
532 xv = cpu.asregs.regs[src];
5c27d164 533 cpu.asregs.regs[dest] = rlat (scpu, opc, xv);
fdd6fa61
AG
534 }
535 break;
536 case 0x0b: /* st.l */
537 {
538 int dest = (inst >> 4) & 0xf;
539 int val = inst & 0xf;
3ba611c3 540
fdd6fa61 541 TRACE("st.l");
5c27d164 542 wlat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
fdd6fa61
AG
543 }
544 break;
545 case 0x0c: /* ldo.l */
546 {
507411cc 547 unsigned int addr = EXTRACT_OFFSET(pc+2);
fdd6fa61
AG
548 int a = (inst >> 4) & 0xf;
549 int b = inst & 0xf;
3ba611c3 550
fdd6fa61
AG
551 TRACE("ldo.l");
552 addr += cpu.asregs.regs[b];
5c27d164 553 cpu.asregs.regs[a] = rlat (scpu, opc, addr);
507411cc 554 pc += 2;
fdd6fa61
AG
555 }
556 break;
557 case 0x0d: /* sto.l */
558 {
507411cc 559 unsigned int addr = EXTRACT_OFFSET(pc+2);
fdd6fa61
AG
560 int a = (inst >> 4) & 0xf;
561 int b = inst & 0xf;
3ba611c3 562
fdd6fa61
AG
563 TRACE("sto.l");
564 addr += cpu.asregs.regs[a];
5c27d164 565 wlat (scpu, opc, addr, cpu.asregs.regs[b]);
507411cc 566 pc += 2;
fdd6fa61
AG
567 }
568 break;
569 case 0x0e: /* cmp */
570 {
571 int a = (inst >> 4) & 0xf;
572 int b = inst & 0xf;
573 int cc = 0;
574 int va = cpu.asregs.regs[a];
575 int vb = cpu.asregs.regs[b];
576
577 TRACE("cmp");
fdd6fa61
AG
578 if (va == vb)
579 cc = CC_EQ;
580 else
581 {
582 cc |= (va < vb ? CC_LT : 0);
583 cc |= (va > vb ? CC_GT : 0);
584 cc |= ((unsigned int) va < (unsigned int) vb ? CC_LTU : 0);
585 cc |= ((unsigned int) va > (unsigned int) vb ? CC_GTU : 0);
586 }
587
588 cpu.asregs.cc = cc;
589 }
590 break;
32d49b7b
AG
591 case 0x0f: /* nop */
592 break;
048ea174
AG
593 case 0x10: /* sex.b */
594 {
595 int a = (inst >> 4) & 0xf;
596 int b = inst & 0xf;
597 signed char bv = cpu.asregs.regs[b];
3ba611c3 598
048ea174
AG
599 TRACE("sex.b");
600 cpu.asregs.regs[a] = (int) bv;
601 }
602 break;
603 case 0x11: /* sex.s */
604 {
605 int a = (inst >> 4) & 0xf;
606 int b = inst & 0xf;
607 signed short bv = cpu.asregs.regs[b];
3ba611c3 608
048ea174
AG
609 TRACE("sex.s");
610 cpu.asregs.regs[a] = (int) bv;
611 }
612 break;
c784b115
AG
613 case 0x12: /* zex.b */
614 {
615 int a = (inst >> 4) & 0xf;
616 int b = inst & 0xf;
617 signed char bv = cpu.asregs.regs[b];
3ba611c3 618
c784b115
AG
619 TRACE("zex.b");
620 cpu.asregs.regs[a] = (int) bv & 0xff;
621 }
622 break;
623 case 0x13: /* zex.s */
624 {
625 int a = (inst >> 4) & 0xf;
626 int b = inst & 0xf;
627 signed short bv = cpu.asregs.regs[b];
3ba611c3 628
c784b115
AG
629 TRACE("zex.s");
630 cpu.asregs.regs[a] = (int) bv & 0xffff;
631 }
632 break;
507411cc 633 case 0x14: /* umul.x */
ed4fd7b7
AG
634 {
635 int a = (inst >> 4) & 0xf;
636 int b = inst & 0xf;
637 unsigned av = cpu.asregs.regs[a];
638 unsigned bv = cpu.asregs.regs[b];
507411cc
AG
639 unsigned long long r =
640 (unsigned long long) av * (unsigned long long) bv;
3ba611c3 641
507411cc 642 TRACE("umul.x");
ed4fd7b7
AG
643 cpu.asregs.regs[a] = r >> 32;
644 }
645 break;
507411cc 646 case 0x15: /* mul.x */
ed4fd7b7
AG
647 {
648 int a = (inst >> 4) & 0xf;
649 int b = inst & 0xf;
650 unsigned av = cpu.asregs.regs[a];
651 unsigned bv = cpu.asregs.regs[b];
507411cc
AG
652 signed long long r =
653 (signed long long) av * (signed long long) bv;
3ba611c3 654
507411cc 655 TRACE("mul.x");
ed4fd7b7
AG
656 cpu.asregs.regs[a] = r >> 32;
657 }
658 break;
32d49b7b
AG
659 case 0x16: /* bad */
660 case 0x17: /* bad */
661 case 0x18: /* bad */
fdd6fa61 662 {
86566200
AG
663 opc = opcode;
664 TRACE("SIGILL0");
665 cpu.asregs.exception = SIGILL;
666 break;
fdd6fa61 667 }
fdd6fa61
AG
668 case 0x19: /* jsr */
669 {
670 unsigned int fn = cpu.asregs.regs[(inst >> 4) & 0xf];
671 unsigned int sp = cpu.asregs.regs[1];
672
673 TRACE("jsr");
674
675 /* Save a slot for the static chain. */
676 sp -= 4;
677
678 /* Push the return address. */
679 sp -= 4;
5c27d164 680 wlat (scpu, opc, sp, pc + 2);
fdd6fa61
AG
681
682 /* Push the current frame pointer. */
683 sp -= 4;
5c27d164 684 wlat (scpu, opc, sp, cpu.asregs.regs[0]);
fdd6fa61
AG
685
686 /* Uncache the stack pointer and set the fp & pc. */
687 cpu.asregs.regs[1] = sp;
688 cpu.asregs.regs[0] = sp;
689 pc = fn - 2;
690 }
691 break;
692 case 0x1a: /* jmpa */
693 {
5c27d164 694 unsigned int tgt = EXTRACT_WORD(pc+2);
3ba611c3 695
fdd6fa61
AG
696 TRACE("jmpa");
697 pc = tgt - 2;
698 }
699 break;
700 case 0x1b: /* ldi.b (immediate) */
701 {
702 int reg = (inst >> 4) & 0xf;
5c27d164 703 unsigned int val = EXTRACT_WORD(pc+2);
3ba611c3 704
fdd6fa61
AG
705 TRACE("ldi.b");
706 cpu.asregs.regs[reg] = val;
707 pc += 4;
708 }
709 break;
710 case 0x1c: /* ld.b (register indirect) */
711 {
712 int src = inst & 0xf;
713 int dest = (inst >> 4) & 0xf;
714 int xv;
3ba611c3 715
fdd6fa61
AG
716 TRACE("ld.b");
717 xv = cpu.asregs.regs[src];
5c27d164 718 cpu.asregs.regs[dest] = rbat (scpu, opc, xv);
fdd6fa61
AG
719 }
720 break;
721 case 0x1d: /* lda.b */
722 {
723 int reg = (inst >> 4) & 0xf;
5c27d164 724 unsigned int addr = EXTRACT_WORD(pc+2);
3ba611c3 725
fdd6fa61 726 TRACE("lda.b");
5c27d164 727 cpu.asregs.regs[reg] = rbat (scpu, opc, addr);
fdd6fa61
AG
728 pc += 4;
729 }
730 break;
731 case 0x1e: /* st.b */
732 {
733 int dest = (inst >> 4) & 0xf;
734 int val = inst & 0xf;
3ba611c3 735
fdd6fa61 736 TRACE("st.b");
5c27d164 737 wbat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
fdd6fa61
AG
738 }
739 break;
740 case 0x1f: /* sta.b */
741 {
742 int reg = (inst >> 4) & 0xf;
5c27d164 743 unsigned int addr = EXTRACT_WORD(pc+2);
3ba611c3 744
fdd6fa61 745 TRACE("sta.b");
5c27d164 746 wbat (scpu, opc, addr, cpu.asregs.regs[reg]);
fdd6fa61
AG
747 pc += 4;
748 }
749 break;
750 case 0x20: /* ldi.s (immediate) */
751 {
752 int reg = (inst >> 4) & 0xf;
753
5c27d164 754 unsigned int val = EXTRACT_WORD(pc+2);
3ba611c3 755
fdd6fa61
AG
756 TRACE("ldi.s");
757 cpu.asregs.regs[reg] = val;
758 pc += 4;
759 }
760 break;
761 case 0x21: /* ld.s (register indirect) */
762 {
763 int src = inst & 0xf;
764 int dest = (inst >> 4) & 0xf;
765 int xv;
3ba611c3 766
fdd6fa61
AG
767 TRACE("ld.s");
768 xv = cpu.asregs.regs[src];
5c27d164 769 cpu.asregs.regs[dest] = rsat (scpu, opc, xv);
fdd6fa61
AG
770 }
771 break;
772 case 0x22: /* lda.s */
773 {
774 int reg = (inst >> 4) & 0xf;
5c27d164 775 unsigned int addr = EXTRACT_WORD(pc+2);
3ba611c3 776
fdd6fa61 777 TRACE("lda.s");
5c27d164 778 cpu.asregs.regs[reg] = rsat (scpu, opc, addr);
fdd6fa61
AG
779 pc += 4;
780 }
781 break;
782 case 0x23: /* st.s */
783 {
784 int dest = (inst >> 4) & 0xf;
785 int val = inst & 0xf;
3ba611c3 786
fdd6fa61 787 TRACE("st.s");
5c27d164 788 wsat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
fdd6fa61
AG
789 }
790 break;
791 case 0x24: /* sta.s */
792 {
793 int reg = (inst >> 4) & 0xf;
5c27d164 794 unsigned int addr = EXTRACT_WORD(pc+2);
3ba611c3 795
fdd6fa61 796 TRACE("sta.s");
5c27d164 797 wsat (scpu, opc, addr, cpu.asregs.regs[reg]);
fdd6fa61
AG
798 pc += 4;
799 }
800 break;
801 case 0x25: /* jmp */
802 {
803 int reg = (inst >> 4) & 0xf;
3ba611c3 804
fdd6fa61
AG
805 TRACE("jmp");
806 pc = cpu.asregs.regs[reg] - 2;
807 }
808 break;
809 case 0x26: /* and */
810 {
811 int a = (inst >> 4) & 0xf;
812 int b = inst & 0xf;
813 int av, bv;
3ba611c3 814
fdd6fa61
AG
815 TRACE("and");
816 av = cpu.asregs.regs[a];
817 bv = cpu.asregs.regs[b];
818 cpu.asregs.regs[a] = av & bv;
819 }
820 break;
821 case 0x27: /* lshr */
822 {
823 int a = (inst >> 4) & 0xf;
824 int b = inst & 0xf;
825 int av = cpu.asregs.regs[a];
826 int bv = cpu.asregs.regs[b];
3ba611c3 827
fdd6fa61
AG
828 TRACE("lshr");
829 cpu.asregs.regs[a] = (unsigned) ((unsigned) av >> bv);
830 }
831 break;
832 case 0x28: /* ashl */
833 {
834 int a = (inst >> 4) & 0xf;
835 int b = inst & 0xf;
836 int av = cpu.asregs.regs[a];
837 int bv = cpu.asregs.regs[b];
3ba611c3 838
fdd6fa61
AG
839 TRACE("ashl");
840 cpu.asregs.regs[a] = av << bv;
841 }
842 break;
843 case 0x29: /* sub.l */
844 {
845 int a = (inst >> 4) & 0xf;
846 int b = inst & 0xf;
847 unsigned av = cpu.asregs.regs[a];
848 unsigned bv = cpu.asregs.regs[b];
3ba611c3 849
fdd6fa61
AG
850 TRACE("sub.l");
851 cpu.asregs.regs[a] = av - bv;
852 }
853 break;
854 case 0x2a: /* neg */
855 {
856 int a = (inst >> 4) & 0xf;
857 int b = inst & 0xf;
858 int bv = cpu.asregs.regs[b];
3ba611c3 859
fdd6fa61
AG
860 TRACE("neg");
861 cpu.asregs.regs[a] = - bv;
862 }
863 break;
864 case 0x2b: /* or */
865 {
866 int a = (inst >> 4) & 0xf;
867 int b = inst & 0xf;
868 int av, bv;
3ba611c3 869
fdd6fa61
AG
870 TRACE("or");
871 av = cpu.asregs.regs[a];
872 bv = cpu.asregs.regs[b];
873 cpu.asregs.regs[a] = av | bv;
874 }
875 break;
876 case 0x2c: /* not */
877 {
878 int a = (inst >> 4) & 0xf;
879 int b = inst & 0xf;
880 int bv = cpu.asregs.regs[b];
3ba611c3 881
fdd6fa61
AG
882 TRACE("not");
883 cpu.asregs.regs[a] = 0xffffffff ^ bv;
884 }
885 break;
886 case 0x2d: /* ashr */
887 {
888 int a = (inst >> 4) & 0xf;
889 int b = inst & 0xf;
890 int av = cpu.asregs.regs[a];
891 int bv = cpu.asregs.regs[b];
3ba611c3 892
fdd6fa61
AG
893 TRACE("ashr");
894 cpu.asregs.regs[a] = av >> bv;
895 }
896 break;
897 case 0x2e: /* xor */
898 {
899 int a = (inst >> 4) & 0xf;
900 int b = inst & 0xf;
901 int av, bv;
3ba611c3 902
fdd6fa61
AG
903 TRACE("xor");
904 av = cpu.asregs.regs[a];
905 bv = cpu.asregs.regs[b];
906 cpu.asregs.regs[a] = av ^ bv;
907 }
908 break;
909 case 0x2f: /* mul.l */
910 {
911 int a = (inst >> 4) & 0xf;
912 int b = inst & 0xf;
913 unsigned av = cpu.asregs.regs[a];
914 unsigned bv = cpu.asregs.regs[b];
3ba611c3 915
fdd6fa61
AG
916 TRACE("mul.l");
917 cpu.asregs.regs[a] = av * bv;
918 }
919 break;
920 case 0x30: /* swi */
921 {
5c27d164 922 unsigned int inum = EXTRACT_WORD(pc+2);
3ba611c3 923
fdd6fa61 924 TRACE("swi");
5c27d164
AG
925 /* Set the special registers appropriately. */
926 cpu.asregs.sregs[2] = 3; /* MOXIE_EX_SWI */
927 cpu.asregs.sregs[3] = inum;
fdd6fa61
AG
928 switch (inum)
929 {
930 case 0x1: /* SYS_exit */
931 {
932 cpu.asregs.exception = SIGQUIT;
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");
1044 cpu.asregs.exception = SIGTRAP;
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");
1098 cpu.asregs.exception = SIGILL;
1099 break;
1100 }
1101 }
1102
1103 insts++;
1104 pc += 2;
1105
1106 } while (!cpu.asregs.exception);
1107
1108 /* Hide away the things we've cached while executing. */
1109 cpu.asregs.regs[PC_REGNO] = pc;
1110 cpu.asregs.insts += insts; /* instructions done ... */
fdd6fa61
AG
1111}
1112
fdd6fa61 1113int
1bf57e9a 1114sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
fdd6fa61 1115{
fdd6fa61
AG
1116 if (rn < NUM_MOXIE_REGS && rn >= 0)
1117 {
1118 if (length == 4)
1119 {
1120 long ival;
1121
1122 /* misalignment safe */
1123 ival = moxie_extract_unsigned_integer (memory, 4);
1124 cpu.asints[rn] = ival;
1125 }
1126
1127 return 4;
1128 }
1129 else
1130 return 0;
1131}
1132
1133int
1bf57e9a 1134sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
fdd6fa61 1135{
fdd6fa61
AG
1136 if (rn < NUM_MOXIE_REGS && rn >= 0)
1137 {
1138 if (length == 4)
1139 {
1140 long ival = cpu.asints[rn];
1141
1142 /* misalignment-safe */
1143 moxie_store_unsigned_integer (memory, 4, ival);
1144 }
1145
1146 return 4;
1147 }
1148 else
1149 return 0;
1150}
1151
cc8ab1de
MF
1152static void
1153free_state (SIM_DESC sd)
fdd6fa61 1154{
cc8ab1de
MF
1155 if (STATE_MODULES (sd) != NULL)
1156 sim_module_uninstall (sd);
1157 sim_cpu_free_all (sd);
1158 sim_state_free (sd);
fdd6fa61
AG
1159}
1160
fdd6fa61 1161SIM_DESC
1bf57e9a 1162sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
fdd6fa61 1163{
5c27d164 1164 SIM_DESC sd = sim_state_alloc (kind, cb);
5c27d164
AG
1165 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
1166
cc8ab1de
MF
1167 /* The cpu data is kept in a separately allocated chunk of memory. */
1168 if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
1169 {
1170 free_state (sd);
1171 return 0;
1172 }
1173
1174 STATE_WATCHPOINTS (sd)->pc = &cpu.asregs.regs[PC_REGNO];
1175 STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (word);
1176
5c27d164 1177 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
cc8ab1de
MF
1178 {
1179 free_state (sd);
1180 return 0;
1181 }
1182
1183 /* getopt will print the error message so we just have to exit if this fails.
1184 FIXME: Hmmm... in the case of gdb we need getopt to call
1185 print_filtered. */
1186 if (sim_parse_args (sd, argv) != SIM_RC_OK)
1187 {
1188 free_state (sd);
1189 return 0;
1190 }
5c27d164
AG
1191
1192 sim_do_command(sd," memory region 0x00000000,0x4000000") ;
1193 sim_do_command(sd," memory region 0xE0000000,0x10000") ;
1194
cc8ab1de
MF
1195 /* Check for/establish the a reference program image. */
1196 if (sim_analyze_program (sd,
1197 (STATE_PROG_ARGV (sd) != NULL
1198 ? *STATE_PROG_ARGV (sd)
1199 : NULL), abfd) != SIM_RC_OK)
1200 {
1201 free_state (sd);
1202 return 0;
1203 }
1204
b8dcd182 1205 /* Configure/verify the target byte order and other runtime
11db68fd 1206 configuration options. */
b8dcd182
AG
1207 if (sim_config (sd) != SIM_RC_OK)
1208 {
1209 sim_module_uninstall (sd);
1210 return 0;
1211 }
1212
1213 if (sim_post_argv_init (sd) != SIM_RC_OK)
1214 {
1215 /* Uninstall the modules to avoid memory leaks,
1216 file descriptor leaks, etc. */
1217 sim_module_uninstall (sd);
1218 return 0;
1219 }
1220
cc8ab1de
MF
1221 /* CPU specific initialization. */
1222 set_initial_gprs ();
1223
5c27d164 1224 return sd;
fdd6fa61
AG
1225}
1226
1227void
1bf57e9a 1228sim_close (SIM_DESC sd, int quitting)
fdd6fa61
AG
1229{
1230 /* nothing to do */
1231}
1232
5c27d164
AG
1233
1234/* Load the device tree blob. */
1235
1236static void
1237load_dtb (SIM_DESC sd, const char *filename)
1238{
1239 int size = 0;
1240 FILE *f = fopen (filename, "rb");
1241 char *buf;
1242 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1243 if (f == NULL)
1244 {
1245 printf ("WARNING: ``%s'' could not be opened.\n", filename);
1246 return;
1247 }
1248 fseek (f, 0, SEEK_END);
1249 size = ftell(f);
1250 fseek (f, 0, SEEK_SET);
1251 buf = alloca (size);
1252 if (size != fread (buf, 1, size, f))
1253 {
1254 printf ("ERROR: error reading ``%s''.\n", filename);
1255 return;
1256 }
1257 sim_core_write_buffer (sd, scpu, write_map, buf, 0xE0000000, size);
1258 cpu.asregs.sregs[9] = 0xE0000000;
1259 fclose (f);
1260}
1261
fdd6fa61 1262SIM_RC
1bf57e9a 1263sim_create_inferior (SIM_DESC sd, struct bfd *prog_bfd, char **argv, char **env)
fdd6fa61
AG
1264{
1265 char ** avp;
1266 int l, argc, i, tp;
5c27d164 1267 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
fdd6fa61 1268
bc56c8fa
JK
1269 if (prog_bfd != NULL)
1270 cpu.asregs.regs[PC_REGNO] = bfd_get_start_address (prog_bfd);
fdd6fa61
AG
1271
1272 /* Copy args into target memory. */
1273 avp = argv;
bc56c8fa 1274 for (argc = 0; avp && *avp; avp++)
fdd6fa61
AG
1275 argc++;
1276
1277 /* Target memory looks like this:
1278 0x00000000 zero word
1279 0x00000004 argc word
1280 0x00000008 start of argv
1281 .
1282 0x0000???? end of argv
1283 0x0000???? zero word
1284 0x0000???? start of data pointed to by argv */
1285
5c27d164
AG
1286 wlat (scpu, 0, 0, 0);
1287 wlat (scpu, 0, 4, argc);
fdd6fa61
AG
1288
1289 /* tp is the offset of our first argv data. */
1290 tp = 4 + 4 + argc * 4 + 4;
1291
1292 for (i = 0; i < argc; i++)
1293 {
1294 /* Set the argv value. */
5c27d164 1295 wlat (scpu, 0, 4 + 4 + i * 4, tp);
fdd6fa61
AG
1296
1297 /* Store the string. */
5c27d164
AG
1298 sim_core_write_buffer (sd, scpu, write_map, argv[i],
1299 tp, strlen(argv[i])+1);
fdd6fa61
AG
1300 tp += strlen (argv[i]) + 1;
1301 }
1302
5c27d164
AG
1303 wlat (scpu, 0, 4 + 4 + i * 4, 0);
1304
1305 load_dtb (sd, DTB);
fdd6fa61
AG
1306
1307 return SIM_RC_OK;
1308}