Home | History | Annotate | Line # | Download | only in moxie
interp.c revision 1.10
      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