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