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