Home | History | Annotate | Line # | Download | only in msp430
msp430-sim.c revision 1.1
      1  1.1  christos /* Simulator for TI MSP430 and MSP430X
      2  1.1  christos 
      3  1.1  christos    Copyright (C) 2013-2014 Free Software Foundation, Inc.
      4  1.1  christos    Contributed by Red Hat.
      5  1.1  christos    Based on sim/bfin/bfin-sim.c which was contributed by Analog Devices, Inc.
      6  1.1  christos 
      7  1.1  christos    This file is part of simulators.
      8  1.1  christos 
      9  1.1  christos    This program is free software; you can redistribute it and/or modify
     10  1.1  christos    it under the terms of the GNU General Public License as published by
     11  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     12  1.1  christos    (at your option) any later version.
     13  1.1  christos 
     14  1.1  christos    This program is distributed in the hope that it will be useful,
     15  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17  1.1  christos    GNU General Public License for more details.
     18  1.1  christos 
     19  1.1  christos    You should have received a copy of the GNU General Public License
     20  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     21  1.1  christos 
     22  1.1  christos #include "config.h"
     23  1.1  christos #include <stdio.h>
     24  1.1  christos #include <stdlib.h>
     25  1.1  christos #include <string.h>
     26  1.1  christos #include <inttypes.h>
     27  1.1  christos #include <assert.h>
     28  1.1  christos #include "bfd.h"
     29  1.1  christos #include "opcode/msp430-decode.h"
     30  1.1  christos #include "sim-main.h"
     31  1.1  christos #include "dis-asm.h"
     32  1.1  christos #include "targ-vals.h"
     33  1.1  christos 
     34  1.1  christos static int
     35  1.1  christos loader_write_mem (SIM_DESC sd,
     36  1.1  christos 		  SIM_ADDR taddr,
     37  1.1  christos 		  const unsigned char *buf,
     38  1.1  christos 		  int bytes)
     39  1.1  christos {
     40  1.1  christos   SIM_CPU *cpu = MSP430_CPU (sd);
     41  1.1  christos   return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
     42  1.1  christos }
     43  1.1  christos 
     44  1.1  christos static sim_cia
     45  1.1  christos msp430_pc_fetch (SIM_CPU *cpu)
     46  1.1  christos {
     47  1.1  christos   return cpu->state.regs[0];
     48  1.1  christos }
     49  1.1  christos 
     50  1.1  christos static void
     51  1.1  christos msp430_pc_store (SIM_CPU *cpu, sim_cia newpc)
     52  1.1  christos {
     53  1.1  christos   cpu->state.regs[0] = newpc;
     54  1.1  christos }
     55  1.1  christos 
     56  1.1  christos static long
     57  1.1  christos lookup_symbol (SIM_DESC sd, const char *name)
     58  1.1  christos {
     59  1.1  christos   struct bfd *abfd = STATE_PROG_BFD (sd);
     60  1.1  christos   asymbol **symbol_table = STATE_SYMBOL_TABLE (sd);
     61  1.1  christos   long number_of_symbols = STATE_NUM_SYMBOLS (sd);
     62  1.1  christos   long i;
     63  1.1  christos 
     64  1.1  christos   if (symbol_table == NULL)
     65  1.1  christos     {
     66  1.1  christos       long storage_needed;
     67  1.1  christos 
     68  1.1  christos       storage_needed = bfd_get_symtab_upper_bound (abfd);
     69  1.1  christos       if (storage_needed <= 0)
     70  1.1  christos 	return -1;
     71  1.1  christos 
     72  1.1  christos       STATE_SYMBOL_TABLE (sd) = symbol_table = xmalloc (storage_needed);
     73  1.1  christos       STATE_NUM_SYMBOLS (sd) = number_of_symbols =
     74  1.1  christos 	bfd_canonicalize_symtab (abfd, symbol_table);
     75  1.1  christos     }
     76  1.1  christos 
     77  1.1  christos   for (i = 0; i < number_of_symbols; i++)
     78  1.1  christos     if (strcmp (symbol_table[i]->name, name) == 0)
     79  1.1  christos       {
     80  1.1  christos 	long val = symbol_table[i]->section->vma + symbol_table[i]->value;
     81  1.1  christos 	return val;
     82  1.1  christos       }
     83  1.1  christos   return -1;
     84  1.1  christos }
     85  1.1  christos 
     86  1.1  christos static int
     87  1.1  christos msp430_reg_fetch (SIM_CPU *cpu, int regno, unsigned char *buf, int len)
     88  1.1  christos {
     89  1.1  christos   if (0 <= regno && regno < 16)
     90  1.1  christos     {
     91  1.1  christos       if (len == 2)
     92  1.1  christos 	{
     93  1.1  christos 	  int val = cpu->state.regs[regno];
     94  1.1  christos 	  buf[0] = val & 0xff;
     95  1.1  christos 	  buf[1] = (val >> 8) & 0xff;
     96  1.1  christos 	  return 0;
     97  1.1  christos 	}
     98  1.1  christos       else if (len == 4)
     99  1.1  christos 	{
    100  1.1  christos 	  int val = cpu->state.regs[regno];
    101  1.1  christos 	  buf[0] = val & 0xff;
    102  1.1  christos 	  buf[1] = (val >> 8) & 0xff;
    103  1.1  christos 	  buf[2] = (val >> 16) & 0x0f; /* Registers are only 20 bits wide.  */
    104  1.1  christos 	  buf[3] = 0;
    105  1.1  christos 	  return 0;
    106  1.1  christos 	}
    107  1.1  christos       else
    108  1.1  christos 	return -1;
    109  1.1  christos     }
    110  1.1  christos   else
    111  1.1  christos     return -1;
    112  1.1  christos }
    113  1.1  christos 
    114  1.1  christos static int
    115  1.1  christos msp430_reg_store (SIM_CPU *cpu, int regno, unsigned char *buf, int len)
    116  1.1  christos {
    117  1.1  christos   if (0 <= regno && regno < 16)
    118  1.1  christos     {
    119  1.1  christos       if (len == 2)
    120  1.1  christos 	{
    121  1.1  christos 	  cpu->state.regs[regno] = (buf[1] << 8) | buf[0];
    122  1.1  christos 	  return len;
    123  1.1  christos 	}
    124  1.1  christos 
    125  1.1  christos       if (len == 4)
    126  1.1  christos 	{
    127  1.1  christos 	  cpu->state.regs[regno] = ((buf[2] << 16) & 0xf0000)
    128  1.1  christos 				   | (buf[1] << 8) | buf[0];
    129  1.1  christos 	  return len;
    130  1.1  christos 	}
    131  1.1  christos     }
    132  1.1  christos 
    133  1.1  christos   return -1;
    134  1.1  christos }
    135  1.1  christos 
    136  1.1  christos static inline void
    137  1.1  christos msp430_initialize_cpu (SIM_DESC sd, SIM_CPU *cpu)
    138  1.1  christos {
    139  1.1  christos   memset (&cpu->state, 0, sizeof (cpu->state));
    140  1.1  christos }
    141  1.1  christos 
    142  1.1  christos SIM_DESC
    143  1.1  christos sim_open (SIM_OPEN_KIND kind,
    144  1.1  christos 	  struct host_callback_struct *callback,
    145  1.1  christos 	  struct bfd *abfd,
    146  1.1  christos 	  char **argv)
    147  1.1  christos {
    148  1.1  christos   SIM_DESC sd = sim_state_alloc (kind, callback);
    149  1.1  christos   char c;
    150  1.1  christos   struct bfd *prog_bfd;
    151  1.1  christos 
    152  1.1  christos   /* Initialise the simulator.  */
    153  1.1  christos 
    154  1.1  christos   if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
    155  1.1  christos     {
    156  1.1  christos       sim_state_free (sd);
    157  1.1  christos       return 0;
    158  1.1  christos     }
    159  1.1  christos 
    160  1.1  christos   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
    161  1.1  christos     {
    162  1.1  christos       sim_state_free (sd);
    163  1.1  christos       return 0;
    164  1.1  christos     }
    165  1.1  christos 
    166  1.1  christos   if (sim_parse_args (sd, argv) != SIM_RC_OK)
    167  1.1  christos     {
    168  1.1  christos       sim_state_free (sd);
    169  1.1  christos       return 0;
    170  1.1  christos     }
    171  1.1  christos 
    172  1.1  christos   CPU_PC_FETCH (MSP430_CPU (sd)) = msp430_pc_fetch;
    173  1.1  christos   CPU_PC_STORE (MSP430_CPU (sd)) = msp430_pc_store;
    174  1.1  christos   CPU_REG_FETCH (MSP430_CPU (sd)) = msp430_reg_fetch;
    175  1.1  christos   CPU_REG_STORE (MSP430_CPU (sd)) = msp430_reg_store;
    176  1.1  christos 
    177  1.1  christos   /* Allocate memory if none specified by user.  */
    178  1.1  christos   if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x200, 1) == 0)
    179  1.1  christos     sim_do_commandf (sd, "memory-region 0,0x10000");
    180  1.1  christos   if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0xfffe, 1) == 0)
    181  1.1  christos     sim_do_commandf (sd, "memory-region 0xfffe,2");
    182  1.1  christos   if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x10000, 1) == 0)
    183  1.1  christos     sim_do_commandf (sd, "memory-region 0x10000,0x100000");
    184  1.1  christos 
    185  1.1  christos   /* Check for/establish the a reference program image.  */
    186  1.1  christos   if (sim_analyze_program (sd,
    187  1.1  christos 			   (STATE_PROG_ARGV (sd) != NULL
    188  1.1  christos 			    ? *STATE_PROG_ARGV (sd)
    189  1.1  christos 			    : NULL), abfd) != SIM_RC_OK)
    190  1.1  christos     {
    191  1.1  christos       sim_state_free (sd);
    192  1.1  christos       return 0;
    193  1.1  christos     }
    194  1.1  christos 
    195  1.1  christos   prog_bfd = sim_load_file (sd, argv[0], callback,
    196  1.1  christos 			    "the program",
    197  1.1  christos 			    STATE_PROG_BFD (sd),
    198  1.1  christos 			    0 /* verbose */,
    199  1.1  christos 			    1 /* use LMA instead of VMA */,
    200  1.1  christos 			    loader_write_mem);
    201  1.1  christos   if (prog_bfd == NULL)
    202  1.1  christos     {
    203  1.1  christos       sim_state_free (sd);
    204  1.1  christos       return 0;
    205  1.1  christos     }
    206  1.1  christos 
    207  1.1  christos   /* Establish any remaining configuration options.  */
    208  1.1  christos   if (sim_config (sd) != SIM_RC_OK)
    209  1.1  christos     {
    210  1.1  christos       sim_state_free (sd);
    211  1.1  christos       return 0;
    212  1.1  christos     }
    213  1.1  christos 
    214  1.1  christos   if (sim_post_argv_init (sd) != SIM_RC_OK)
    215  1.1  christos     {
    216  1.1  christos       sim_state_free (sd);
    217  1.1  christos       return 0;
    218  1.1  christos     }
    219  1.1  christos 
    220  1.1  christos   /* CPU specific initialization.  */
    221  1.1  christos   assert (MAX_NR_PROCESSORS == 1);
    222  1.1  christos   msp430_initialize_cpu (sd, MSP430_CPU (sd));
    223  1.1  christos 
    224  1.1  christos   msp430_trace_init (STATE_PROG_BFD (sd));
    225  1.1  christos 
    226  1.1  christos   MSP430_CPU (sd)->state.cio_breakpoint = lookup_symbol (sd, "C$$IO$$");
    227  1.1  christos   MSP430_CPU (sd)->state.cio_buffer = lookup_symbol (sd, "__CIOBUF__");
    228  1.1  christos   if (MSP430_CPU (sd)->state.cio_buffer == -1)
    229  1.1  christos     MSP430_CPU (sd)->state.cio_buffer = lookup_symbol (sd, "_CIOBUF_");
    230  1.1  christos 
    231  1.1  christos   return sd;
    232  1.1  christos }
    233  1.1  christos 
    234  1.1  christos void
    235  1.1  christos sim_close (SIM_DESC sd,
    236  1.1  christos 	   int quitting)
    237  1.1  christos {
    238  1.1  christos   free (STATE_SYMBOL_TABLE (sd));
    239  1.1  christos   sim_state_free (sd);
    240  1.1  christos }
    241  1.1  christos 
    242  1.1  christos SIM_RC
    243  1.1  christos sim_create_inferior (SIM_DESC sd,
    244  1.1  christos 		     struct bfd *abfd,
    245  1.1  christos 		     char **argv,
    246  1.1  christos 		     char **env)
    247  1.1  christos {
    248  1.1  christos   unsigned char resetv[2];
    249  1.1  christos   int c;
    250  1.1  christos   int new_pc;
    251  1.1  christos 
    252  1.1  christos   c = sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, resetv, 0xfffe, 2);
    253  1.1  christos 
    254  1.1  christos   new_pc = resetv[0] + 256 * resetv[1];
    255  1.1  christos   sim_pc_set (MSP430_CPU (sd), new_pc);
    256  1.1  christos   msp430_pc_store (MSP430_CPU (sd), new_pc);
    257  1.1  christos 
    258  1.1  christos   return SIM_RC_OK;
    259  1.1  christos }
    260  1.1  christos 
    261  1.1  christos typedef struct
    262  1.1  christos {
    263  1.1  christos   SIM_DESC sd;
    264  1.1  christos   int gb_addr;
    265  1.1  christos } Get_Byte_Local_Data;
    266  1.1  christos 
    267  1.1  christos static int
    268  1.1  christos msp430_getbyte (void *vld)
    269  1.1  christos {
    270  1.1  christos   Get_Byte_Local_Data *ld = (Get_Byte_Local_Data *)vld;
    271  1.1  christos   char buf[1];
    272  1.1  christos   SIM_DESC sd = ld->sd;
    273  1.1  christos 
    274  1.1  christos   sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, ld->gb_addr, 1);
    275  1.1  christos   ld->gb_addr ++;
    276  1.1  christos   return buf[0];
    277  1.1  christos }
    278  1.1  christos 
    279  1.1  christos #define REG(N) MSP430_CPU (sd)->state.regs[(N)]
    280  1.1  christos #define PC REG(MSR_PC)
    281  1.1  christos #define SP REG(MSR_SP)
    282  1.1  christos #define SR REG(MSR_SR)
    283  1.1  christos 
    284  1.1  christos static const char *
    285  1.1  christos register_names[] =
    286  1.1  christos {
    287  1.1  christos   "PC", "SP", "SR", "CG", "R4", "R5", "R6", "R7", "R8",
    288  1.1  christos   "R9", "R10", "R11", "R12", "R13", "R14", "R15"
    289  1.1  christos };
    290  1.1  christos 
    291  1.1  christos static void
    292  1.1  christos trace_reg_put (SIM_DESC sd, int n, unsigned int v)
    293  1.1  christos {
    294  1.1  christos   if (TRACE_VPU_P (MSP430_CPU (sd)))
    295  1.1  christos     trace_generic (sd, MSP430_CPU (sd), TRACE_VPU_IDX,
    296  1.1  christos 		   "PUT: %#x -> %s", v, register_names [n]);
    297  1.1  christos   REG (n) = v;
    298  1.1  christos }
    299  1.1  christos 
    300  1.1  christos static unsigned int
    301  1.1  christos trace_reg_get (SIM_DESC sd, int n)
    302  1.1  christos {
    303  1.1  christos   if (TRACE_VPU_P (MSP430_CPU (sd)))
    304  1.1  christos     trace_generic (sd, MSP430_CPU (sd), TRACE_VPU_IDX,
    305  1.1  christos 		   "GET: %s -> %#x", register_names [n], REG (n));
    306  1.1  christos   return REG (n);
    307  1.1  christos }
    308  1.1  christos 
    309  1.1  christos #define REG_PUT(N,V) trace_reg_put (sd, N, V)
    310  1.1  christos #define REG_GET(N)   trace_reg_get (sd, N)
    311  1.1  christos 
    312  1.1  christos static int
    313  1.1  christos get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n)
    314  1.1  christos {
    315  1.1  christos   MSP430_Opcode_Operand *op = opc->op + n;
    316  1.1  christos   int rv;
    317  1.1  christos   int addr;
    318  1.1  christos   unsigned char buf[4];
    319  1.1  christos   int incval = 0;
    320  1.1  christos 
    321  1.1  christos   switch (op->type)
    322  1.1  christos     {
    323  1.1  christos     case MSP430_Operand_Immediate:
    324  1.1  christos       rv =  op->addend;
    325  1.1  christos       break;
    326  1.1  christos     case MSP430_Operand_Register:
    327  1.1  christos       rv = REG_GET (op->reg);
    328  1.1  christos       break;
    329  1.1  christos     case MSP430_Operand_Indirect:
    330  1.1  christos     case MSP430_Operand_Indirect_Postinc:
    331  1.1  christos       addr = op->addend;
    332  1.1  christos       if (op->reg != MSR_None)
    333  1.1  christos 	{
    334  1.1  christos 	  int reg;
    335  1.1  christos 	  /* Index values are signed, but the sum is limited to 16
    336  1.1  christos 	     bits if the register < 64k, for MSP430 compatibility in
    337  1.1  christos 	     MSP430X chips.  */
    338  1.1  christos 	  if (addr & 0x8000)
    339  1.1  christos 	    addr |= -1 << 16;
    340  1.1  christos 	  reg = REG_GET (op->reg);
    341  1.1  christos 	  addr += reg;
    342  1.1  christos 	  if (reg < 0x10000 && ! opc->ofs_430x)
    343  1.1  christos 	    addr &= 0xffff;
    344  1.1  christos 	}
    345  1.1  christos       addr &= 0xfffff;
    346  1.1  christos       switch (opc->size)
    347  1.1  christos 	{
    348  1.1  christos 	case 8:
    349  1.1  christos 	  sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 1);
    350  1.1  christos 	  rv = buf[0];
    351  1.1  christos 	  break;
    352  1.1  christos 	case 16:
    353  1.1  christos 	  sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 2);
    354  1.1  christos 	  rv = buf[0] | (buf[1] << 8);
    355  1.1  christos 	  break;
    356  1.1  christos 	case 20:
    357  1.1  christos 	case 32:
    358  1.1  christos 	  sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 4);
    359  1.1  christos 	  rv = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
    360  1.1  christos 	  break;
    361  1.1  christos 	default:
    362  1.1  christos 	  assert (! opc->size);
    363  1.1  christos 	  break;
    364  1.1  christos 	}
    365  1.1  christos #if 0
    366  1.1  christos       /* Hack - MSP430X5438 serial port status register.  */
    367  1.1  christos       if (addr == 0x5dd)
    368  1.1  christos 	rv = 2;
    369  1.1  christos #endif
    370  1.1  christos       if (TRACE_MEMORY_P (MSP430_CPU (sd)))
    371  1.1  christos 	trace_generic (sd, MSP430_CPU (sd), TRACE_MEMORY_IDX,
    372  1.1  christos 		       "GET: [%#x].%d -> %#x", addr, opc->size, rv);
    373  1.1  christos       break;
    374  1.1  christos     default:
    375  1.1  christos       fprintf (stderr, "invalid operand %d type %d\n", n, op->type);
    376  1.1  christos       abort ();
    377  1.1  christos     }
    378  1.1  christos 
    379  1.1  christos   switch (opc->size)
    380  1.1  christos     {
    381  1.1  christos     case 8:
    382  1.1  christos       rv &= 0xff;
    383  1.1  christos       incval = 1;
    384  1.1  christos       break;
    385  1.1  christos     case 16:
    386  1.1  christos       rv &= 0xffff;
    387  1.1  christos       incval = 2;
    388  1.1  christos       break;
    389  1.1  christos     case 20:
    390  1.1  christos       rv &= 0xfffff;
    391  1.1  christos       incval = 4;
    392  1.1  christos       break;
    393  1.1  christos     case 32:
    394  1.1  christos       rv &= 0xffffffff;
    395  1.1  christos       incval = 4;
    396  1.1  christos       break;
    397  1.1  christos     }
    398  1.1  christos 
    399  1.1  christos   if (op->type == MSP430_Operand_Indirect_Postinc)
    400  1.1  christos     REG_PUT (op->reg, REG_GET (op->reg) + incval);
    401  1.1  christos 
    402  1.1  christos   return rv;
    403  1.1  christos }
    404  1.1  christos 
    405  1.1  christos static int
    406  1.1  christos put_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n, int val)
    407  1.1  christos {
    408  1.1  christos   MSP430_Opcode_Operand *op = opc->op + n;
    409  1.1  christos   int rv;
    410  1.1  christos   int addr;
    411  1.1  christos   unsigned char buf[4];
    412  1.1  christos   int incval = 0;
    413  1.1  christos 
    414  1.1  christos   switch (opc->size)
    415  1.1  christos     {
    416  1.1  christos     case 8:
    417  1.1  christos       val &= 0xff;
    418  1.1  christos       break;
    419  1.1  christos     case 16:
    420  1.1  christos       val &= 0xffff;
    421  1.1  christos       break;
    422  1.1  christos     case 20:
    423  1.1  christos       val &= 0xfffff;
    424  1.1  christos       break;
    425  1.1  christos     case 32:
    426  1.1  christos       val &= 0xffffffff;
    427  1.1  christos       break;
    428  1.1  christos     }
    429  1.1  christos 
    430  1.1  christos   switch (op->type)
    431  1.1  christos     {
    432  1.1  christos     case MSP430_Operand_Register:
    433  1.1  christos       REG (op->reg) = val;
    434  1.1  christos       REG_PUT (op->reg, val);
    435  1.1  christos       break;
    436  1.1  christos     case MSP430_Operand_Indirect:
    437  1.1  christos     case MSP430_Operand_Indirect_Postinc:
    438  1.1  christos       addr = op->addend;
    439  1.1  christos       if (op->reg != MSR_None)
    440  1.1  christos 	{
    441  1.1  christos 	  int reg;
    442  1.1  christos 	  /* Index values are signed, but the sum is limited to 16
    443  1.1  christos 	     bits if the register < 64k, for MSP430 compatibility in
    444  1.1  christos 	     MSP430X chips.  */
    445  1.1  christos 	  if (addr & 0x8000)
    446  1.1  christos 	    addr |= -1 << 16;
    447  1.1  christos 	  reg = REG_GET (op->reg);
    448  1.1  christos 	  addr += reg;
    449  1.1  christos 	  if (reg < 0x10000)
    450  1.1  christos 	    addr &= 0xffff;
    451  1.1  christos 	}
    452  1.1  christos       addr &= 0xfffff;
    453  1.1  christos 
    454  1.1  christos       if (TRACE_MEMORY_P (MSP430_CPU (sd)))
    455  1.1  christos 	trace_generic (sd, MSP430_CPU (sd), TRACE_MEMORY_IDX,
    456  1.1  christos 		       "PUT: [%#x].%d <- %#x", addr, opc->size, val);
    457  1.1  christos #if 0
    458  1.1  christos       /* Hack - MSP430X5438 serial port transmit register.  */
    459  1.1  christos       if (addr == 0x5ce)
    460  1.1  christos 	putchar (val);
    461  1.1  christos #endif
    462  1.1  christos       switch (opc->size)
    463  1.1  christos 	{
    464  1.1  christos 	case 8:
    465  1.1  christos 	  buf[0] = val;
    466  1.1  christos 	  sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 1);
    467  1.1  christos 	  break;
    468  1.1  christos 	case 16:
    469  1.1  christos 	  buf[0] = val;
    470  1.1  christos 	  buf[1] = val >> 8;
    471  1.1  christos 	  sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 2);
    472  1.1  christos 	  break;
    473  1.1  christos 	case 20:
    474  1.1  christos 	case 32:
    475  1.1  christos 	  buf[0] = val;
    476  1.1  christos 	  buf[1] = val >> 8;
    477  1.1  christos 	  buf[2] = val >> 16;
    478  1.1  christos 	  buf[3] = val >> 24;
    479  1.1  christos 	  sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 4);
    480  1.1  christos 	  break;
    481  1.1  christos 	default:
    482  1.1  christos 	  assert (! opc->size);
    483  1.1  christos 	  break;
    484  1.1  christos 	}
    485  1.1  christos       break;
    486  1.1  christos     default:
    487  1.1  christos       fprintf (stderr, "invalid operand %d type %d\n", n, op->type);
    488  1.1  christos       abort ();
    489  1.1  christos     }
    490  1.1  christos 
    491  1.1  christos   switch (opc->size)
    492  1.1  christos     {
    493  1.1  christos     case 8:
    494  1.1  christos       rv &= 0xff;
    495  1.1  christos       incval = 1;
    496  1.1  christos       break;
    497  1.1  christos     case 16:
    498  1.1  christos       rv &= 0xffff;
    499  1.1  christos       incval = 2;
    500  1.1  christos       break;
    501  1.1  christos     case 20:
    502  1.1  christos       rv &= 0xfffff;
    503  1.1  christos       incval = 4;
    504  1.1  christos       break;
    505  1.1  christos     case 32:
    506  1.1  christos       rv &= 0xffffffff;
    507  1.1  christos       incval = 4;
    508  1.1  christos       break;
    509  1.1  christos     }
    510  1.1  christos 
    511  1.1  christos   if (op->type == MSP430_Operand_Indirect_Postinc)
    512  1.1  christos     {
    513  1.1  christos       int new_val = REG_GET (op->reg) + incval;
    514  1.1  christos       /* SP is always word-aligned.  */
    515  1.1  christos       if (op->reg == MSR_SP && (new_val & 1))
    516  1.1  christos 	new_val ++;
    517  1.1  christos       REG_PUT (op->reg, new_val);
    518  1.1  christos     }
    519  1.1  christos 
    520  1.1  christos   return rv;
    521  1.1  christos }
    522  1.1  christos 
    523  1.1  christos static void
    524  1.1  christos mem_put_val (SIM_DESC sd, int addr, int val, int bits)
    525  1.1  christos {
    526  1.1  christos   MSP430_Opcode_Decoded opc;
    527  1.1  christos 
    528  1.1  christos   opc.size = bits;
    529  1.1  christos   opc.op[0].type = MSP430_Operand_Indirect;
    530  1.1  christos   opc.op[0].addend = addr;
    531  1.1  christos   opc.op[0].reg = MSR_None;
    532  1.1  christos   put_op (sd, &opc, 0, val);
    533  1.1  christos }
    534  1.1  christos 
    535  1.1  christos static int
    536  1.1  christos mem_get_val (SIM_DESC sd, int addr, int bits)
    537  1.1  christos {
    538  1.1  christos   MSP430_Opcode_Decoded opc;
    539  1.1  christos 
    540  1.1  christos   opc.size = bits;
    541  1.1  christos   opc.op[0].type = MSP430_Operand_Indirect;
    542  1.1  christos   opc.op[0].addend = addr;
    543  1.1  christos   opc.op[0].reg = MSR_None;
    544  1.1  christos   return get_op (sd, &opc, 0);
    545  1.1  christos }
    546  1.1  christos 
    547  1.1  christos #define CIO_OPEN    (0xF0)
    548  1.1  christos #define CIO_CLOSE   (0xF1)
    549  1.1  christos #define CIO_READ    (0xF2)
    550  1.1  christos #define CIO_WRITE   (0xF3)
    551  1.1  christos #define CIO_LSEEK   (0xF4)
    552  1.1  christos #define CIO_UNLINK  (0xF5)
    553  1.1  christos #define CIO_GETENV  (0xF6)
    554  1.1  christos #define CIO_RENAME  (0xF7)
    555  1.1  christos #define CIO_GETTIME (0xF8)
    556  1.1  christos #define CIO_GETCLK  (0xF9)
    557  1.1  christos #define CIO_SYNC    (0xFF)
    558  1.1  christos 
    559  1.1  christos #define CIO_I(n) (parms[(n)] + parms[(n)+1] * 256)
    560  1.1  christos #define CIO_L(n) (parms[(n)] + parms[(n)+1] * 256 \
    561  1.1  christos 		  + parms[(n)+2] * 65536 + parms[(n)+3] * 16777216)
    562  1.1  christos 
    563  1.1  christos static void
    564  1.1  christos msp430_cio (SIM_DESC sd)
    565  1.1  christos {
    566  1.1  christos   /* A block of data at __CIOBUF__ describes the I/O operation to
    567  1.1  christos      perform.  */
    568  1.1  christos 
    569  1.1  christos   unsigned char raw_parms[13];
    570  1.1  christos   unsigned char parms[8];
    571  1.1  christos   long length;
    572  1.1  christos   int command;
    573  1.1  christos   unsigned char buffer[512];
    574  1.1  christos   long ret_buflen = 0;
    575  1.1  christos   long fd, addr, len, rv;
    576  1.1  christos 
    577  1.1  christos   sim_core_read_buffer (sd, MSP430_CPU (sd), 0, parms,
    578  1.1  christos 			MSP430_CPU (sd)->state.cio_buffer, 5);
    579  1.1  christos   length = CIO_I (0);
    580  1.1  christos   command = parms[2];
    581  1.1  christos 
    582  1.1  christos   sim_core_read_buffer (sd, MSP430_CPU (sd), 0, parms,
    583  1.1  christos 			MSP430_CPU (sd)->state.cio_buffer + 3, 8);
    584  1.1  christos 
    585  1.1  christos   sim_core_read_buffer (sd, MSP430_CPU (sd), 0, buffer,
    586  1.1  christos 			MSP430_CPU (sd)->state.cio_buffer + 11, length);
    587  1.1  christos 
    588  1.1  christos   switch (command)
    589  1.1  christos     {
    590  1.1  christos     case CIO_WRITE:
    591  1.1  christos       fd = CIO_I (0);
    592  1.1  christos       len = CIO_I (2);
    593  1.1  christos 
    594  1.1  christos       rv = write (fd, buffer, len);
    595  1.1  christos       parms[0] = rv & 0xff;
    596  1.1  christos       parms[1] = rv >> 8;
    597  1.1  christos 
    598  1.1  christos       break;
    599  1.1  christos     }
    600  1.1  christos 
    601  1.1  christos   sim_core_write_buffer (sd, MSP430_CPU (sd), 0, parms,
    602  1.1  christos 			 MSP430_CPU (sd)->state.cio_buffer + 4, 8);
    603  1.1  christos   if (ret_buflen)
    604  1.1  christos     sim_core_write_buffer (sd, MSP430_CPU (sd), 0, buffer,
    605  1.1  christos 			   MSP430_CPU (sd)->state.cio_buffer + 12, ret_buflen);
    606  1.1  christos }
    607  1.1  christos 
    608  1.1  christos #define SRC     get_op (sd, opcode, 1)
    609  1.1  christos #define DSRC    get_op (sd, opcode, 0)
    610  1.1  christos #define DEST(V) put_op (sd, opcode, 0, (V))
    611  1.1  christos 
    612  1.1  christos static int
    613  1.1  christos msp430_dis_read (bfd_vma memaddr,
    614  1.1  christos 		 bfd_byte *myaddr,
    615  1.1  christos 		 unsigned int length,
    616  1.1  christos 		 struct disassemble_info *dinfo)
    617  1.1  christos {
    618  1.1  christos   SIM_DESC sd = dinfo->private_data;
    619  1.1  christos   sim_core_read_buffer (sd, MSP430_CPU (sd), 0, myaddr, memaddr, length);
    620  1.1  christos   return 0;
    621  1.1  christos }
    622  1.1  christos 
    623  1.1  christos #define DO_ALU(OP,SOP,MORE)						\
    624  1.1  christos   {									\
    625  1.1  christos     int s1 = DSRC;							\
    626  1.1  christos     int s2 = SRC;							\
    627  1.1  christos     int result = s1 OP s2 MORE;						\
    628  1.1  christos     if (TRACE_ALU_P (MSP430_CPU (sd)))					\
    629  1.1  christos       trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,		\
    630  1.1  christos 		     "ALU: %#x %s %#x %s = %#x", s1, SOP, s2, #MORE, result); \
    631  1.1  christos     DEST (result);							\
    632  1.1  christos   }
    633  1.1  christos 
    634  1.1  christos #define SIGN   (1 << (opcode->size - 1))
    635  1.1  christos #define POS(x) (((x) & SIGN) ? 0 : 1)
    636  1.1  christos #define NEG(x) (((x) & SIGN) ? 1 : 0)
    637  1.1  christos 
    638  1.1  christos static int
    639  1.1  christos zero_ext (int v, int bits)
    640  1.1  christos {
    641  1.1  christos   v &= ((1 << bits) - 1);
    642  1.1  christos   return v;
    643  1.1  christos }
    644  1.1  christos 
    645  1.1  christos static int
    646  1.1  christos sign_ext (int v, int bits)
    647  1.1  christos {
    648  1.1  christos   int sb = 1 << (bits-1);	/* Sign bit.  */
    649  1.1  christos   int mb = (1 << (bits-1)) - 1; /* Mantissa bits.  */
    650  1.1  christos 
    651  1.1  christos   if (v & sb)
    652  1.1  christos     v = v | ~mb;
    653  1.1  christos   else
    654  1.1  christos     v = v & mb;
    655  1.1  christos   return v;
    656  1.1  christos }
    657  1.1  christos 
    658  1.1  christos #define SX(v) sign_ext (v, opcode->size)
    659  1.1  christos #define ZX(v) zero_ext (v, opcode->size)
    660  1.1  christos 
    661  1.1  christos static char *
    662  1.1  christos flags2string (int f)
    663  1.1  christos {
    664  1.1  christos   static char buf[2][6];
    665  1.1  christos   static int bi = 0;
    666  1.1  christos   char *bp = buf[bi];
    667  1.1  christos 
    668  1.1  christos   bi = (bi + 1) % 2;
    669  1.1  christos 
    670  1.1  christos   bp[0] = f & MSP430_FLAG_V ? 'V' : '-';
    671  1.1  christos   bp[1] = f & MSP430_FLAG_N ? 'N' : '-';
    672  1.1  christos   bp[2] = f & MSP430_FLAG_Z ? 'Z' : '-';
    673  1.1  christos   bp[3] = f & MSP430_FLAG_C ? 'C' : '-';
    674  1.1  christos   bp[4] = 0;
    675  1.1  christos   return bp;
    676  1.1  christos }
    677  1.1  christos 
    678  1.1  christos /* Random number that won't show up in our usual logic.  */
    679  1.1  christos #define MAGIC_OVERFLOW 0x55000F
    680  1.1  christos 
    681  1.1  christos static void
    682  1.1  christos do_flags (SIM_DESC sd,
    683  1.1  christos 	  MSP430_Opcode_Decoded *opcode,
    684  1.1  christos 	  int vnz_val, /* Signed result.  */
    685  1.1  christos 	  int carry,
    686  1.1  christos 	  int overflow)
    687  1.1  christos {
    688  1.1  christos   int f = SR;
    689  1.1  christos   int new_f = 0;
    690  1.1  christos   int signbit = 1 << (opcode->size - 1);
    691  1.1  christos 
    692  1.1  christos   f &= ~opcode->flags_0;
    693  1.1  christos   f &= ~opcode->flags_set;
    694  1.1  christos   f |= opcode->flags_1;
    695  1.1  christos 
    696  1.1  christos   if (vnz_val & signbit)
    697  1.1  christos     new_f |= MSP430_FLAG_N;
    698  1.1  christos   if (! (vnz_val & ((signbit << 1) - 1)))
    699  1.1  christos     new_f |= MSP430_FLAG_Z;
    700  1.1  christos   if (overflow == MAGIC_OVERFLOW)
    701  1.1  christos     {
    702  1.1  christos       if (vnz_val != SX (vnz_val))
    703  1.1  christos 	new_f |= MSP430_FLAG_V;
    704  1.1  christos     }
    705  1.1  christos   else
    706  1.1  christos     if (overflow)
    707  1.1  christos       new_f |= MSP430_FLAG_V;
    708  1.1  christos   if (carry)
    709  1.1  christos     new_f |= MSP430_FLAG_C;
    710  1.1  christos 
    711  1.1  christos   new_f = f | (new_f & opcode->flags_set);
    712  1.1  christos   if (TRACE_ALU_P (MSP430_CPU (sd)))
    713  1.1  christos     {
    714  1.1  christos       if (SR != new_f)
    715  1.1  christos 	trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
    716  1.1  christos 		       "FLAGS: %s -> %s", flags2string (SR),
    717  1.1  christos 		       flags2string (new_f));
    718  1.1  christos       else
    719  1.1  christos 	trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
    720  1.1  christos 		       "FLAGS: %s", flags2string (new_f));
    721  1.1  christos     }
    722  1.1  christos   SR = new_f;
    723  1.1  christos }
    724  1.1  christos 
    725  1.1  christos #define FLAGS(vnz,c)    do_flags (sd, opcode, vnz, c, MAGIC_OVERFLOW)
    726  1.1  christos #define FLAGSV(vnz,c,v) do_flags (sd, opcode, vnz, c, v)
    727  1.1  christos 
    728  1.1  christos /* These two assume unsigned 16-bit (four digit) words.
    729  1.1  christos    Mask off unwanted bits for byte operations.  */
    730  1.1  christos 
    731  1.1  christos static int
    732  1.1  christos bcd_to_binary (int v)
    733  1.1  christos {
    734  1.1  christos   int r = (  ((v >>  0) & 0xf) * 1
    735  1.1  christos 	   + ((v >>  4) & 0xf) * 10
    736  1.1  christos 	   + ((v >>  8) & 0xf) * 100
    737  1.1  christos 	   + ((v >> 12) & 0xf) * 1000);
    738  1.1  christos   return r;
    739  1.1  christos }
    740  1.1  christos 
    741  1.1  christos static int
    742  1.1  christos binary_to_bcd (int v)
    743  1.1  christos {
    744  1.1  christos   int r = ( ((v /    1) % 10) <<  0
    745  1.1  christos 	  | ((v /   10) % 10) <<  4
    746  1.1  christos 	  | ((v /  100) % 10) <<  8
    747  1.1  christos 	  | ((v / 1000) % 10) << 12);
    748  1.1  christos   return r;
    749  1.1  christos }
    750  1.1  christos 
    751  1.1  christos static int
    752  1.1  christos syscall_read_mem (host_callback *cb, struct cb_syscall *sc,
    753  1.1  christos 		  unsigned long taddr, char *buf, int bytes)
    754  1.1  christos {
    755  1.1  christos   SIM_DESC sd = (SIM_DESC) sc->p1;
    756  1.1  christos   SIM_CPU *cpu = (SIM_CPU *) sc->p2;
    757  1.1  christos 
    758  1.1  christos   return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
    759  1.1  christos }
    760  1.1  christos 
    761  1.1  christos static int
    762  1.1  christos syscall_write_mem (host_callback *cb, struct cb_syscall *sc,
    763  1.1  christos 		  unsigned long taddr, const char *buf, int bytes)
    764  1.1  christos {
    765  1.1  christos   SIM_DESC sd = (SIM_DESC) sc->p1;
    766  1.1  christos   SIM_CPU *cpu = (SIM_CPU *) sc->p2;
    767  1.1  christos 
    768  1.1  christos   return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
    769  1.1  christos }
    770  1.1  christos 
    771  1.1  christos static const char *
    772  1.1  christos cond_string (int cond)
    773  1.1  christos {
    774  1.1  christos   switch (cond)
    775  1.1  christos     {
    776  1.1  christos     case MSC_nz:
    777  1.1  christos       return "NZ";
    778  1.1  christos     case MSC_z:
    779  1.1  christos       return "Z";
    780  1.1  christos     case MSC_nc:
    781  1.1  christos       return "NC";
    782  1.1  christos     case MSC_c:
    783  1.1  christos       return "C";
    784  1.1  christos     case MSC_n:
    785  1.1  christos       return "N";
    786  1.1  christos     case MSC_ge:
    787  1.1  christos       return "GE";
    788  1.1  christos     case MSC_l:
    789  1.1  christos       return "L";
    790  1.1  christos     case MSC_true:
    791  1.1  christos       return "MP";
    792  1.1  christos     default:
    793  1.1  christos       return "??";
    794  1.1  christos     }
    795  1.1  christos }
    796  1.1  christos 
    797  1.1  christos /* Checks a CALL to address CALL_ADDR.  If this is a special
    798  1.1  christos    syscall address then the call is simulated and non-zero is
    799  1.1  christos    returned.  Otherwise 0 is returned.  */
    800  1.1  christos 
    801  1.1  christos static int
    802  1.1  christos maybe_perform_syscall (SIM_DESC sd, int call_addr)
    803  1.1  christos {
    804  1.1  christos   if (call_addr == 0x00160)
    805  1.1  christos     {
    806  1.1  christos       int i;
    807  1.1  christos 
    808  1.1  christos       for (i = 0; i < 16; i++)
    809  1.1  christos 	{
    810  1.1  christos 	  if (i % 4 == 0)
    811  1.1  christos 	    fprintf (stderr, "\t");
    812  1.1  christos 	  fprintf (stderr, "R%-2d %05x   ", i, MSP430_CPU (sd)->state.regs[i]);
    813  1.1  christos 	  if (i % 4 == 3)
    814  1.1  christos 	    {
    815  1.1  christos 	      int sp = SP + (3 - (i / 4)) * 2;
    816  1.1  christos 	      unsigned char buf[2];
    817  1.1  christos 
    818  1.1  christos 	      sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, sp, 2);
    819  1.1  christos 
    820  1.1  christos 	      fprintf (stderr, "\tSP%+d: %04x", sp - SP,
    821  1.1  christos 		       buf[0] + buf[1] * 256);
    822  1.1  christos 
    823  1.1  christos 	      if (i / 4 == 0)
    824  1.1  christos 		{
    825  1.1  christos 		  int flags = SR;
    826  1.1  christos 
    827  1.1  christos 		  fprintf (stderr, flags & 0x100 ? "   V" : "   -");
    828  1.1  christos 		  fprintf (stderr, flags & 0x004 ? "N" : "-");
    829  1.1  christos 		  fprintf (stderr, flags & 0x002 ? "Z" : "-");
    830  1.1  christos 		  fprintf (stderr, flags & 0x001 ? "C" : "-");
    831  1.1  christos 		}
    832  1.1  christos 
    833  1.1  christos 	      fprintf (stderr, "\n");
    834  1.1  christos 	    }
    835  1.1  christos 	}
    836  1.1  christos       return 1;
    837  1.1  christos     }
    838  1.1  christos 
    839  1.1  christos   if ((call_addr & ~0x3f) == 0x00180)
    840  1.1  christos     {
    841  1.1  christos       /* Syscall!  */
    842  1.1  christos       int syscall_num = call_addr & 0x3f;
    843  1.1  christos       host_callback *cb = STATE_CALLBACK (sd);
    844  1.1  christos       CB_SYSCALL sc;
    845  1.1  christos 
    846  1.1  christos       CB_SYSCALL_INIT (&sc);
    847  1.1  christos 
    848  1.1  christos       sc.func = syscall_num;
    849  1.1  christos       sc.arg1 = MSP430_CPU (sd)->state.regs[12];
    850  1.1  christos       sc.arg2 = MSP430_CPU (sd)->state.regs[13];
    851  1.1  christos       sc.arg3 = MSP430_CPU (sd)->state.regs[14];
    852  1.1  christos       sc.arg4 = MSP430_CPU (sd)->state.regs[15];
    853  1.1  christos 
    854  1.1  christos       if (TRACE_SYSCALL_P (MSP430_CPU (sd)))
    855  1.1  christos 	{
    856  1.1  christos 	  const char *syscall_name = "*unknown*";
    857  1.1  christos 
    858  1.1  christos 	  switch (syscall_num)
    859  1.1  christos 	    {
    860  1.1  christos 	    case TARGET_SYS_exit:
    861  1.1  christos 	      syscall_name = "exit(%d)";
    862  1.1  christos 	      break;
    863  1.1  christos 	    case TARGET_SYS_open:
    864  1.1  christos 	      syscall_name = "open(%#x,%#x)";
    865  1.1  christos 	      break;
    866  1.1  christos 	    case TARGET_SYS_close:
    867  1.1  christos 	      syscall_name = "close(%d)";
    868  1.1  christos 	      break;
    869  1.1  christos 	    case TARGET_SYS_read:
    870  1.1  christos 	      syscall_name = "read(%d,%#x,%d)";
    871  1.1  christos 	      break;
    872  1.1  christos 	    case TARGET_SYS_write:
    873  1.1  christos 	      syscall_name = "write(%d,%#x,%d)";
    874  1.1  christos 	      break;
    875  1.1  christos 	    }
    876  1.1  christos 	  trace_generic (sd, MSP430_CPU (sd), TRACE_SYSCALL_IDX,
    877  1.1  christos 			 syscall_name, sc.arg1, sc.arg2, sc.arg3, sc.arg4);
    878  1.1  christos 	}
    879  1.1  christos 
    880  1.1  christos       /* Handle SYS_exit here.  */
    881  1.1  christos       if (syscall_num == 1)
    882  1.1  christos 	{
    883  1.1  christos 	  sim_engine_halt (sd, MSP430_CPU (sd), NULL,
    884  1.1  christos 			   MSP430_CPU (sd)->state.regs[0],
    885  1.1  christos 			   sim_exited, sc.arg1);
    886  1.1  christos 	  return 1;
    887  1.1  christos 	}
    888  1.1  christos 
    889  1.1  christos       sc.p1 = sd;
    890  1.1  christos       sc.p2 = MSP430_CPU (sd);
    891  1.1  christos       sc.read_mem = syscall_read_mem;
    892  1.1  christos       sc.write_mem = syscall_write_mem;
    893  1.1  christos 
    894  1.1  christos       cb_syscall (cb, &sc);
    895  1.1  christos 
    896  1.1  christos       if (TRACE_SYSCALL_P (MSP430_CPU (sd)))
    897  1.1  christos 	trace_generic (sd, MSP430_CPU (sd), TRACE_SYSCALL_IDX,
    898  1.1  christos 		       "returns %d", sc.result);
    899  1.1  christos 
    900  1.1  christos       MSP430_CPU (sd)->state.regs[12] = sc.result;
    901  1.1  christos       return 1;
    902  1.1  christos     }
    903  1.1  christos 
    904  1.1  christos   return 0;
    905  1.1  christos }
    906  1.1  christos 
    907  1.1  christos static void
    908  1.1  christos msp430_step_once (SIM_DESC sd)
    909  1.1  christos {
    910  1.1  christos   Get_Byte_Local_Data ld;
    911  1.1  christos   unsigned char buf[100];
    912  1.1  christos   int i;
    913  1.1  christos   int opsize;
    914  1.1  christos   unsigned int opcode_pc;
    915  1.1  christos   MSP430_Opcode_Decoded opcode_buf;
    916  1.1  christos   MSP430_Opcode_Decoded *opcode = &opcode_buf;
    917  1.1  christos   int s1, s2, result;
    918  1.1  christos   int u1, u2, uresult;
    919  1.1  christos   int c, reg;
    920  1.1  christos   int sp;
    921  1.1  christos   int carry_to_use;
    922  1.1  christos   int n_repeats;
    923  1.1  christos   int rept;
    924  1.1  christos   int op_bytes, op_bits;
    925  1.1  christos 
    926  1.1  christos   PC &= 0xfffff;
    927  1.1  christos   opcode_pc = PC;
    928  1.1  christos 
    929  1.1  christos   if (opcode_pc < 0x10)
    930  1.1  christos     {
    931  1.1  christos       fprintf (stderr, "Fault: PC(%#x) is less than 0x10\n", opcode_pc);
    932  1.1  christos       sim_engine_halt (sd, MSP430_CPU (sd), NULL,
    933  1.1  christos 		       MSP430_CPU (sd)->state.regs[0],
    934  1.1  christos 		       sim_exited, -1);
    935  1.1  christos       return;
    936  1.1  christos     }
    937  1.1  christos 
    938  1.1  christos   if (PC == MSP430_CPU (sd)->state.cio_breakpoint
    939  1.1  christos       && STATE_OPEN_KIND (sd) != SIM_OPEN_DEBUG)
    940  1.1  christos     msp430_cio (sd);
    941  1.1  christos 
    942  1.1  christos   ld.sd = sd;
    943  1.1  christos   ld.gb_addr = PC;
    944  1.1  christos   opsize = msp430_decode_opcode (MSP430_CPU (sd)->state.regs[0],
    945  1.1  christos 				 opcode, msp430_getbyte, &ld);
    946  1.1  christos   PC += opsize;
    947  1.1  christos   if (opsize <= 0)
    948  1.1  christos     {
    949  1.1  christos       fprintf (stderr, "Fault: undecodable opcode at %#x\n", opcode_pc);
    950  1.1  christos       sim_engine_halt (sd, MSP430_CPU (sd), NULL,
    951  1.1  christos 		       MSP430_CPU (sd)->state.regs[0],
    952  1.1  christos 		       sim_exited, -1);
    953  1.1  christos       return;
    954  1.1  christos     }
    955  1.1  christos 
    956  1.1  christos   if (opcode->repeat_reg)
    957  1.1  christos     n_repeats = (MSP430_CPU (sd)->state.regs[opcode->repeats] & 0x000f) + 1;
    958  1.1  christos   else
    959  1.1  christos     n_repeats = opcode->repeats + 1;
    960  1.1  christos 
    961  1.1  christos   op_bits = opcode->size;
    962  1.1  christos   switch (op_bits)
    963  1.1  christos     {
    964  1.1  christos     case 8:
    965  1.1  christos       op_bytes = 1;
    966  1.1  christos       break;
    967  1.1  christos     case 16:
    968  1.1  christos       op_bytes = 2;
    969  1.1  christos       break;
    970  1.1  christos     case 20:
    971  1.1  christos     case 32:
    972  1.1  christos       op_bytes = 4;
    973  1.1  christos       break;
    974  1.1  christos     }
    975  1.1  christos 
    976  1.1  christos   if (TRACE_INSN_P (MSP430_CPU (sd)))
    977  1.1  christos     {
    978  1.1  christos       disassemble_info info;
    979  1.1  christos       unsigned char b[10];
    980  1.1  christos 
    981  1.1  christos       msp430_trace_one (opcode_pc);
    982  1.1  christos 
    983  1.1  christos       sim_core_read_buffer (sd, MSP430_CPU (sd), 0, b, opcode_pc, opsize);
    984  1.1  christos 
    985  1.1  christos       init_disassemble_info (&info, stderr, fprintf);
    986  1.1  christos       info.private_data = sd;
    987  1.1  christos       info.read_memory_func = msp430_dis_read;
    988  1.1  christos       fprintf (stderr, "%#8x  ", opcode_pc);
    989  1.1  christos       for (i = 0; i < opsize; i += 2)
    990  1.1  christos 	fprintf (stderr, " %02x%02x", b[i+1], b[i]);
    991  1.1  christos       for (; i < 6; i += 2)
    992  1.1  christos 	fprintf (stderr, "     ");
    993  1.1  christos       fprintf (stderr, "  ");
    994  1.1  christos       print_insn_msp430 (opcode_pc, &info);
    995  1.1  christos       fprintf (stderr, "\n");
    996  1.1  christos       fflush (stdout);
    997  1.1  christos     }
    998  1.1  christos 
    999  1.1  christos   if (TRACE_ANY_P (MSP430_CPU (sd)))
   1000  1.1  christos     trace_prefix (sd, MSP430_CPU (sd), NULL_CIA, opcode_pc,
   1001  1.1  christos     TRACE_LINENUM_P (MSP430_CPU (sd)), NULL, 0, "");
   1002  1.1  christos 
   1003  1.1  christos   carry_to_use = 0;
   1004  1.1  christos   switch (opcode->id)
   1005  1.1  christos     {
   1006  1.1  christos     case MSO_unknown:
   1007  1.1  christos       break;
   1008  1.1  christos 
   1009  1.1  christos       /* Double-operand instructions.  */
   1010  1.1  christos     case MSO_mov:
   1011  1.1  christos       if (opcode->n_bytes == 2
   1012  1.1  christos 	  && opcode->op[0].type == MSP430_Operand_Register
   1013  1.1  christos 	  && opcode->op[0].reg == MSR_CG
   1014  1.1  christos 	  && opcode->op[1].type == MSP430_Operand_Immediate
   1015  1.1  christos 	  && opcode->op[1].addend == 0
   1016  1.1  christos 	  /* A 16-bit write of #0 is a NOP; an 8-bit write is a BRK.  */
   1017  1.1  christos 	  && opcode->size == 8)
   1018  1.1  christos 	{
   1019  1.1  christos 	  /* This is the designated software breakpoint instruction.  */
   1020  1.1  christos 	  PC -= opsize;
   1021  1.1  christos 	  sim_engine_halt (sd, MSP430_CPU (sd), NULL,
   1022  1.1  christos 			   MSP430_CPU (sd)->state.regs[0],
   1023  1.1  christos 			   sim_stopped, SIM_SIGTRAP);
   1024  1.1  christos 
   1025  1.1  christos 	}
   1026  1.1  christos       else
   1027  1.1  christos 	{
   1028  1.1  christos 	  /* Otherwise, do the move.  */
   1029  1.1  christos 	  for (rept = 0; rept < n_repeats; rept ++)
   1030  1.1  christos 	    {
   1031  1.1  christos 	      DEST (SRC);
   1032  1.1  christos 	    }
   1033  1.1  christos 	}
   1034  1.1  christos       break;
   1035  1.1  christos 
   1036  1.1  christos     case MSO_addc:
   1037  1.1  christos       for (rept = 0; rept < n_repeats; rept ++)
   1038  1.1  christos 	{
   1039  1.1  christos 	  carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0;
   1040  1.1  christos 	  u1 = DSRC;
   1041  1.1  christos 	  u2 = SRC;
   1042  1.1  christos 	  s1 = SX (u1);
   1043  1.1  christos 	  s2 = SX (u2);
   1044  1.1  christos 	  uresult = u1 + u2 + carry_to_use;
   1045  1.1  christos 	  result = s1 + s2 + carry_to_use;
   1046  1.1  christos 	  if (TRACE_ALU_P (MSP430_CPU (sd)))
   1047  1.1  christos 	    trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
   1048  1.1  christos 			   "ADDC: %#x + %#x + %d = %#x",
   1049  1.1  christos 			   u1, u2, carry_to_use, uresult);
   1050  1.1  christos 	  DEST (result);
   1051  1.1  christos 	  FLAGS (result, uresult != ZX (uresult));
   1052  1.1  christos 	}
   1053  1.1  christos       break;
   1054  1.1  christos 
   1055  1.1  christos     case MSO_add:
   1056  1.1  christos       for (rept = 0; rept < n_repeats; rept ++)
   1057  1.1  christos 	{
   1058  1.1  christos 	  u1 = DSRC;
   1059  1.1  christos 	  u2 = SRC;
   1060  1.1  christos 	  s1 = SX (u1);
   1061  1.1  christos 	  s2 = SX (u2);
   1062  1.1  christos 	  uresult = u1 + u2;
   1063  1.1  christos 	  result = s1 + s2;
   1064  1.1  christos 	  if (TRACE_ALU_P (MSP430_CPU (sd)))
   1065  1.1  christos 	    trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
   1066  1.1  christos 			   "ADD: %#x + %#x = %#x",
   1067  1.1  christos 			   u1, u2, uresult);
   1068  1.1  christos 	  DEST (result);
   1069  1.1  christos 	  FLAGS (result, uresult != ZX (uresult));
   1070  1.1  christos 	}
   1071  1.1  christos       break;
   1072  1.1  christos 
   1073  1.1  christos     case MSO_subc:
   1074  1.1  christos       for (rept = 0; rept < n_repeats; rept ++)
   1075  1.1  christos 	{
   1076  1.1  christos 	  carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0;
   1077  1.1  christos 	  u1 = DSRC;
   1078  1.1  christos 	  u2 = SRC;
   1079  1.1  christos 	  s1 = SX (u1);
   1080  1.1  christos 	  s2 = SX (u2);
   1081  1.1  christos 	  uresult = ZX (~u2) + u1 + carry_to_use;
   1082  1.1  christos 	  result = s1 - s2 + (carry_to_use - 1);
   1083  1.1  christos 	  if (TRACE_ALU_P (MSP430_CPU (sd)))
   1084  1.1  christos 	    trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
   1085  1.1  christos 			   "SUBC: %#x - %#x + %d = %#x",
   1086  1.1  christos 			   u1, u2, carry_to_use, uresult);
   1087  1.1  christos 	  DEST (result);
   1088  1.1  christos 	  FLAGS (result, uresult != ZX (uresult));
   1089  1.1  christos 	}
   1090  1.1  christos       break;
   1091  1.1  christos 
   1092  1.1  christos     case MSO_sub:
   1093  1.1  christos       for (rept = 0; rept < n_repeats; rept ++)
   1094  1.1  christos 	{
   1095  1.1  christos 	  u1 = DSRC;
   1096  1.1  christos 	  u2 = SRC;
   1097  1.1  christos 	  s1 = SX (u1);
   1098  1.1  christos 	  s2 = SX (u2);
   1099  1.1  christos 	  uresult = ZX (~u2) + u1 + 1;
   1100  1.1  christos 	  result = SX (uresult);
   1101  1.1  christos 	  if (TRACE_ALU_P (MSP430_CPU (sd)))
   1102  1.1  christos 	    trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
   1103  1.1  christos 			   "SUB: %#x - %#x = %#x",
   1104  1.1  christos 			   u1, u2, uresult);
   1105  1.1  christos 	  DEST (result);
   1106  1.1  christos 	  FLAGS (result, uresult != ZX (uresult));
   1107  1.1  christos 	}
   1108  1.1  christos       break;
   1109  1.1  christos 
   1110  1.1  christos     case MSO_cmp:
   1111  1.1  christos       for (rept = 0; rept < n_repeats; rept ++)
   1112  1.1  christos 	{
   1113  1.1  christos 	  u1 = DSRC;
   1114  1.1  christos 	  u2 = SRC;
   1115  1.1  christos 	  s1 = SX (u1);
   1116  1.1  christos 	  s2 = SX (u2);
   1117  1.1  christos 	  uresult = ZX (~u2) + u1 + 1;
   1118  1.1  christos 	  result = s1 - s2;
   1119  1.1  christos 	  if (TRACE_ALU_P (MSP430_CPU (sd)))
   1120  1.1  christos 	    trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
   1121  1.1  christos 			   "CMP: %#x - %#x = %x",
   1122  1.1  christos 			   u1, u2, uresult);
   1123  1.1  christos 	  FLAGS (result, uresult != ZX (uresult));
   1124  1.1  christos 	}
   1125  1.1  christos       break;
   1126  1.1  christos 
   1127  1.1  christos     case MSO_dadd:
   1128  1.1  christos       for (rept = 0; rept < n_repeats; rept ++)
   1129  1.1  christos 	{
   1130  1.1  christos 	  carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0;
   1131  1.1  christos 	  u1 = DSRC;
   1132  1.1  christos 	  u2 = SRC;
   1133  1.1  christos 	  uresult = bcd_to_binary (u1) + bcd_to_binary (u2) + carry_to_use;
   1134  1.1  christos 	  result = binary_to_bcd (uresult);
   1135  1.1  christos 	  if (TRACE_ALU_P (MSP430_CPU (sd)))
   1136  1.1  christos 	    trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
   1137  1.1  christos 			   "DADD: %#x + %#x + %d = %#x",
   1138  1.1  christos 			   u1, u2, carry_to_use, result);
   1139  1.1  christos 	  DEST (result);
   1140  1.1  christos 	  FLAGS (result, uresult > ((opcode->size == 8) ? 99 : 9999));
   1141  1.1  christos 	}
   1142  1.1  christos       break;
   1143  1.1  christos 
   1144  1.1  christos     case MSO_and:
   1145  1.1  christos       for (rept = 0; rept < n_repeats; rept ++)
   1146  1.1  christos 	{
   1147  1.1  christos 	  u1 = DSRC;
   1148  1.1  christos 	  u2 = SRC;
   1149  1.1  christos 	  uresult = u1 & u2;
   1150  1.1  christos 	  if (TRACE_ALU_P (MSP430_CPU (sd)))
   1151  1.1  christos 	    trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
   1152  1.1  christos 			   "AND: %#x & %#x = %#x",
   1153  1.1  christos 			   u1, u2, uresult);
   1154  1.1  christos 	  DEST (uresult);
   1155  1.1  christos 	  FLAGS (uresult, uresult != 0);
   1156  1.1  christos 	}
   1157  1.1  christos       break;
   1158  1.1  christos 
   1159  1.1  christos     case MSO_bit:
   1160  1.1  christos       for (rept = 0; rept < n_repeats; rept ++)
   1161  1.1  christos 	{
   1162  1.1  christos 	  u1 = DSRC;
   1163  1.1  christos 	  u2 = SRC;
   1164  1.1  christos 	  uresult = u1 & u2;
   1165  1.1  christos 	  if (TRACE_ALU_P (MSP430_CPU (sd)))
   1166  1.1  christos 	    trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
   1167  1.1  christos 			   "BIT: %#x & %#x -> %#x",
   1168  1.1  christos 			   u1, u2, uresult);
   1169  1.1  christos 	  FLAGS (uresult, uresult != 0);
   1170  1.1  christos 	}
   1171  1.1  christos       break;
   1172  1.1  christos 
   1173  1.1  christos     case MSO_bic:
   1174  1.1  christos       for (rept = 0; rept < n_repeats; rept ++)
   1175  1.1  christos 	{
   1176  1.1  christos 	  u1 = DSRC;
   1177  1.1  christos 	  u2 = SRC;
   1178  1.1  christos 	  uresult = u1 & ~ u2;
   1179  1.1  christos 	  if (TRACE_ALU_P (MSP430_CPU (sd)))
   1180  1.1  christos 	    trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
   1181  1.1  christos 			   "BIC: %#x & ~ %#x = %#x",
   1182  1.1  christos 			   u1, u2, uresult);
   1183  1.1  christos 	  DEST (uresult);
   1184  1.1  christos 	}
   1185  1.1  christos       break;
   1186  1.1  christos 
   1187  1.1  christos     case MSO_bis:
   1188  1.1  christos       for (rept = 0; rept < n_repeats; rept ++)
   1189  1.1  christos 	{
   1190  1.1  christos 	  u1 = DSRC;
   1191  1.1  christos 	  u2 = SRC;
   1192  1.1  christos 	  uresult = u1 | u2;
   1193  1.1  christos 	  if (TRACE_ALU_P (MSP430_CPU (sd)))
   1194  1.1  christos 	    trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
   1195  1.1  christos 			   "BIS: %#x | %#x = %#x",
   1196  1.1  christos 			   u1, u2, uresult);
   1197  1.1  christos 	  DEST (uresult);
   1198  1.1  christos 	}
   1199  1.1  christos       break;
   1200  1.1  christos 
   1201  1.1  christos     case MSO_xor:
   1202  1.1  christos       for (rept = 0; rept < n_repeats; rept ++)
   1203  1.1  christos 	{
   1204  1.1  christos 	  s1 = 1 << (opcode->size - 1);
   1205  1.1  christos 	  u1 = DSRC;
   1206  1.1  christos 	  u2 = SRC;
   1207  1.1  christos 	  uresult = u1 ^ u2;
   1208  1.1  christos 	  if (TRACE_ALU_P (MSP430_CPU (sd)))
   1209  1.1  christos 	    trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
   1210  1.1  christos 			   "XOR: %#x & %#x = %#x",
   1211  1.1  christos 			   u1, u2, uresult);
   1212  1.1  christos 	  DEST (uresult);
   1213  1.1  christos 	  FLAGSV (uresult, uresult != 0, (u1 & s1) && (u2 & s1));
   1214  1.1  christos 	}
   1215  1.1  christos       break;
   1216  1.1  christos 
   1217  1.1  christos     /* Single-operand instructions.  Note: the decoder puts the same
   1218  1.1  christos        operand in SRC as in DEST, for our convenience.  */
   1219  1.1  christos 
   1220  1.1  christos     case MSO_rrc:
   1221  1.1  christos       for (rept = 0; rept < n_repeats; rept ++)
   1222  1.1  christos 	{
   1223  1.1  christos 	  u1 = SRC;
   1224  1.1  christos 	  carry_to_use = u1 & 1;
   1225  1.1  christos 	  uresult = u1 >> 1;
   1226  1.1  christos 	  if (SR & MSP430_FLAG_C)
   1227  1.1  christos 	  uresult |= (1 << (opcode->size - 1));
   1228  1.1  christos 	  if (TRACE_ALU_P (MSP430_CPU (sd)))
   1229  1.1  christos 	    trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
   1230  1.1  christos 			   "RRC: %#x >>= %#x",
   1231  1.1  christos 			   u1, uresult);
   1232  1.1  christos 	  DEST (uresult);
   1233  1.1  christos 	  FLAGS (uresult, carry_to_use);
   1234  1.1  christos 	}
   1235  1.1  christos       break;
   1236  1.1  christos 
   1237  1.1  christos     case MSO_swpb:
   1238  1.1  christos       for (rept = 0; rept < n_repeats; rept ++)
   1239  1.1  christos 	{
   1240  1.1  christos 	  u1 = SRC;
   1241  1.1  christos 	  uresult = ((u1 >> 8) & 0x00ff) | ((u1 << 8) & 0xff00);
   1242  1.1  christos 	  if (TRACE_ALU_P (MSP430_CPU (sd)))
   1243  1.1  christos 	    trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
   1244  1.1  christos 			   "SWPB: %#x -> %#x",
   1245  1.1  christos 			   u1, uresult);
   1246  1.1  christos 	  DEST (uresult);
   1247  1.1  christos 	}
   1248  1.1  christos       break;
   1249  1.1  christos 
   1250  1.1  christos     case MSO_rra:
   1251  1.1  christos       for (rept = 0; rept < n_repeats; rept ++)
   1252  1.1  christos 	{
   1253  1.1  christos 	  u1 = SRC;
   1254  1.1  christos 	  c = u1 & 1;
   1255  1.1  christos 	  s1 = 1 << (opcode->size - 1);
   1256  1.1  christos 	  uresult = (u1 >> 1) | (u1 & s1);
   1257  1.1  christos 	  if (TRACE_ALU_P (MSP430_CPU (sd)))
   1258  1.1  christos 	    trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
   1259  1.1  christos 			   "RRA: %#x >>= %#x",
   1260  1.1  christos 			   u1, uresult);
   1261  1.1  christos 	  DEST (uresult);
   1262  1.1  christos 	  FLAGS (uresult, c);
   1263  1.1  christos 	}
   1264  1.1  christos       break;
   1265  1.1  christos 
   1266  1.1  christos     case MSO_rru:
   1267  1.1  christos       for (rept = 0; rept < n_repeats; rept ++)
   1268  1.1  christos 	{
   1269  1.1  christos 	  u1 = SRC;
   1270  1.1  christos 	  c = u1 & 1;
   1271  1.1  christos 	  uresult = (u1 >> 1);
   1272  1.1  christos 	  if (TRACE_ALU_P (MSP430_CPU (sd)))
   1273  1.1  christos 	    trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
   1274  1.1  christos 			   "RRU: %#x >>= %#x",
   1275  1.1  christos 			   u1, uresult);
   1276  1.1  christos 	  DEST (uresult);
   1277  1.1  christos 	  FLAGS (uresult, c);
   1278  1.1  christos 	}
   1279  1.1  christos       break;
   1280  1.1  christos 
   1281  1.1  christos     case MSO_sxt:
   1282  1.1  christos       for (rept = 0; rept < n_repeats; rept ++)
   1283  1.1  christos 	{
   1284  1.1  christos 	  u1 = SRC;
   1285  1.1  christos 	  if (u1 & 0x80)
   1286  1.1  christos 	    uresult = u1 | 0xfff00;
   1287  1.1  christos 	  else
   1288  1.1  christos 	    uresult = u1 & 0x000ff;
   1289  1.1  christos 	  if (TRACE_ALU_P (MSP430_CPU (sd)))
   1290  1.1  christos 	    trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
   1291  1.1  christos 			   "SXT: %#x -> %#x",
   1292  1.1  christos 			   u1, uresult);
   1293  1.1  christos 	  DEST (uresult);
   1294  1.1  christos 	  FLAGS (uresult, c);
   1295  1.1  christos 	}
   1296  1.1  christos       break;
   1297  1.1  christos 
   1298  1.1  christos     case MSO_push:
   1299  1.1  christos       for (rept = 0; rept < n_repeats; rept ++)
   1300  1.1  christos 	{
   1301  1.1  christos 	  int new_sp;
   1302  1.1  christos 
   1303  1.1  christos 	  new_sp = REG_GET (MSR_SP) - op_bytes;
   1304  1.1  christos 	  /* SP is always word-aligned.  */
   1305  1.1  christos 	  if (new_sp & 1)
   1306  1.1  christos 	    new_sp --;
   1307  1.1  christos 	  REG_PUT (MSR_SP, new_sp);
   1308  1.1  christos 	  u1 = SRC;
   1309  1.1  christos 	  mem_put_val (sd, SP, u1, op_bits);
   1310  1.1  christos 	  if (opcode->op[1].type == MSP430_Operand_Register)
   1311  1.1  christos 	    opcode->op[1].reg --;
   1312  1.1  christos 	}
   1313  1.1  christos       break;
   1314  1.1  christos 
   1315  1.1  christos     case MSO_pop:
   1316  1.1  christos       for (rept = 0; rept < n_repeats; rept ++)
   1317  1.1  christos 	{
   1318  1.1  christos 	  int new_sp;
   1319  1.1  christos 
   1320  1.1  christos 	  u1 = mem_get_val (sd, SP, op_bits);
   1321  1.1  christos 	  DEST (u1);
   1322  1.1  christos 	  if (opcode->op[0].type == MSP430_Operand_Register)
   1323  1.1  christos 	    opcode->op[0].reg ++;
   1324  1.1  christos 	  new_sp = REG_GET (MSR_SP) + op_bytes;
   1325  1.1  christos 	  /* SP is always word-aligned.  */
   1326  1.1  christos 	  if (new_sp & 1)
   1327  1.1  christos 	    new_sp ++;
   1328  1.1  christos 	  REG_PUT (MSR_SP, new_sp);
   1329  1.1  christos 	}
   1330  1.1  christos       break;
   1331  1.1  christos 
   1332  1.1  christos     case MSO_call:
   1333  1.1  christos       u1 = SRC;
   1334  1.1  christos 
   1335  1.1  christos       if (maybe_perform_syscall (sd, u1))
   1336  1.1  christos 	break;
   1337  1.1  christos 
   1338  1.1  christos       REG_PUT (MSR_SP, REG_GET (MSR_SP) - op_bytes);
   1339  1.1  christos       mem_put_val (sd, SP, PC, op_bits);
   1340  1.1  christos       if (TRACE_ALU_P (MSP430_CPU (sd)))
   1341  1.1  christos 	trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
   1342  1.1  christos 		       "CALL: func %#x ret %#x, sp %#x",
   1343  1.1  christos 		       u1, PC, SP);
   1344  1.1  christos       REG_PUT (MSR_PC, u1);
   1345  1.1  christos       break;
   1346  1.1  christos 
   1347  1.1  christos     case MSO_reti:
   1348  1.1  christos       SR = mem_get_val (sd, SP, op_bits);
   1349  1.1  christos       SP += 2;
   1350  1.1  christos       PC = mem_get_val (sd, SP, op_bits);
   1351  1.1  christos       SP += 2;
   1352  1.1  christos       if (TRACE_ALU_P (MSP430_CPU (sd)))
   1353  1.1  christos 	trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
   1354  1.1  christos 		       "RETI: pc %#x sr %#x",
   1355  1.1  christos 		       PC, SR);
   1356  1.1  christos       break;
   1357  1.1  christos 
   1358  1.1  christos       /* Jumps.  */
   1359  1.1  christos 
   1360  1.1  christos     case MSO_jmp:
   1361  1.1  christos       i = SRC;
   1362  1.1  christos       switch (opcode->cond)
   1363  1.1  christos 	{
   1364  1.1  christos 	case MSC_nz:
   1365  1.1  christos 	  u1 = (SR & MSP430_FLAG_Z) ? 0 : 1;
   1366  1.1  christos 	  break;
   1367  1.1  christos 	case MSC_z:
   1368  1.1  christos 	  u1 = (SR & MSP430_FLAG_Z) ? 1 : 0;
   1369  1.1  christos 	  break;
   1370  1.1  christos 	case MSC_nc:
   1371  1.1  christos 	  u1 = (SR & MSP430_FLAG_C) ? 0 : 1;
   1372  1.1  christos 	  break;
   1373  1.1  christos 	case MSC_c:
   1374  1.1  christos 	  u1 = (SR & MSP430_FLAG_C) ? 1 : 0;
   1375  1.1  christos 	  break;
   1376  1.1  christos 	case MSC_n:
   1377  1.1  christos 	  u1 = (SR & MSP430_FLAG_N) ? 1 : 0;
   1378  1.1  christos 	  break;
   1379  1.1  christos 	case MSC_ge:
   1380  1.1  christos 	  u1 = (!!(SR & MSP430_FLAG_N) == !!(SR & MSP430_FLAG_V)) ? 1 : 0;
   1381  1.1  christos 	  break;
   1382  1.1  christos 	case MSC_l:
   1383  1.1  christos 	  u1 = (!!(SR & MSP430_FLAG_N) == !!(SR & MSP430_FLAG_V)) ? 0 : 1;
   1384  1.1  christos 	  break;
   1385  1.1  christos 	case MSC_true:
   1386  1.1  christos 	  u1 = 1;
   1387  1.1  christos 	  break;
   1388  1.1  christos 	}
   1389  1.1  christos 
   1390  1.1  christos       if (u1)
   1391  1.1  christos 	{
   1392  1.1  christos 	  if (TRACE_BRANCH_P (MSP430_CPU (sd)))
   1393  1.1  christos 	    trace_generic (sd, MSP430_CPU (sd), TRACE_BRANCH_IDX,
   1394  1.1  christos 			   "J%s: pc %#x -> %#x sr %#x, taken",
   1395  1.1  christos 			   cond_string (opcode->cond), PC, i, SR);
   1396  1.1  christos 	  PC = i;
   1397  1.1  christos 	  if (PC == opcode_pc)
   1398  1.1  christos 	    exit (0);
   1399  1.1  christos 	}
   1400  1.1  christos       else
   1401  1.1  christos 	if (TRACE_BRANCH_P (MSP430_CPU (sd)))
   1402  1.1  christos 	  trace_generic (sd, MSP430_CPU (sd), TRACE_BRANCH_IDX,
   1403  1.1  christos 			 "J%s: pc %#x to %#x sr %#x, not taken",
   1404  1.1  christos 			 cond_string (opcode->cond), PC, i, SR);
   1405  1.1  christos       break;
   1406  1.1  christos 
   1407  1.1  christos     default:
   1408  1.1  christos       fprintf (stderr, "error: unexpected opcode id %d\n", opcode->id);
   1409  1.1  christos       exit (1);
   1410  1.1  christos     }
   1411  1.1  christos }
   1412  1.1  christos 
   1413  1.1  christos void
   1414  1.1  christos sim_engine_run (SIM_DESC sd,
   1415  1.1  christos 		int next_cpu_nr,
   1416  1.1  christos 		int nr_cpus,
   1417  1.1  christos 		int siggnal)
   1418  1.1  christos {
   1419  1.1  christos   while (1)
   1420  1.1  christos     {
   1421  1.1  christos       msp430_step_once (sd);
   1422  1.1  christos       if (sim_events_tick (sd))
   1423  1.1  christos 	sim_events_process (sd);
   1424  1.1  christos     }
   1425  1.1  christos }
   1426