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