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