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