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