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