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