1#include "config.h"
2
3#include <signal.h>
4#include <errno.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7#ifdef HAVE_UNISTD_H
8#include <unistd.h>
9#endif
10#ifdef HAVE_STRING_H
11#include <string.h>
12#endif
13
14#include "d10v_sim.h"
15#include "simops.h"
16#include "targ-vals.h"
17
18extern char *strrchr ();
19
20enum op_types {
21  OP_VOID,
22  OP_REG,
23  OP_REG_OUTPUT,
24  OP_DREG,
25  OP_DREG_OUTPUT,
26  OP_ACCUM,
27  OP_ACCUM_OUTPUT,
28  OP_ACCUM_REVERSE,
29  OP_CR,
30  OP_CR_OUTPUT,
31  OP_CR_REVERSE,
32  OP_FLAG,
33  OP_FLAG_OUTPUT,
34  OP_CONSTANT16,
35  OP_CONSTANT8,
36  OP_CONSTANT3,
37  OP_CONSTANT4,
38  OP_MEMREF,
39  OP_MEMREF2,
40  OP_MEMREF3,
41  OP_POSTDEC,
42  OP_POSTINC,
43  OP_PREDEC,
44  OP_R0,
45  OP_R1,
46  OP_R2,
47};
48
49
50enum {
51  PSW_MASK = (PSW_SM_BIT
52	      | PSW_EA_BIT
53	      | PSW_DB_BIT
54	      | PSW_IE_BIT
55	      | PSW_RP_BIT
56	      | PSW_MD_BIT
57	      | PSW_FX_BIT
58	      | PSW_ST_BIT
59	      | PSW_F0_BIT
60	      | PSW_F1_BIT
61	      | PSW_C_BIT),
62  /* The following bits in the PSW _can't_ be set by instructions such
63     as mvtc. */
64  PSW_HW_MASK = (PSW_MASK | PSW_DM_BIT)
65};
66
67reg_t
68move_to_cr (int cr, reg_t mask, reg_t val, int psw_hw_p)
69{
70  /* A MASK bit is set when the corresponding bit in the CR should
71     be left alone */
72  /* This assumes that (VAL & MASK) == 0 */
73  switch (cr)
74    {
75    case PSW_CR:
76      if (psw_hw_p)
77	val &= PSW_HW_MASK;
78      else
79	val &= PSW_MASK;
80      if ((mask & PSW_SM_BIT) == 0)
81	{
82	  int new_psw_sm = (val & PSW_SM_BIT) != 0;
83	  /* save old SP */
84	  SET_HELD_SP (PSW_SM, GPR (SP_IDX));
85	  if (PSW_SM != new_psw_sm)
86	    /* restore new SP */
87	    SET_GPR (SP_IDX, HELD_SP (new_psw_sm));
88	}
89      if ((mask & (PSW_ST_BIT | PSW_FX_BIT)) == 0)
90	{
91	  if (val & PSW_ST_BIT && !(val & PSW_FX_BIT))
92	    {
93	      (*d10v_callback->printf_filtered)
94		(d10v_callback,
95		 "ERROR at PC 0x%x: ST can only be set when FX is set.\n",
96		 PC<<2);
97	      State.exception = SIGILL;
98	    }
99	}
100      /* keep an up-to-date psw around for tracing */
101      State.trace.psw = (State.trace.psw & mask) | val;
102      break;
103    case BPSW_CR:
104    case DPSW_CR:
105      /* Just like PSW, mask things like DM out. */
106      if (psw_hw_p)
107	val &= PSW_HW_MASK;
108      else
109	val &= PSW_MASK;
110      break;
111    case MOD_S_CR:
112    case MOD_E_CR:
113      val &= ~1;
114      break;
115    default:
116      break;
117    }
118  /* only issue an update if the register is being changed */
119  if ((State.cregs[cr] & ~mask) != val)
120    SLOT_PEND_MASK (State.cregs[cr], mask, val);
121  return val;
122}
123
124#ifdef DEBUG
125static void trace_input_func PARAMS ((char *name,
126				      enum op_types in1,
127				      enum op_types in2,
128				      enum op_types in3));
129
130#define trace_input(name, in1, in2, in3) do { if (d10v_debug) trace_input_func (name, in1, in2, in3); } while (0)
131
132#ifndef SIZE_INSTRUCTION
133#define SIZE_INSTRUCTION 8
134#endif
135
136#ifndef SIZE_OPERANDS
137#define SIZE_OPERANDS 18
138#endif
139
140#ifndef SIZE_VALUES
141#define SIZE_VALUES 13
142#endif
143
144#ifndef SIZE_LOCATION
145#define SIZE_LOCATION 20
146#endif
147
148#ifndef SIZE_PC
149#define SIZE_PC 6
150#endif
151
152#ifndef SIZE_LINE_NUMBER
153#define SIZE_LINE_NUMBER 4
154#endif
155
156static void
157trace_input_func (name, in1, in2, in3)
158     char *name;
159     enum op_types in1;
160     enum op_types in2;
161     enum op_types in3;
162{
163  char *comma;
164  enum op_types in[3];
165  int i;
166  char buf[1024];
167  char *p;
168  long tmp;
169  char *type;
170  const char *filename;
171  const char *functionname;
172  unsigned int linenumber;
173  bfd_vma byte_pc;
174
175  if ((d10v_debug & DEBUG_TRACE) == 0)
176    return;
177
178  switch (State.ins_type)
179    {
180    default:
181    case INS_UNKNOWN:		type = " ?"; break;
182    case INS_LEFT:		type = " L"; break;
183    case INS_RIGHT:		type = " R"; break;
184    case INS_LEFT_PARALLEL:	type = "*L"; break;
185    case INS_RIGHT_PARALLEL:	type = "*R"; break;
186    case INS_LEFT_COND_TEST:	type = "?L"; break;
187    case INS_RIGHT_COND_TEST:	type = "?R"; break;
188    case INS_LEFT_COND_EXE:	type = "&L"; break;
189    case INS_RIGHT_COND_EXE:	type = "&R"; break;
190    case INS_LONG:		type = " B"; break;
191    }
192
193  if ((d10v_debug & DEBUG_LINE_NUMBER) == 0)
194    (*d10v_callback->printf_filtered) (d10v_callback,
195				       "0x%.*x %s: %-*s ",
196				       SIZE_PC, (unsigned)PC,
197				       type,
198				       SIZE_INSTRUCTION, name);
199
200  else
201    {
202      buf[0] = '\0';
203      byte_pc = decode_pc ();
204      if (text && byte_pc >= text_start && byte_pc < text_end)
205	{
206	  filename = (const char *)0;
207	  functionname = (const char *)0;
208	  linenumber = 0;
209	  if (bfd_find_nearest_line (prog_bfd, text, (struct bfd_symbol **)0, byte_pc - text_start,
210				     &filename, &functionname, &linenumber))
211	    {
212	      p = buf;
213	      if (linenumber)
214		{
215		  sprintf (p, "#%-*d ", SIZE_LINE_NUMBER, linenumber);
216		  p += strlen (p);
217		}
218	      else
219		{
220		  sprintf (p, "%-*s ", SIZE_LINE_NUMBER+1, "---");
221		  p += SIZE_LINE_NUMBER+2;
222		}
223
224	      if (functionname)
225		{
226		  sprintf (p, "%s ", functionname);
227		  p += strlen (p);
228		}
229	      else if (filename)
230		{
231		  char *q = strrchr (filename, '/');
232		  sprintf (p, "%s ", (q) ? q+1 : filename);
233		  p += strlen (p);
234		}
235
236	      if (*p == ' ')
237		*p = '\0';
238	    }
239	}
240
241      (*d10v_callback->printf_filtered) (d10v_callback,
242					 "0x%.*x %s: %-*.*s %-*s ",
243					 SIZE_PC, (unsigned)PC,
244					 type,
245					 SIZE_LOCATION, SIZE_LOCATION, buf,
246					 SIZE_INSTRUCTION, name);
247    }
248
249  in[0] = in1;
250  in[1] = in2;
251  in[2] = in3;
252  comma = "";
253  p = buf;
254  for (i = 0; i < 3; i++)
255    {
256      switch (in[i])
257	{
258	case OP_VOID:
259	case OP_R0:
260	case OP_R1:
261	case OP_R2:
262	  break;
263
264	case OP_REG:
265	case OP_REG_OUTPUT:
266	case OP_DREG:
267	case OP_DREG_OUTPUT:
268	  sprintf (p, "%sr%d", comma, OP[i]);
269	  p += strlen (p);
270	  comma = ",";
271	  break;
272
273	case OP_CR:
274	case OP_CR_OUTPUT:
275	case OP_CR_REVERSE:
276	  sprintf (p, "%scr%d", comma, OP[i]);
277	  p += strlen (p);
278	  comma = ",";
279	  break;
280
281	case OP_ACCUM:
282	case OP_ACCUM_OUTPUT:
283	case OP_ACCUM_REVERSE:
284	  sprintf (p, "%sa%d", comma, OP[i]);
285	  p += strlen (p);
286	  comma = ",";
287	  break;
288
289	case OP_CONSTANT16:
290	  sprintf (p, "%s%d", comma, OP[i]);
291	  p += strlen (p);
292	  comma = ",";
293	  break;
294
295	case OP_CONSTANT8:
296	  sprintf (p, "%s%d", comma, SEXT8(OP[i]));
297	  p += strlen (p);
298	  comma = ",";
299	  break;
300
301	case OP_CONSTANT4:
302	  sprintf (p, "%s%d", comma, SEXT4(OP[i]));
303	  p += strlen (p);
304	  comma = ",";
305	  break;
306
307	case OP_CONSTANT3:
308	  sprintf (p, "%s%d", comma, SEXT3(OP[i]));
309	  p += strlen (p);
310	  comma = ",";
311	  break;
312
313	case OP_MEMREF:
314	  sprintf (p, "%s@r%d", comma, OP[i]);
315	  p += strlen (p);
316	  comma = ",";
317	  break;
318
319	case OP_MEMREF2:
320	  sprintf (p, "%s@(%d,r%d)", comma, (int16)OP[i], OP[i+1]);
321	  p += strlen (p);
322	  comma = ",";
323	  break;
324
325	case OP_MEMREF3:
326	  sprintf (p, "%s@%d", comma, OP[i]);
327	  p += strlen (p);
328	  comma = ",";
329	  break;
330
331	case OP_POSTINC:
332	  sprintf (p, "%s@r%d+", comma, OP[i]);
333	  p += strlen (p);
334	  comma = ",";
335	  break;
336
337	case OP_POSTDEC:
338	  sprintf (p, "%s@r%d-", comma, OP[i]);
339	  p += strlen (p);
340	  comma = ",";
341	  break;
342
343	case OP_PREDEC:
344	  sprintf (p, "%s@-r%d", comma, OP[i]);
345	  p += strlen (p);
346	  comma = ",";
347	  break;
348
349	case OP_FLAG:
350	case OP_FLAG_OUTPUT:
351	  if (OP[i] == 0)
352	    sprintf (p, "%sf0", comma);
353
354	  else if (OP[i] == 1)
355	    sprintf (p, "%sf1", comma);
356
357	  else
358	    sprintf (p, "%sc", comma);
359
360	  p += strlen (p);
361	  comma = ",";
362	  break;
363	}
364    }
365
366  if ((d10v_debug & DEBUG_VALUES) == 0)
367    {
368      *p++ = '\n';
369      *p = '\0';
370      (*d10v_callback->printf_filtered) (d10v_callback, "%s", buf);
371    }
372  else
373    {
374      *p = '\0';
375      (*d10v_callback->printf_filtered) (d10v_callback, "%-*s", SIZE_OPERANDS, buf);
376
377      p = buf;
378      for (i = 0; i < 3; i++)
379	{
380	  buf[0] = '\0';
381	  switch (in[i])
382	    {
383	    case OP_VOID:
384	      (*d10v_callback->printf_filtered) (d10v_callback, "%*s", SIZE_VALUES, "");
385	      break;
386
387	    case OP_REG_OUTPUT:
388	    case OP_DREG_OUTPUT:
389	    case OP_CR_OUTPUT:
390	    case OP_ACCUM_OUTPUT:
391	    case OP_FLAG_OUTPUT:
392	      (*d10v_callback->printf_filtered) (d10v_callback, "%*s", SIZE_VALUES, "---");
393	      break;
394
395	    case OP_REG:
396	    case OP_MEMREF:
397	    case OP_POSTDEC:
398	    case OP_POSTINC:
399	    case OP_PREDEC:
400	      (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
401						 (uint16) GPR (OP[i]));
402	      break;
403
404	    case OP_MEMREF3:
405	      (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "", (uint16) OP[i]);
406	      break;
407
408	    case OP_DREG:
409	      tmp = (long)((((uint32) GPR (OP[i])) << 16) | ((uint32) GPR (OP[i] + 1)));
410	      (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.8lx", SIZE_VALUES-10, "", tmp);
411	      break;
412
413	    case OP_CR:
414	    case OP_CR_REVERSE:
415	      (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
416						 (uint16) CREG (OP[i]));
417	      break;
418
419	    case OP_ACCUM:
420	    case OP_ACCUM_REVERSE:
421	      (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.2x%.8lx", SIZE_VALUES-12, "",
422						 ((int)(ACC (OP[i]) >> 32) & 0xff),
423						 ((unsigned long) ACC (OP[i])) & 0xffffffff);
424	      break;
425
426	    case OP_CONSTANT16:
427	      (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
428						 (uint16)OP[i]);
429	      break;
430
431	    case OP_CONSTANT4:
432	      (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
433						 (uint16)SEXT4(OP[i]));
434	      break;
435
436	    case OP_CONSTANT8:
437	      (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
438						 (uint16)SEXT8(OP[i]));
439	      break;
440
441	    case OP_CONSTANT3:
442	      (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
443						 (uint16)SEXT3(OP[i]));
444	      break;
445
446	    case OP_FLAG:
447	      if (OP[i] == 0)
448		(*d10v_callback->printf_filtered) (d10v_callback, "%*sF0 = %d", SIZE_VALUES-6, "",
449						   PSW_F0 != 0);
450
451	      else if (OP[i] == 1)
452		(*d10v_callback->printf_filtered) (d10v_callback, "%*sF1 = %d", SIZE_VALUES-6, "",
453						   PSW_F1 != 0);
454
455	      else
456		(*d10v_callback->printf_filtered) (d10v_callback, "%*sC = %d", SIZE_VALUES-5, "",
457						   PSW_C != 0);
458
459	      break;
460
461	    case OP_MEMREF2:
462	      (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
463						 (uint16)OP[i]);
464	      (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
465						 (uint16)GPR (OP[i + 1]));
466	      i++;
467	      break;
468
469	    case OP_R0:
470	      (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
471						 (uint16) GPR (0));
472	      break;
473
474	    case OP_R1:
475	      (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
476						 (uint16) GPR (1));
477	      break;
478
479	    case OP_R2:
480	      (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
481						 (uint16) GPR (2));
482	      break;
483
484	    }
485	}
486    }
487
488  (*d10v_callback->flush_stdout) (d10v_callback);
489}
490
491static void
492do_trace_output_flush (void)
493{
494  (*d10v_callback->flush_stdout) (d10v_callback);
495}
496
497static void
498do_trace_output_finish (void)
499{
500  (*d10v_callback->printf_filtered) (d10v_callback,
501				     " F0=%d F1=%d C=%d\n",
502				     (State.trace.psw & PSW_F0_BIT) != 0,
503				     (State.trace.psw & PSW_F1_BIT) != 0,
504				     (State.trace.psw & PSW_C_BIT) != 0);
505  (*d10v_callback->flush_stdout) (d10v_callback);
506}
507
508static void
509trace_output_40 (uint64 val)
510{
511  if ((d10v_debug & (DEBUG_TRACE | DEBUG_VALUES)) == (DEBUG_TRACE | DEBUG_VALUES))
512    {
513      (*d10v_callback->printf_filtered) (d10v_callback,
514					 " :: %*s0x%.2x%.8lx",
515					 SIZE_VALUES - 12,
516					 "",
517					 ((int)(val >> 32) & 0xff),
518					 ((unsigned long) val) & 0xffffffff);
519      do_trace_output_finish ();
520    }
521}
522
523static void
524trace_output_32 (uint32 val)
525{
526  if ((d10v_debug & (DEBUG_TRACE | DEBUG_VALUES)) == (DEBUG_TRACE | DEBUG_VALUES))
527    {
528      (*d10v_callback->printf_filtered) (d10v_callback,
529					 " :: %*s0x%.8x",
530					 SIZE_VALUES - 10,
531					 "",
532					 (int) val);
533      do_trace_output_finish ();
534    }
535}
536
537static void
538trace_output_16 (uint16 val)
539{
540  if ((d10v_debug & (DEBUG_TRACE | DEBUG_VALUES)) == (DEBUG_TRACE | DEBUG_VALUES))
541    {
542      (*d10v_callback->printf_filtered) (d10v_callback,
543					 " :: %*s0x%.4x",
544					 SIZE_VALUES - 6,
545					 "",
546					 (int) val);
547      do_trace_output_finish ();
548    }
549}
550
551static void
552trace_output_void ()
553{
554  if ((d10v_debug & (DEBUG_TRACE | DEBUG_VALUES)) == (DEBUG_TRACE | DEBUG_VALUES))
555    {
556      (*d10v_callback->printf_filtered) (d10v_callback, "\n");
557      do_trace_output_flush ();
558    }
559}
560
561static void
562trace_output_flag ()
563{
564  if ((d10v_debug & (DEBUG_TRACE | DEBUG_VALUES)) == (DEBUG_TRACE | DEBUG_VALUES))
565    {
566      (*d10v_callback->printf_filtered) (d10v_callback,
567					 " :: %*s",
568					 SIZE_VALUES,
569					 "");
570      do_trace_output_finish ();
571    }
572}
573
574
575
576
577#else
578#define trace_input(NAME, IN1, IN2, IN3)
579#define trace_output(RESULT)
580#endif
581
582/* abs */
583void
584OP_4607 ()
585{
586  int16 tmp;
587  trace_input ("abs", OP_REG, OP_VOID, OP_VOID);
588  SET_PSW_F1 (PSW_F0);
589  tmp = GPR(OP[0]);
590  if (tmp < 0)
591    {
592      tmp = - tmp;
593      SET_PSW_F0 (1);
594    }
595  else
596    SET_PSW_F0 (0);
597  SET_GPR (OP[0], tmp);
598  trace_output_16 (tmp);
599}
600
601/* abs */
602void
603OP_5607 ()
604{
605  int64 tmp;
606  trace_input ("abs", OP_ACCUM, OP_VOID, OP_VOID);
607  SET_PSW_F1 (PSW_F0);
608
609  tmp = SEXT40 (ACC (OP[0]));
610  if (tmp < 0 )
611    {
612      tmp = - tmp;
613      if (PSW_ST)
614	{
615	  if (tmp > SEXT40(MAX32))
616	    tmp = (MAX32);
617	  else if (tmp < SEXT40(MIN32))
618	    tmp = (MIN32);
619	  else
620	    tmp = (tmp & MASK40);
621	}
622      else
623	tmp = (tmp & MASK40);
624      SET_PSW_F0 (1);
625    }
626  else
627    {
628      tmp = (tmp & MASK40);
629      SET_PSW_F0 (0);
630    }
631  SET_ACC (OP[0], tmp);
632  trace_output_40 (tmp);
633}
634
635/* add */
636void
637OP_200 ()
638{
639  uint16 a = GPR (OP[0]);
640  uint16 b = GPR (OP[1]);
641  uint16 tmp = (a + b);
642  trace_input ("add", OP_REG, OP_REG, OP_VOID);
643  SET_PSW_C (a > tmp);
644  SET_GPR (OP[0], tmp);
645  trace_output_16 (tmp);
646}
647
648/* add */
649void
650OP_1201 ()
651{
652  int64 tmp;
653  tmp = SEXT40(ACC (OP[0])) + (SEXT16 (GPR (OP[1])) << 16 | GPR (OP[1] + 1));
654
655  trace_input ("add", OP_ACCUM, OP_REG, OP_VOID);
656  if (PSW_ST)
657    {
658      if (tmp > SEXT40(MAX32))
659	tmp = (MAX32);
660      else if (tmp < SEXT40(MIN32))
661	tmp = (MIN32);
662      else
663	tmp = (tmp & MASK40);
664    }
665  else
666    tmp = (tmp & MASK40);
667  SET_ACC (OP[0], tmp);
668  trace_output_40 (tmp);
669}
670
671/* add */
672void
673OP_1203 ()
674{
675  int64 tmp;
676  tmp = SEXT40(ACC (OP[0])) + SEXT40(ACC (OP[1]));
677
678  trace_input ("add", OP_ACCUM, OP_ACCUM, OP_VOID);
679  if (PSW_ST)
680    {
681      if (tmp > SEXT40(MAX32))
682	tmp = (MAX32);
683      else if (tmp < SEXT40(MIN32))
684	tmp = (MIN32);
685      else
686	tmp = (tmp & MASK40);
687    }
688  else
689    tmp = (tmp & MASK40);
690  SET_ACC (OP[0], tmp);
691  trace_output_40 (tmp);
692}
693
694/* add2w */
695void
696OP_1200 ()
697{
698  uint32 tmp;
699  uint32 a = (GPR (OP[0])) << 16 | GPR (OP[0] + 1);
700  uint32 b = (GPR (OP[1])) << 16 | GPR (OP[1] + 1);
701  trace_input ("add2w", OP_DREG, OP_DREG, OP_VOID);
702  tmp = a + b;
703  SET_PSW_C (tmp < a);
704  SET_GPR (OP[0] + 0, (tmp >> 16));
705  SET_GPR (OP[0] + 1, (tmp & 0xFFFF));
706  trace_output_32 (tmp);
707}
708
709/* add3 */
710void
711OP_1000000 ()
712{
713  uint16 a = GPR (OP[1]);
714  uint16 b = OP[2];
715  uint16 tmp = (a + b);
716  trace_input ("add3", OP_REG_OUTPUT, OP_REG, OP_CONSTANT16);
717  SET_PSW_C (tmp < a);
718  SET_GPR (OP[0], tmp);
719  trace_output_16 (tmp);
720}
721
722/* addac3 */
723void
724OP_17000200 ()
725{
726  int64 tmp;
727  tmp = SEXT40(ACC (OP[2])) + SEXT40 ((GPR (OP[1]) << 16) | GPR (OP[1] + 1));
728
729  trace_input ("addac3", OP_DREG_OUTPUT, OP_DREG, OP_ACCUM);
730  SET_GPR (OP[0] + 0, ((tmp >> 16) & 0xffff));
731  SET_GPR (OP[0] + 1, (tmp & 0xffff));
732  trace_output_32 (tmp);
733}
734
735/* addac3 */
736void
737OP_17000202 ()
738{
739  int64 tmp;
740  tmp = SEXT40(ACC (OP[1])) + SEXT40(ACC (OP[2]));
741
742  trace_input ("addac3", OP_DREG_OUTPUT, OP_ACCUM, OP_ACCUM);
743  SET_GPR (OP[0] + 0, (tmp >> 16) & 0xffff);
744  SET_GPR (OP[0] + 1, tmp & 0xffff);
745  trace_output_32 (tmp);
746}
747
748/* addac3s */
749void
750OP_17001200 ()
751{
752  int64 tmp;
753  SET_PSW_F1 (PSW_F0);
754
755  trace_input ("addac3s", OP_DREG_OUTPUT, OP_DREG, OP_ACCUM);
756  tmp = SEXT40 (ACC (OP[2])) + SEXT40 ((GPR (OP[1]) << 16) | GPR (OP[1] + 1));
757  if (tmp > SEXT40(MAX32))
758    {
759      tmp = (MAX32);
760      SET_PSW_F0 (1);
761    }
762  else if (tmp < SEXT40(MIN32))
763    {
764      tmp = (MIN32);
765      SET_PSW_F0 (1);
766    }
767  else
768    {
769      SET_PSW_F0 (0);
770    }
771  SET_GPR (OP[0] + 0, (tmp >> 16) & 0xffff);
772  SET_GPR (OP[0] + 1, (tmp & 0xffff));
773  trace_output_32 (tmp);
774}
775
776/* addac3s */
777void
778OP_17001202 ()
779{
780  int64 tmp;
781  SET_PSW_F1 (PSW_F0);
782
783  trace_input ("addac3s", OP_DREG_OUTPUT, OP_ACCUM, OP_ACCUM);
784  tmp = SEXT40(ACC (OP[1])) + SEXT40(ACC (OP[2]));
785  if (tmp > SEXT40(MAX32))
786    {
787      tmp = (MAX32);
788      SET_PSW_F0 (1);
789    }
790  else if (tmp < SEXT40(MIN32))
791    {
792      tmp = (MIN32);
793      SET_PSW_F0 (1);
794    }
795  else
796    {
797      SET_PSW_F0 (0);
798    }
799  SET_GPR (OP[0] + 0, (tmp >> 16) & 0xffff);
800  SET_GPR (OP[0] + 1, (tmp & 0xffff));
801  trace_output_32 (tmp);
802}
803
804/* addi */
805void
806OP_201 ()
807{
808  uint16 a = GPR (OP[0]);
809  uint16 b;
810  uint16 tmp;
811  if (OP[1] == 0)
812    OP[1] = 16;
813  b = OP[1];
814  tmp = (a + b);
815  trace_input ("addi", OP_REG, OP_CONSTANT16, OP_VOID);
816  SET_PSW_C (tmp < a);
817  SET_GPR (OP[0], tmp);
818  trace_output_16 (tmp);
819}
820
821/* and */
822void
823OP_C00 ()
824{
825  uint16 tmp = GPR (OP[0]) & GPR (OP[1]);
826  trace_input ("and", OP_REG, OP_REG, OP_VOID);
827  SET_GPR (OP[0], tmp);
828  trace_output_16 (tmp);
829}
830
831/* and3 */
832void
833OP_6000000 ()
834{
835  uint16 tmp = GPR (OP[1]) & OP[2];
836  trace_input ("and3", OP_REG_OUTPUT, OP_REG, OP_CONSTANT16);
837  SET_GPR (OP[0], tmp);
838  trace_output_16 (tmp);
839}
840
841/* bclri */
842void
843OP_C01 ()
844{
845  int16 tmp;
846  trace_input ("bclri", OP_REG, OP_CONSTANT16, OP_VOID);
847  tmp = (GPR (OP[0]) &~(0x8000 >> OP[1]));
848  SET_GPR (OP[0], tmp);
849  trace_output_16 (tmp);
850}
851
852/* bl.s */
853void
854OP_4900 ()
855{
856  trace_input ("bl.s", OP_CONSTANT8, OP_R0, OP_R1);
857  SET_GPR (13, PC + 1);
858  JMP( PC + SEXT8 (OP[0]));
859  trace_output_void ();
860}
861
862/* bl.l */
863void
864OP_24800000 ()
865{
866  trace_input ("bl.l", OP_CONSTANT16, OP_R0, OP_R1);
867  SET_GPR (13, (PC + 1));
868  JMP (PC + OP[0]);
869  trace_output_void ();
870}
871
872/* bnoti */
873void
874OP_A01 ()
875{
876  int16 tmp;
877  trace_input ("bnoti", OP_REG, OP_CONSTANT16, OP_VOID);
878  tmp = (GPR (OP[0]) ^ (0x8000 >> OP[1]));
879  SET_GPR (OP[0], tmp);
880  trace_output_16 (tmp);
881}
882
883/* bra.s */
884void
885OP_4800 ()
886{
887  trace_input ("bra.s", OP_CONSTANT8, OP_VOID, OP_VOID);
888  JMP (PC + SEXT8 (OP[0]));
889  trace_output_void ();
890}
891
892/* bra.l */
893void
894OP_24000000 ()
895{
896  trace_input ("bra.l", OP_CONSTANT16, OP_VOID, OP_VOID);
897  JMP (PC + OP[0]);
898  trace_output_void ();
899}
900
901/* brf0f.s */
902void
903OP_4A00 ()
904{
905  trace_input ("brf0f.s", OP_CONSTANT8, OP_VOID, OP_VOID);
906  if (!PSW_F0)
907    JMP (PC + SEXT8 (OP[0]));
908  trace_output_flag ();
909}
910
911/* brf0f.l */
912void
913OP_25000000 ()
914{
915  trace_input ("brf0f.l", OP_CONSTANT16, OP_VOID, OP_VOID);
916  if (!PSW_F0)
917    JMP (PC + OP[0]);
918  trace_output_flag ();
919}
920
921/* brf0t.s */
922void
923OP_4B00 ()
924{
925  trace_input ("brf0t.s", OP_CONSTANT8, OP_VOID, OP_VOID);
926  if (PSW_F0)
927    JMP (PC + SEXT8 (OP[0]));
928  trace_output_flag ();
929}
930
931/* brf0t.l */
932void
933OP_25800000 ()
934{
935  trace_input ("brf0t.l", OP_CONSTANT16, OP_VOID, OP_VOID);
936  if (PSW_F0)
937    JMP (PC + OP[0]);
938  trace_output_flag ();
939}
940
941/* bseti */
942void
943OP_801 ()
944{
945  int16 tmp;
946  trace_input ("bseti", OP_REG, OP_CONSTANT16, OP_VOID);
947  tmp = (GPR (OP[0]) | (0x8000 >> OP[1]));
948  SET_GPR (OP[0], tmp);
949  trace_output_16 (tmp);
950}
951
952/* btsti */
953void
954OP_E01 ()
955{
956  trace_input ("btsti", OP_REG, OP_CONSTANT16, OP_VOID);
957  SET_PSW_F1 (PSW_F0);
958  SET_PSW_F0 ((GPR (OP[0]) & (0x8000 >> OP[1])) ? 1 : 0);
959  trace_output_flag ();
960}
961
962/* clrac */
963void
964OP_5601 ()
965{
966  trace_input ("clrac", OP_ACCUM_OUTPUT, OP_VOID, OP_VOID);
967  SET_ACC (OP[0], 0);
968  trace_output_40 (0);
969}
970
971/* cmp */
972void
973OP_600 ()
974{
975  trace_input ("cmp", OP_REG, OP_REG, OP_VOID);
976  SET_PSW_F1 (PSW_F0);
977  SET_PSW_F0 (((int16)(GPR (OP[0])) < (int16)(GPR (OP[1]))) ? 1 : 0);
978  trace_output_flag ();
979}
980
981/* cmp */
982void
983OP_1603 ()
984{
985  trace_input ("cmp", OP_ACCUM, OP_ACCUM, OP_VOID);
986  SET_PSW_F1 (PSW_F0);
987  SET_PSW_F0 ((SEXT40(ACC (OP[0])) < SEXT40(ACC (OP[1]))) ? 1 : 0);
988  trace_output_flag ();
989}
990
991/* cmpeq */
992void
993OP_400 ()
994{
995  trace_input ("cmpeq", OP_REG, OP_REG, OP_VOID);
996  SET_PSW_F1 (PSW_F0);
997  SET_PSW_F0 ((GPR (OP[0]) == GPR (OP[1])) ? 1 : 0);
998  trace_output_flag ();
999}
1000
1001/* cmpeq */
1002void
1003OP_1403 ()
1004{
1005  trace_input ("cmpeq", OP_ACCUM, OP_ACCUM, OP_VOID);
1006  SET_PSW_F1 (PSW_F0);
1007  SET_PSW_F0 (((ACC (OP[0]) & MASK40) == (ACC (OP[1]) & MASK40)) ? 1 : 0);
1008  trace_output_flag ();
1009}
1010
1011/* cmpeqi.s */
1012void
1013OP_401 ()
1014{
1015  trace_input ("cmpeqi.s", OP_REG, OP_CONSTANT4, OP_VOID);
1016  SET_PSW_F1 (PSW_F0);
1017  SET_PSW_F0 ((GPR (OP[0]) == (reg_t) SEXT4 (OP[1])) ? 1 : 0);
1018  trace_output_flag ();
1019}
1020
1021/* cmpeqi.l */
1022void
1023OP_2000000 ()
1024{
1025  trace_input ("cmpeqi.l", OP_REG, OP_CONSTANT16, OP_VOID);
1026  SET_PSW_F1 (PSW_F0);
1027  SET_PSW_F0 ((GPR (OP[0]) == (reg_t)OP[1]) ? 1 : 0);
1028  trace_output_flag ();
1029}
1030
1031/* cmpi.s */
1032void
1033OP_601 ()
1034{
1035  trace_input ("cmpi.s", OP_REG, OP_CONSTANT4, OP_VOID);
1036  SET_PSW_F1 (PSW_F0);
1037  SET_PSW_F0 (((int16)(GPR (OP[0])) < (int16)SEXT4(OP[1])) ? 1 : 0);
1038  trace_output_flag ();
1039}
1040
1041/* cmpi.l */
1042void
1043OP_3000000 ()
1044{
1045  trace_input ("cmpi.l", OP_REG, OP_CONSTANT16, OP_VOID);
1046  SET_PSW_F1 (PSW_F0);
1047  SET_PSW_F0 (((int16)(GPR (OP[0])) < (int16)(OP[1])) ? 1 : 0);
1048  trace_output_flag ();
1049}
1050
1051/* cmpu */
1052void
1053OP_4600 ()
1054{
1055  trace_input ("cmpu", OP_REG, OP_REG, OP_VOID);
1056  SET_PSW_F1 (PSW_F0);
1057  SET_PSW_F0 ((GPR (OP[0]) < GPR (OP[1])) ? 1 : 0);
1058  trace_output_flag ();
1059}
1060
1061/* cmpui */
1062void
1063OP_23000000 ()
1064{
1065  trace_input ("cmpui", OP_REG, OP_CONSTANT16, OP_VOID);
1066  SET_PSW_F1 (PSW_F0);
1067  SET_PSW_F0 ((GPR (OP[0]) < (reg_t)OP[1]) ? 1 : 0);
1068  trace_output_flag ();
1069}
1070
1071/* cpfg */
1072void
1073OP_4E09 ()
1074{
1075  uint8 val;
1076
1077  trace_input ("cpfg", OP_FLAG_OUTPUT, OP_FLAG, OP_VOID);
1078
1079  if (OP[1] == 0)
1080    val = PSW_F0;
1081  else if (OP[1] == 1)
1082    val = PSW_F1;
1083  else
1084    val = PSW_C;
1085  if (OP[0] == 0)
1086    SET_PSW_F0 (val);
1087  else
1088    SET_PSW_F1 (val);
1089
1090  trace_output_flag ();
1091}
1092
1093/* cpfg */
1094void
1095OP_4E0F ()
1096{
1097  uint8 val;
1098
1099  trace_input ("cpfg", OP_FLAG_OUTPUT, OP_FLAG, OP_VOID);
1100
1101  if (OP[1] == 0)
1102    val = PSW_F0;
1103  else if (OP[1] == 1)
1104    val = PSW_F1;
1105  else
1106    val = PSW_C;
1107  if (OP[0] == 0)
1108    SET_PSW_F0 (val);
1109  else
1110    SET_PSW_F1 (val);
1111
1112  trace_output_flag ();
1113}
1114
1115/* dbt */
1116void
1117OP_5F20 ()
1118{
1119  /* d10v_callback->printf_filtered(d10v_callback, "***** DBT *****  PC=%x\n",PC); */
1120
1121  /* GDB uses the instruction pair ``dbt || nop'' as a break-point.
1122     The conditional below is for either of the instruction pairs
1123     ``dbt -> XXX'' or ``dbt <- XXX'' and treats them as as cases
1124     where the dbt instruction should be interpreted.
1125
1126     The module `sim-break' provides a more effective mechanism for
1127     detecting GDB planted breakpoints.  The code below may,
1128     eventually, be changed to use that mechanism. */
1129
1130  if (State.ins_type == INS_LEFT
1131      || State.ins_type == INS_RIGHT)
1132    {
1133      trace_input ("dbt", OP_VOID, OP_VOID, OP_VOID);
1134      SET_DPC (PC + 1);
1135      SET_DPSW (PSW);
1136      SET_HW_PSW (PSW_DM_BIT | (PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
1137      JMP (DBT_VECTOR_START);
1138      trace_output_void ();
1139    }
1140  else
1141    {
1142      State.exception = SIGTRAP;
1143    }
1144}
1145
1146/* divs */
1147void
1148OP_14002800 ()
1149{
1150  uint16 foo, tmp, tmpf;
1151  uint16 hi;
1152  uint16 lo;
1153
1154  trace_input ("divs", OP_DREG, OP_REG, OP_VOID);
1155  foo = (GPR (OP[0]) << 1) | (GPR (OP[0] + 1) >> 15);
1156  tmp = (int16)foo - (int16)(GPR (OP[1]));
1157  tmpf = (foo >= GPR (OP[1])) ? 1 : 0;
1158  hi = ((tmpf == 1) ? tmp : foo);
1159  lo = ((GPR (OP[0] + 1) << 1) | tmpf);
1160  SET_GPR (OP[0] + 0, hi);
1161  SET_GPR (OP[0] + 1, lo);
1162  trace_output_32 (((uint32) hi << 16) | lo);
1163}
1164
1165/* exef0f */
1166void
1167OP_4E04 ()
1168{
1169  trace_input ("exef0f", OP_VOID, OP_VOID, OP_VOID);
1170  State.exe = (PSW_F0 == 0);
1171  trace_output_flag ();
1172}
1173
1174/* exef0t */
1175void
1176OP_4E24 ()
1177{
1178  trace_input ("exef0t", OP_VOID, OP_VOID, OP_VOID);
1179  State.exe = (PSW_F0 != 0);
1180  trace_output_flag ();
1181}
1182
1183/* exef1f */
1184void
1185OP_4E40 ()
1186{
1187  trace_input ("exef1f", OP_VOID, OP_VOID, OP_VOID);
1188  State.exe = (PSW_F1 == 0);
1189  trace_output_flag ();
1190}
1191
1192/* exef1t */
1193void
1194OP_4E42 ()
1195{
1196  trace_input ("exef1t", OP_VOID, OP_VOID, OP_VOID);
1197  State.exe = (PSW_F1 != 0);
1198  trace_output_flag ();
1199}
1200
1201/* exefaf */
1202void
1203OP_4E00 ()
1204{
1205  trace_input ("exefaf", OP_VOID, OP_VOID, OP_VOID);
1206  State.exe = (PSW_F0 == 0) & (PSW_F1 == 0);
1207  trace_output_flag ();
1208}
1209
1210/* exefat */
1211void
1212OP_4E02 ()
1213{
1214  trace_input ("exefat", OP_VOID, OP_VOID, OP_VOID);
1215  State.exe = (PSW_F0 == 0) & (PSW_F1 != 0);
1216  trace_output_flag ();
1217}
1218
1219/* exetaf */
1220void
1221OP_4E20 ()
1222{
1223  trace_input ("exetaf", OP_VOID, OP_VOID, OP_VOID);
1224  State.exe = (PSW_F0 != 0) & (PSW_F1 == 0);
1225  trace_output_flag ();
1226}
1227
1228/* exetat */
1229void
1230OP_4E22 ()
1231{
1232  trace_input ("exetat", OP_VOID, OP_VOID, OP_VOID);
1233  State.exe = (PSW_F0 != 0) & (PSW_F1 != 0);
1234  trace_output_flag ();
1235}
1236
1237/* exp */
1238void
1239OP_15002A00 ()
1240{
1241  uint32 tmp, foo;
1242  int i;
1243
1244  trace_input ("exp", OP_REG_OUTPUT, OP_DREG, OP_VOID);
1245  if (((int16)GPR (OP[1])) >= 0)
1246    tmp = (GPR (OP[1]) << 16) | GPR (OP[1] + 1);
1247  else
1248    tmp = ~((GPR (OP[1]) << 16) | GPR (OP[1] + 1));
1249
1250  foo = 0x40000000;
1251  for (i=1;i<17;i++)
1252    {
1253      if (tmp & foo)
1254	{
1255	  SET_GPR (OP[0], (i - 1));
1256	  trace_output_16 (i - 1);
1257	  return;
1258	}
1259      foo >>= 1;
1260    }
1261  SET_GPR (OP[0], 16);
1262  trace_output_16 (16);
1263}
1264
1265/* exp */
1266void
1267OP_15002A02 ()
1268{
1269  int64 tmp, foo;
1270  int i;
1271
1272  trace_input ("exp", OP_REG_OUTPUT, OP_ACCUM, OP_VOID);
1273  tmp = SEXT40(ACC (OP[1]));
1274  if (tmp < 0)
1275    tmp = ~tmp & MASK40;
1276
1277  foo = 0x4000000000LL;
1278  for (i=1;i<25;i++)
1279    {
1280      if (tmp & foo)
1281	{
1282	  SET_GPR (OP[0], i - 9);
1283	  trace_output_16 (i - 9);
1284	  return;
1285	}
1286      foo >>= 1;
1287    }
1288  SET_GPR (OP[0], 16);
1289  trace_output_16 (16);
1290}
1291
1292/* jl */
1293void
1294OP_4D00 ()
1295{
1296  trace_input ("jl", OP_REG, OP_R0, OP_R1);
1297  SET_GPR (13, PC + 1);
1298  JMP (GPR (OP[0]));
1299  trace_output_void ();
1300}
1301
1302/* jmp */
1303void
1304OP_4C00 ()
1305{
1306  trace_input ("jmp", OP_REG,
1307	       (OP[0] == 13) ? OP_R0 : OP_VOID,
1308	       (OP[0] == 13) ? OP_R1 : OP_VOID);
1309
1310  JMP (GPR (OP[0]));
1311  trace_output_void ();
1312}
1313
1314/* ld */
1315void
1316OP_30000000 ()
1317{
1318  uint16 tmp;
1319  uint16 addr = OP[1] + GPR (OP[2]);
1320  trace_input ("ld", OP_REG_OUTPUT, OP_MEMREF2, OP_VOID);
1321  if ((addr & 1))
1322    {
1323      State.exception = SIG_D10V_BUS;
1324      State.pc_changed = 1; /* Don't increment the PC. */
1325      trace_output_void ();
1326      return;
1327    }
1328  tmp = RW (addr);
1329  SET_GPR (OP[0], tmp);
1330  trace_output_16 (tmp);
1331}
1332
1333/* ld */
1334void
1335OP_6401 ()
1336{
1337  uint16 tmp;
1338  uint16 addr = GPR (OP[1]);
1339  trace_input ("ld", OP_REG_OUTPUT, OP_POSTDEC, OP_VOID);
1340  if ((addr & 1))
1341    {
1342      State.exception = SIG_D10V_BUS;
1343      State.pc_changed = 1; /* Don't increment the PC. */
1344      trace_output_void ();
1345      return;
1346    }
1347  tmp = RW (addr);
1348  SET_GPR (OP[0], tmp);
1349  if (OP[0] != OP[1])
1350    INC_ADDR (OP[1], -2);
1351  trace_output_16 (tmp);
1352}
1353
1354/* ld */
1355void
1356OP_6001 ()
1357{
1358  uint16 tmp;
1359  uint16 addr = GPR (OP[1]);
1360  trace_input ("ld", OP_REG_OUTPUT, OP_POSTINC, OP_VOID);
1361  if ((addr & 1))
1362    {
1363      State.exception = SIG_D10V_BUS;
1364      State.pc_changed = 1; /* Don't increment the PC. */
1365      trace_output_void ();
1366      return;
1367    }
1368  tmp = RW (addr);
1369  SET_GPR (OP[0], tmp);
1370  if (OP[0] != OP[1])
1371    INC_ADDR (OP[1], 2);
1372  trace_output_16 (tmp);
1373}
1374
1375/* ld */
1376void
1377OP_6000 ()
1378{
1379  uint16 tmp;
1380  uint16 addr = GPR (OP[1]);
1381  trace_input ("ld", OP_REG_OUTPUT, OP_MEMREF, OP_VOID);
1382  if ((addr & 1))
1383    {
1384      State.exception = SIG_D10V_BUS;
1385      State.pc_changed = 1; /* Don't increment the PC. */
1386      trace_output_void ();
1387      return;
1388    }
1389  tmp = RW (addr);
1390  SET_GPR (OP[0], tmp);
1391  trace_output_16 (tmp);
1392}
1393
1394/* ld */
1395void
1396OP_32010000 ()
1397{
1398  uint16 tmp;
1399  uint16 addr = OP[1];
1400  trace_input ("ld", OP_REG_OUTPUT, OP_MEMREF3, OP_VOID);
1401  if ((addr & 1))
1402    {
1403      State.exception = SIG_D10V_BUS;
1404      State.pc_changed = 1; /* Don't increment the PC. */
1405      trace_output_void ();
1406      return;
1407    }
1408  tmp = RW (addr);
1409  SET_GPR (OP[0], tmp);
1410  trace_output_16 (tmp);
1411}
1412
1413/* ld2w */
1414void
1415OP_31000000 ()
1416{
1417  int32 tmp;
1418  uint16 addr = OP[1] + GPR (OP[2]);
1419  trace_input ("ld2w", OP_REG_OUTPUT, OP_MEMREF2, OP_VOID);
1420  if ((addr & 1))
1421    {
1422      State.exception = SIG_D10V_BUS;
1423      State.pc_changed = 1; /* Don't increment the PC. */
1424      trace_output_void ();
1425      return;
1426    }
1427  tmp = RLW (addr);
1428  SET_GPR32 (OP[0], tmp);
1429  trace_output_32 (tmp);
1430}
1431
1432/* ld2w */
1433void
1434OP_6601 ()
1435{
1436  uint16 addr = GPR (OP[1]);
1437  int32 tmp;
1438  trace_input ("ld2w", OP_REG_OUTPUT, OP_POSTDEC, OP_VOID);
1439  if ((addr & 1))
1440    {
1441      State.exception = SIG_D10V_BUS;
1442      State.pc_changed = 1; /* Don't increment the PC. */
1443      trace_output_void ();
1444      return;
1445    }
1446  tmp = RLW (addr);
1447  SET_GPR32 (OP[0], tmp);
1448  if (OP[0] != OP[1] && ((OP[0] + 1) != OP[1]))
1449    INC_ADDR (OP[1], -4);
1450  trace_output_32 (tmp);
1451}
1452
1453/* ld2w */
1454void
1455OP_6201 ()
1456{
1457  int32 tmp;
1458  uint16 addr = GPR (OP[1]);
1459  trace_input ("ld2w", OP_REG_OUTPUT, OP_POSTINC, OP_VOID);
1460  if ((addr & 1))
1461    {
1462      State.exception = SIG_D10V_BUS;
1463      State.pc_changed = 1; /* Don't increment the PC. */
1464      trace_output_void ();
1465      return;
1466    }
1467  tmp = RLW (addr);
1468  SET_GPR32 (OP[0], tmp);
1469  if (OP[0] != OP[1] && ((OP[0] + 1) != OP[1]))
1470    INC_ADDR (OP[1], 4);
1471  trace_output_32 (tmp);
1472}
1473
1474/* ld2w */
1475void
1476OP_6200 ()
1477{
1478  uint16 addr = GPR (OP[1]);
1479  int32 tmp;
1480  trace_input ("ld2w", OP_REG_OUTPUT, OP_MEMREF, OP_VOID);
1481  if ((addr & 1))
1482    {
1483      State.exception = SIG_D10V_BUS;
1484      State.pc_changed = 1; /* Don't increment the PC. */
1485      trace_output_void ();
1486      return;
1487    }
1488  tmp = RLW (addr);
1489  SET_GPR32 (OP[0], tmp);
1490  trace_output_32 (tmp);
1491}
1492
1493/* ld2w */
1494void
1495OP_33010000 ()
1496{
1497  int32 tmp;
1498  uint16 addr = OP[1];
1499  trace_input ("ld2w", OP_REG_OUTPUT, OP_MEMREF3, OP_VOID);
1500  if ((addr & 1))
1501    {
1502      State.exception = SIG_D10V_BUS;
1503      State.pc_changed = 1; /* Don't increment the PC. */
1504      trace_output_void ();
1505      return;
1506    }
1507  tmp = RLW (addr);
1508  SET_GPR32 (OP[0], tmp);
1509  trace_output_32 (tmp);
1510}
1511
1512/* ldb */
1513void
1514OP_38000000 ()
1515{
1516  int16 tmp;
1517  trace_input ("ldb", OP_REG_OUTPUT, OP_MEMREF2, OP_VOID);
1518  tmp = SEXT8 (RB (OP[1] + GPR (OP[2])));
1519  SET_GPR (OP[0], tmp);
1520  trace_output_16 (tmp);
1521}
1522
1523/* ldb */
1524void
1525OP_7000 ()
1526{
1527  int16 tmp;
1528  trace_input ("ldb", OP_REG_OUTPUT, OP_MEMREF, OP_VOID);
1529  tmp = SEXT8 (RB (GPR (OP[1])));
1530  SET_GPR (OP[0], tmp);
1531  trace_output_16 (tmp);
1532}
1533
1534/* ldi.s */
1535void
1536OP_4001 ()
1537{
1538  int16 tmp;
1539  trace_input ("ldi.s", OP_REG_OUTPUT, OP_CONSTANT4, OP_VOID);
1540  tmp = SEXT4 (OP[1]);
1541  SET_GPR (OP[0], tmp);
1542  trace_output_16 (tmp);
1543}
1544
1545/* ldi.l */
1546void
1547OP_20000000 ()
1548{
1549  int16 tmp;
1550  trace_input ("ldi.l", OP_REG_OUTPUT, OP_CONSTANT16, OP_VOID);
1551  tmp = OP[1];
1552  SET_GPR (OP[0], tmp);
1553  trace_output_16 (tmp);
1554}
1555
1556/* ldub */
1557void
1558OP_39000000 ()
1559{
1560  int16 tmp;
1561  trace_input ("ldub", OP_REG_OUTPUT, OP_MEMREF2, OP_VOID);
1562  tmp = RB (OP[1] + GPR (OP[2]));
1563  SET_GPR (OP[0], tmp);
1564  trace_output_16 (tmp);
1565}
1566
1567/* ldub */
1568void
1569OP_7200 ()
1570{
1571  int16 tmp;
1572  trace_input ("ldub", OP_REG_OUTPUT, OP_MEMREF, OP_VOID);
1573  tmp = RB (GPR (OP[1]));
1574  SET_GPR (OP[0], tmp);
1575  trace_output_16 (tmp);
1576}
1577
1578/* mac */
1579void
1580OP_2A00 ()
1581{
1582  int64 tmp;
1583
1584  trace_input ("mac", OP_ACCUM, OP_REG, OP_REG);
1585  tmp = SEXT40 ((int16)(GPR (OP[1])) * (int16)(GPR (OP[2])));
1586
1587  if (PSW_FX)
1588    tmp = SEXT40( (tmp << 1) & MASK40);
1589
1590  if (PSW_ST && tmp > SEXT40(MAX32))
1591    tmp = (MAX32);
1592
1593  tmp += SEXT40 (ACC (OP[0]));
1594  if (PSW_ST)
1595    {
1596      if (tmp > SEXT40(MAX32))
1597	tmp = (MAX32);
1598      else if (tmp < SEXT40(MIN32))
1599	tmp = (MIN32);
1600      else
1601	tmp = (tmp & MASK40);
1602    }
1603  else
1604    tmp = (tmp & MASK40);
1605  SET_ACC (OP[0], tmp);
1606  trace_output_40 (tmp);
1607}
1608
1609/* macsu */
1610void
1611OP_1A00 ()
1612{
1613  int64 tmp;
1614
1615  trace_input ("macsu", OP_ACCUM, OP_REG, OP_REG);
1616  tmp = SEXT40 ((int16) GPR (OP[1]) * GPR (OP[2]));
1617  if (PSW_FX)
1618    tmp = SEXT40 ((tmp << 1) & MASK40);
1619  tmp = ((SEXT40 (ACC (OP[0])) + tmp) & MASK40);
1620  SET_ACC (OP[0], tmp);
1621  trace_output_40 (tmp);
1622}
1623
1624/* macu */
1625void
1626OP_3A00 ()
1627{
1628  uint64 tmp;
1629  uint32 src1;
1630  uint32 src2;
1631
1632  trace_input ("macu", OP_ACCUM, OP_REG, OP_REG);
1633  src1 = (uint16) GPR (OP[1]);
1634  src2 = (uint16) GPR (OP[2]);
1635  tmp = src1 * src2;
1636  if (PSW_FX)
1637    tmp = (tmp << 1);
1638  tmp = ((ACC (OP[0]) + tmp) & MASK40);
1639  SET_ACC (OP[0], tmp);
1640  trace_output_40 (tmp);
1641}
1642
1643/* max */
1644void
1645OP_2600 ()
1646{
1647  int16 tmp;
1648  trace_input ("max", OP_REG, OP_REG, OP_VOID);
1649  SET_PSW_F1 (PSW_F0);
1650  if ((int16) GPR (OP[1]) > (int16)GPR (OP[0]))
1651    {
1652      tmp = GPR (OP[1]);
1653      SET_PSW_F0 (1);
1654    }
1655  else
1656    {
1657      tmp = GPR (OP[0]);
1658      SET_PSW_F0 (0);
1659    }
1660  SET_GPR (OP[0], tmp);
1661  trace_output_16 (tmp);
1662}
1663
1664/* max */
1665void
1666OP_3600 ()
1667{
1668  int64 tmp;
1669
1670  trace_input ("max", OP_ACCUM, OP_DREG, OP_VOID);
1671  SET_PSW_F1 (PSW_F0);
1672  tmp = SEXT16 (GPR (OP[1])) << 16 | GPR (OP[1] + 1);
1673  if (tmp > SEXT40 (ACC (OP[0])))
1674    {
1675      tmp = (tmp & MASK40);
1676      SET_PSW_F0 (1);
1677    }
1678  else
1679    {
1680      tmp = ACC (OP[0]);
1681      SET_PSW_F0 (0);
1682    }
1683  SET_ACC (OP[0], tmp);
1684  trace_output_40 (tmp);
1685}
1686
1687/* max */
1688void
1689OP_3602 ()
1690{
1691  int64 tmp;
1692  trace_input ("max", OP_ACCUM, OP_ACCUM, OP_VOID);
1693  SET_PSW_F1 (PSW_F0);
1694  if (SEXT40 (ACC (OP[1])) > SEXT40 (ACC (OP[0])))
1695    {
1696      tmp = ACC (OP[1]);
1697      SET_PSW_F0 (1);
1698    }
1699  else
1700    {
1701      tmp = ACC (OP[0]);
1702      SET_PSW_F0 (0);
1703    }
1704  SET_ACC (OP[0], tmp);
1705  trace_output_40 (tmp);
1706}
1707
1708
1709/* min */
1710void
1711OP_2601 ()
1712{
1713  int16 tmp;
1714  trace_input ("min", OP_REG, OP_REG, OP_VOID);
1715  SET_PSW_F1 (PSW_F0);
1716  if ((int16)GPR (OP[1]) < (int16)GPR (OP[0]))
1717    {
1718      tmp = GPR (OP[1]);
1719      SET_PSW_F0 (1);
1720    }
1721  else
1722    {
1723      tmp = GPR (OP[0]);
1724      SET_PSW_F0 (0);
1725    }
1726  SET_GPR (OP[0], tmp);
1727  trace_output_16 (tmp);
1728}
1729
1730/* min */
1731void
1732OP_3601 ()
1733{
1734  int64 tmp;
1735
1736  trace_input ("min", OP_ACCUM, OP_DREG, OP_VOID);
1737  SET_PSW_F1 (PSW_F0);
1738  tmp = SEXT16 (GPR (OP[1])) << 16 | GPR (OP[1] + 1);
1739  if (tmp < SEXT40(ACC (OP[0])))
1740    {
1741      tmp = (tmp & MASK40);
1742      SET_PSW_F0 (1);
1743    }
1744  else
1745    {
1746      tmp = ACC (OP[0]);
1747      SET_PSW_F0 (0);
1748    }
1749  SET_ACC (OP[0], tmp);
1750  trace_output_40 (tmp);
1751}
1752
1753/* min */
1754void
1755OP_3603 ()
1756{
1757  int64 tmp;
1758  trace_input ("min", OP_ACCUM, OP_ACCUM, OP_VOID);
1759  SET_PSW_F1 (PSW_F0);
1760  if (SEXT40(ACC (OP[1])) < SEXT40(ACC (OP[0])))
1761    {
1762      tmp = ACC (OP[1]);
1763      SET_PSW_F0 (1);
1764    }
1765  else
1766    {
1767      tmp = ACC (OP[0]);
1768      SET_PSW_F0 (0);
1769    }
1770  SET_ACC (OP[0], tmp);
1771  trace_output_40 (tmp);
1772}
1773
1774/* msb */
1775void
1776OP_2800 ()
1777{
1778  int64 tmp;
1779
1780  trace_input ("msb", OP_ACCUM, OP_REG, OP_REG);
1781  tmp = SEXT40 ((int16)(GPR (OP[1])) * (int16)(GPR (OP[2])));
1782
1783  if (PSW_FX)
1784    tmp = SEXT40 ((tmp << 1) & MASK40);
1785
1786  if (PSW_ST && tmp > SEXT40(MAX32))
1787    tmp = (MAX32);
1788
1789  tmp = SEXT40(ACC (OP[0])) - tmp;
1790  if (PSW_ST)
1791    {
1792      if (tmp > SEXT40(MAX32))
1793	tmp = (MAX32);
1794      else if (tmp < SEXT40(MIN32))
1795	tmp = (MIN32);
1796      else
1797	tmp = (tmp & MASK40);
1798    }
1799  else
1800    {
1801      tmp = (tmp & MASK40);
1802    }
1803  SET_ACC (OP[0], tmp);
1804  trace_output_40 (tmp);
1805}
1806
1807/* msbsu */
1808void
1809OP_1800 ()
1810{
1811  int64 tmp;
1812
1813  trace_input ("msbsu", OP_ACCUM, OP_REG, OP_REG);
1814  tmp = SEXT40 ((int16)GPR (OP[1]) * GPR (OP[2]));
1815  if (PSW_FX)
1816    tmp = SEXT40( (tmp << 1) & MASK40);
1817  tmp = ((SEXT40 (ACC (OP[0])) - tmp) & MASK40);
1818  SET_ACC (OP[0], tmp);
1819  trace_output_40 (tmp);
1820}
1821
1822/* msbu */
1823void
1824OP_3800 ()
1825{
1826  uint64 tmp;
1827  uint32 src1;
1828  uint32 src2;
1829
1830  trace_input ("msbu", OP_ACCUM, OP_REG, OP_REG);
1831  src1 = (uint16) GPR (OP[1]);
1832  src2 = (uint16) GPR (OP[2]);
1833  tmp = src1 * src2;
1834  if (PSW_FX)
1835    tmp = (tmp << 1);
1836  tmp = ((ACC (OP[0]) - tmp) & MASK40);
1837  SET_ACC (OP[0], tmp);
1838  trace_output_40 (tmp);
1839}
1840
1841/* mul */
1842void
1843OP_2E00 ()
1844{
1845  int16 tmp;
1846  trace_input ("mul", OP_REG, OP_REG, OP_VOID);
1847  tmp = GPR (OP[0]) * GPR (OP[1]);
1848  SET_GPR (OP[0], tmp);
1849  trace_output_16 (tmp);
1850}
1851
1852/* mulx */
1853void
1854OP_2C00 ()
1855{
1856  int64 tmp;
1857
1858  trace_input ("mulx", OP_ACCUM_OUTPUT, OP_REG, OP_REG);
1859  tmp = SEXT40 ((int16)(GPR (OP[1])) * (int16)(GPR (OP[2])));
1860
1861  if (PSW_FX)
1862    tmp = SEXT40 ((tmp << 1) & MASK40);
1863
1864  if (PSW_ST && tmp > SEXT40(MAX32))
1865    tmp = (MAX32);
1866  else
1867    tmp = (tmp & MASK40);
1868  SET_ACC (OP[0], tmp);
1869  trace_output_40 (tmp);
1870}
1871
1872/* mulxsu */
1873void
1874OP_1C00 ()
1875{
1876  int64 tmp;
1877
1878  trace_input ("mulxsu", OP_ACCUM_OUTPUT, OP_REG, OP_REG);
1879  tmp = SEXT40 ((int16)(GPR (OP[1])) * GPR (OP[2]));
1880
1881  if (PSW_FX)
1882    tmp <<= 1;
1883  tmp = (tmp & MASK40);
1884  SET_ACC (OP[0], tmp);
1885  trace_output_40 (tmp);
1886}
1887
1888/* mulxu */
1889void
1890OP_3C00 ()
1891{
1892  uint64 tmp;
1893  uint32 src1;
1894  uint32 src2;
1895
1896  trace_input ("mulxu", OP_ACCUM_OUTPUT, OP_REG, OP_REG);
1897  src1 = (uint16) GPR (OP[1]);
1898  src2 = (uint16) GPR (OP[2]);
1899  tmp = src1 * src2;
1900  if (PSW_FX)
1901    tmp <<= 1;
1902  tmp = (tmp & MASK40);
1903  SET_ACC (OP[0], tmp);
1904  trace_output_40 (tmp);
1905}
1906
1907/* mv */
1908void
1909OP_4000 ()
1910{
1911  int16 tmp;
1912  trace_input ("mv", OP_REG_OUTPUT, OP_REG, OP_VOID);
1913  tmp = GPR (OP[1]);
1914  SET_GPR (OP[0], tmp);
1915  trace_output_16 (tmp);
1916}
1917
1918/* mv2w */
1919void
1920OP_5000 ()
1921{
1922  int32 tmp;
1923  trace_input ("mv2w", OP_DREG_OUTPUT, OP_DREG, OP_VOID);
1924  tmp = GPR32 (OP[1]);
1925  SET_GPR32 (OP[0], tmp);
1926  trace_output_32 (tmp);
1927}
1928
1929/* mv2wfac */
1930void
1931OP_3E00 ()
1932{
1933  int32 tmp;
1934  trace_input ("mv2wfac", OP_DREG_OUTPUT, OP_ACCUM, OP_VOID);
1935  tmp = ACC (OP[1]);
1936  SET_GPR32 (OP[0], tmp);
1937  trace_output_32 (tmp);
1938}
1939
1940/* mv2wtac */
1941void
1942OP_3E01 ()
1943{
1944  int64 tmp;
1945  trace_input ("mv2wtac", OP_DREG, OP_ACCUM_OUTPUT, OP_VOID);
1946  tmp = ((SEXT16 (GPR (OP[0])) << 16 | GPR (OP[0] + 1)) & MASK40);
1947  SET_ACC (OP[1], tmp);
1948  trace_output_40 (tmp);
1949}
1950
1951/* mvac */
1952void
1953OP_3E03 ()
1954{
1955  int64 tmp;
1956  trace_input ("mvac", OP_ACCUM_OUTPUT, OP_ACCUM, OP_VOID);
1957  tmp = ACC (OP[1]);
1958  SET_ACC (OP[0], tmp);
1959  trace_output_40 (tmp);
1960}
1961
1962/* mvb */
1963void
1964OP_5400 ()
1965{
1966  int16 tmp;
1967  trace_input ("mvb", OP_REG_OUTPUT, OP_REG, OP_VOID);
1968  tmp = SEXT8 (GPR (OP[1]) & 0xff);
1969  SET_GPR (OP[0], tmp);
1970  trace_output_16 (tmp);
1971}
1972
1973/* mvf0f */
1974void
1975OP_4400 ()
1976{
1977  int16 tmp;
1978  trace_input ("mvf0f", OP_REG_OUTPUT, OP_REG, OP_VOID);
1979  if (PSW_F0 == 0)
1980    {
1981      tmp = GPR (OP[1]);
1982      SET_GPR (OP[0], tmp);
1983    }
1984  else
1985    tmp = GPR (OP[0]);
1986  trace_output_16 (tmp);
1987}
1988
1989/* mvf0t */
1990void
1991OP_4401 ()
1992{
1993  int16 tmp;
1994  trace_input ("mvf0t", OP_REG_OUTPUT, OP_REG, OP_VOID);
1995  if (PSW_F0)
1996    {
1997      tmp = GPR (OP[1]);
1998      SET_GPR (OP[0], tmp);
1999    }
2000  else
2001    tmp = GPR (OP[0]);
2002  trace_output_16 (tmp);
2003}
2004
2005/* mvfacg */
2006void
2007OP_1E04 ()
2008{
2009  int16 tmp;
2010  trace_input ("mvfacg", OP_REG_OUTPUT, OP_ACCUM, OP_VOID);
2011  tmp = ((ACC (OP[1]) >> 32) & 0xff);
2012  SET_GPR (OP[0], tmp);
2013  trace_output_16 (tmp);
2014}
2015
2016/* mvfachi */
2017void
2018OP_1E00 ()
2019{
2020  int16 tmp;
2021  trace_input ("mvfachi", OP_REG_OUTPUT, OP_ACCUM, OP_VOID);
2022  tmp = (ACC (OP[1]) >> 16);
2023  SET_GPR (OP[0], tmp);
2024  trace_output_16 (tmp);
2025}
2026
2027/* mvfaclo */
2028void
2029OP_1E02 ()
2030{
2031  int16 tmp;
2032  trace_input ("mvfaclo", OP_REG_OUTPUT, OP_ACCUM, OP_VOID);
2033  tmp = ACC (OP[1]);
2034  SET_GPR (OP[0], tmp);
2035  trace_output_16 (tmp);
2036}
2037
2038/* mvfc */
2039void
2040OP_5200 ()
2041{
2042  int16 tmp;
2043  trace_input ("mvfc", OP_REG_OUTPUT, OP_CR, OP_VOID);
2044  tmp = CREG (OP[1]);
2045  SET_GPR (OP[0], tmp);
2046  trace_output_16 (tmp);
2047}
2048
2049/* mvtacg */
2050void
2051OP_1E41 ()
2052{
2053  int64 tmp;
2054  trace_input ("mvtacg", OP_REG, OP_ACCUM, OP_VOID);
2055  tmp = ((ACC (OP[1]) & MASK32)
2056	 | ((int64)(GPR (OP[0]) & 0xff) << 32));
2057  SET_ACC (OP[1], tmp);
2058  trace_output_40 (tmp);
2059}
2060
2061/* mvtachi */
2062void
2063OP_1E01 ()
2064{
2065  uint64 tmp;
2066  trace_input ("mvtachi", OP_REG, OP_ACCUM, OP_VOID);
2067  tmp = ACC (OP[1]) & 0xffff;
2068  tmp = ((SEXT16 (GPR (OP[0])) << 16 | tmp) & MASK40);
2069  SET_ACC (OP[1], tmp);
2070  trace_output_40 (tmp);
2071}
2072
2073/* mvtaclo */
2074void
2075OP_1E21 ()
2076{
2077  int64 tmp;
2078  trace_input ("mvtaclo", OP_REG, OP_ACCUM, OP_VOID);
2079  tmp = ((SEXT16 (GPR (OP[0]))) & MASK40);
2080  SET_ACC (OP[1], tmp);
2081  trace_output_40 (tmp);
2082}
2083
2084/* mvtc */
2085void
2086OP_5600 ()
2087{
2088  int16 tmp;
2089  trace_input ("mvtc", OP_REG, OP_CR_OUTPUT, OP_VOID);
2090  tmp = GPR (OP[0]);
2091  tmp = SET_CREG (OP[1], tmp);
2092  trace_output_16 (tmp);
2093}
2094
2095/* mvub */
2096void
2097OP_5401 ()
2098{
2099  int16 tmp;
2100  trace_input ("mvub", OP_REG_OUTPUT, OP_REG, OP_VOID);
2101  tmp = (GPR (OP[1]) & 0xff);
2102  SET_GPR (OP[0], tmp);
2103  trace_output_16 (tmp);
2104}
2105
2106/* neg */
2107void
2108OP_4605 ()
2109{
2110  int16 tmp;
2111  trace_input ("neg", OP_REG, OP_VOID, OP_VOID);
2112  tmp = - GPR (OP[0]);
2113  SET_GPR (OP[0], tmp);
2114  trace_output_16 (tmp);
2115}
2116
2117/* neg */
2118void
2119OP_5605 ()
2120{
2121  int64 tmp;
2122
2123  trace_input ("neg", OP_ACCUM, OP_VOID, OP_VOID);
2124  tmp = -SEXT40(ACC (OP[0]));
2125  if (PSW_ST)
2126    {
2127      if (tmp > SEXT40(MAX32))
2128	tmp = (MAX32);
2129      else if (tmp < SEXT40(MIN32))
2130	tmp = (MIN32);
2131      else
2132	tmp = (tmp & MASK40);
2133    }
2134  else
2135    tmp = (tmp & MASK40);
2136  SET_ACC (OP[0], tmp);
2137  trace_output_40 (tmp);
2138}
2139
2140
2141/* nop */
2142void
2143OP_5E00 ()
2144{
2145  trace_input ("nop", OP_VOID, OP_VOID, OP_VOID);
2146
2147  ins_type_counters[ (int)State.ins_type ]--;	/* don't count nops as normal instructions */
2148  switch (State.ins_type)
2149    {
2150    default:
2151      ins_type_counters[ (int)INS_UNKNOWN ]++;
2152      break;
2153
2154    case INS_LEFT_PARALLEL:
2155      /* Don't count a parallel op that includes a NOP as a true parallel op */
2156      ins_type_counters[ (int)INS_RIGHT_PARALLEL ]--;
2157      ins_type_counters[ (int)INS_RIGHT ]++;
2158      ins_type_counters[ (int)INS_LEFT_NOPS ]++;
2159      break;
2160
2161    case INS_LEFT:
2162    case INS_LEFT_COND_EXE:
2163      ins_type_counters[ (int)INS_LEFT_NOPS ]++;
2164      break;
2165
2166    case INS_RIGHT_PARALLEL:
2167      /* Don't count a parallel op that includes a NOP as a true parallel op */
2168      ins_type_counters[ (int)INS_LEFT_PARALLEL ]--;
2169      ins_type_counters[ (int)INS_LEFT ]++;
2170      ins_type_counters[ (int)INS_RIGHT_NOPS ]++;
2171      break;
2172
2173    case INS_RIGHT:
2174    case INS_RIGHT_COND_EXE:
2175      ins_type_counters[ (int)INS_RIGHT_NOPS ]++;
2176      break;
2177    }
2178
2179  trace_output_void ();
2180}
2181
2182/* not */
2183void
2184OP_4603 ()
2185{
2186  int16 tmp;
2187  trace_input ("not", OP_REG, OP_VOID, OP_VOID);
2188  tmp = ~GPR (OP[0]);
2189  SET_GPR (OP[0], tmp);
2190  trace_output_16 (tmp);
2191}
2192
2193/* or */
2194void
2195OP_800 ()
2196{
2197  int16 tmp;
2198  trace_input ("or", OP_REG, OP_REG, OP_VOID);
2199  tmp = (GPR (OP[0]) | GPR (OP[1]));
2200  SET_GPR (OP[0], tmp);
2201  trace_output_16 (tmp);
2202}
2203
2204/* or3 */
2205void
2206OP_4000000 ()
2207{
2208  int16 tmp;
2209  trace_input ("or3", OP_REG_OUTPUT, OP_REG, OP_CONSTANT16);
2210  tmp = (GPR (OP[1]) | OP[2]);
2211  SET_GPR (OP[0], tmp);
2212  trace_output_16 (tmp);
2213}
2214
2215/* rac */
2216void
2217OP_5201 ()
2218{
2219  int64 tmp;
2220  int shift = SEXT3 (OP[2]);
2221
2222  trace_input ("rac", OP_DREG_OUTPUT, OP_ACCUM, OP_CONSTANT3);
2223  if (OP[1] != 0)
2224    {
2225      (*d10v_callback->printf_filtered) (d10v_callback,
2226					 "ERROR at PC 0x%x: instruction only valid for A0\n",
2227					 PC<<2);
2228      State.exception = SIGILL;
2229    }
2230
2231  SET_PSW_F1 (PSW_F0);
2232  tmp = SEXT56 ((ACC (0) << 16) | (ACC (1) & 0xffff));
2233  if (shift >=0)
2234    tmp <<= shift;
2235  else
2236    tmp >>= -shift;
2237  tmp += 0x8000;
2238  tmp >>= 16; /* look at bits 0:43 */
2239  if (tmp > SEXT44 (SIGNED64 (0x0007fffffff)))
2240    {
2241      tmp = 0x7fffffff;
2242      SET_PSW_F0 (1);
2243    }
2244  else if (tmp < SEXT44 (SIGNED64 (0xfff80000000)))
2245    {
2246      tmp = 0x80000000;
2247      SET_PSW_F0 (1);
2248    }
2249  else
2250    {
2251      SET_PSW_F0 (0);
2252    }
2253  SET_GPR32 (OP[0], tmp);
2254  trace_output_32 (tmp);
2255}
2256
2257/* rachi */
2258void
2259OP_4201 ()
2260{
2261  signed64 tmp;
2262  int shift = SEXT3 (OP[2]);
2263
2264  trace_input ("rachi", OP_REG_OUTPUT, OP_ACCUM, OP_CONSTANT3);
2265  SET_PSW_F1 (PSW_F0);
2266  if (shift >=0)
2267    tmp = SEXT40 (ACC (OP[1])) << shift;
2268  else
2269    tmp = SEXT40 (ACC (OP[1])) >> -shift;
2270  tmp += 0x8000;
2271
2272  if (tmp > SEXT44 (SIGNED64 (0x0007fffffff)))
2273    {
2274      tmp = 0x7fff;
2275      SET_PSW_F0 (1);
2276    }
2277  else if (tmp < SEXT44 (SIGNED64 (0xfff80000000)))
2278    {
2279      tmp = 0x8000;
2280      SET_PSW_F0 (1);
2281    }
2282  else
2283    {
2284      tmp = (tmp >> 16);
2285      SET_PSW_F0 (0);
2286    }
2287  SET_GPR (OP[0], tmp);
2288  trace_output_16 (tmp);
2289}
2290
2291/* rep */
2292void
2293OP_27000000 ()
2294{
2295  trace_input ("rep", OP_REG, OP_CONSTANT16, OP_VOID);
2296  SET_RPT_S (PC + 1);
2297  SET_RPT_E (PC + OP[1]);
2298  SET_RPT_C (GPR (OP[0]));
2299  SET_PSW_RP (1);
2300  if (GPR (OP[0]) == 0)
2301    {
2302      (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: rep with count=0 is illegal.\n");
2303      State.exception = SIGILL;
2304    }
2305  if (OP[1] < 4)
2306    {
2307      (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: rep must include at least 4 instructions.\n");
2308      State.exception = SIGILL;
2309    }
2310  trace_output_void ();
2311}
2312
2313/* repi */
2314void
2315OP_2F000000 ()
2316{
2317  trace_input ("repi", OP_CONSTANT16, OP_CONSTANT16, OP_VOID);
2318  SET_RPT_S (PC + 1);
2319  SET_RPT_E (PC + OP[1]);
2320  SET_RPT_C (OP[0]);
2321  SET_PSW_RP (1);
2322  if (OP[0] == 0)
2323    {
2324      (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: repi with count=0 is illegal.\n");
2325      State.exception = SIGILL;
2326    }
2327  if (OP[1] < 4)
2328    {
2329      (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: repi must include at least 4 instructions.\n");
2330      State.exception = SIGILL;
2331    }
2332  trace_output_void ();
2333}
2334
2335/* rtd */
2336void
2337OP_5F60 ()
2338{
2339  trace_input ("rtd", OP_VOID, OP_VOID, OP_VOID);
2340  SET_CREG (PSW_CR, DPSW);
2341  JMP(DPC);
2342  trace_output_void ();
2343}
2344
2345/* rte */
2346void
2347OP_5F40 ()
2348{
2349  trace_input ("rte", OP_VOID, OP_VOID, OP_VOID);
2350  SET_CREG (PSW_CR, BPSW);
2351  JMP(BPC);
2352  trace_output_void ();
2353}
2354
2355/* sac */
2356void OP_5209 ()
2357{
2358  int64 tmp;
2359
2360  trace_input ("sac", OP_REG_OUTPUT, OP_ACCUM, OP_VOID);
2361
2362  tmp = SEXT40(ACC (OP[1]));
2363
2364  SET_PSW_F1 (PSW_F0);
2365
2366  if (tmp > SEXT40(MAX32))
2367    {
2368      tmp = (MAX32);
2369      SET_PSW_F0 (1);
2370    }
2371  else if (tmp < SEXT40(MIN32))
2372    {
2373      tmp = 0x80000000;
2374      SET_PSW_F0 (1);
2375    }
2376  else
2377    {
2378      tmp = (tmp & MASK32);
2379      SET_PSW_F0 (0);
2380    }
2381
2382  SET_GPR32 (OP[0], tmp);
2383
2384  trace_output_40 (tmp);
2385}
2386
2387/* sachi */
2388void
2389OP_4209 ()
2390{
2391  int64 tmp;
2392
2393  trace_input ("sachi", OP_REG_OUTPUT, OP_ACCUM, OP_VOID);
2394
2395  tmp = SEXT40(ACC (OP[1]));
2396
2397  SET_PSW_F1 (PSW_F0);
2398
2399  if (tmp > SEXT40(MAX32))
2400    {
2401      tmp = 0x7fff;
2402      SET_PSW_F0 (1);
2403    }
2404  else if (tmp < SEXT40(MIN32))
2405    {
2406      tmp = 0x8000;
2407      SET_PSW_F0 (1);
2408    }
2409  else
2410    {
2411      tmp >>= 16;
2412      SET_PSW_F0 (0);
2413    }
2414
2415  SET_GPR (OP[0], tmp);
2416
2417  trace_output_16 (OP[0]);
2418}
2419
2420/* sadd */
2421void
2422OP_1223 ()
2423{
2424  int64 tmp;
2425
2426  trace_input ("sadd", OP_ACCUM, OP_ACCUM, OP_VOID);
2427  tmp = SEXT40(ACC (OP[0])) + (SEXT40(ACC (OP[1])) >> 16);
2428  if (PSW_ST)
2429    {
2430      if (tmp > SEXT40(MAX32))
2431	tmp = (MAX32);
2432      else if (tmp < SEXT40(MIN32))
2433	tmp = (MIN32);
2434      else
2435	tmp = (tmp & MASK40);
2436    }
2437  else
2438    tmp = (tmp & MASK40);
2439  SET_ACC (OP[0], tmp);
2440  trace_output_40 (tmp);
2441}
2442
2443/* setf0f */
2444void
2445OP_4611 ()
2446{
2447  int16 tmp;
2448  trace_input ("setf0f", OP_REG_OUTPUT, OP_VOID, OP_VOID);
2449  tmp = ((PSW_F0 == 0) ? 1 : 0);
2450  SET_GPR (OP[0], tmp);
2451  trace_output_16 (tmp);
2452}
2453
2454/* setf0t */
2455void
2456OP_4613 ()
2457{
2458  int16 tmp;
2459  trace_input ("setf0t", OP_REG_OUTPUT, OP_VOID, OP_VOID);
2460  tmp = ((PSW_F0 == 1) ? 1 : 0);
2461  SET_GPR (OP[0], tmp);
2462  trace_output_16 (tmp);
2463}
2464
2465/* slae */
2466void
2467OP_3220 ()
2468{
2469  int64 tmp;
2470  int16 reg;
2471
2472  trace_input ("slae", OP_ACCUM, OP_REG, OP_VOID);
2473
2474  reg = SEXT16 (GPR (OP[1]));
2475
2476  if (reg >= 17 || reg <= -17)
2477    {
2478      (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: shift value %d too large.\n", reg);
2479      State.exception = SIGILL;
2480      return;
2481    }
2482
2483  tmp = SEXT40 (ACC (OP[0]));
2484
2485  if (PSW_ST && (tmp < SEXT40 (MIN32) || tmp > SEXT40 (MAX32)))
2486    {
2487      (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: accumulator value 0x%.2x%.8lx out of range\n", ((int)(tmp >> 32) & 0xff), ((unsigned long) tmp) & 0xffffffff);
2488      State.exception = SIGILL;
2489      return;
2490    }
2491
2492  if (reg >= 0 && reg <= 16)
2493    {
2494      tmp = SEXT56 ((SEXT56 (tmp)) << (GPR (OP[1])));
2495      if (PSW_ST)
2496	{
2497	  if (tmp > SEXT40(MAX32))
2498	    tmp = (MAX32);
2499	  else if (tmp < SEXT40(MIN32))
2500	    tmp = (MIN32);
2501	  else
2502	    tmp = (tmp & MASK40);
2503	}
2504      else
2505	tmp = (tmp & MASK40);
2506    }
2507  else
2508    {
2509      tmp = (SEXT40 (ACC (OP[0]))) >> (-GPR (OP[1]));
2510    }
2511
2512  SET_ACC(OP[0], tmp);
2513
2514  trace_output_40(tmp);
2515}
2516
2517/* sleep */
2518void
2519OP_5FC0 ()
2520{
2521  trace_input ("sleep", OP_VOID, OP_VOID, OP_VOID);
2522  SET_PSW_IE (1);
2523  trace_output_void ();
2524}
2525
2526/* sll */
2527void
2528OP_2200 ()
2529{
2530  int16 tmp;
2531  trace_input ("sll", OP_REG, OP_REG, OP_VOID);
2532  tmp = (GPR (OP[0]) << (GPR (OP[1]) & 0xf));
2533  SET_GPR (OP[0], tmp);
2534  trace_output_16 (tmp);
2535}
2536
2537/* sll */
2538void
2539OP_3200 ()
2540{
2541  int64 tmp;
2542  trace_input ("sll", OP_ACCUM, OP_REG, OP_VOID);
2543  if ((GPR (OP[1]) & 31) <= 16)
2544    tmp = SEXT40 (ACC (OP[0])) << (GPR (OP[1]) & 31);
2545  else
2546    {
2547      (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: shift value %d too large.\n", GPR (OP[1]) & 31);
2548      State.exception = SIGILL;
2549      return;
2550    }
2551
2552  if (PSW_ST)
2553    {
2554      if (tmp > SEXT40(MAX32))
2555	tmp = (MAX32);
2556      else if (tmp < SEXT40(MIN32))
2557	tmp = (MIN32);
2558      else
2559	tmp = (tmp & MASK40);
2560    }
2561  else
2562    tmp = (tmp & MASK40);
2563  SET_ACC (OP[0], tmp);
2564  trace_output_40 (tmp);
2565}
2566
2567/* slli */
2568void
2569OP_2201 ()
2570{
2571  int16 tmp;
2572  trace_input ("slli", OP_REG, OP_CONSTANT16, OP_VOID);
2573  tmp = (GPR (OP[0]) << OP[1]);
2574  SET_GPR (OP[0], tmp);
2575  trace_output_16 (tmp);
2576}
2577
2578/* slli */
2579void
2580OP_3201 ()
2581{
2582  int64 tmp;
2583
2584  if (OP[1] == 0)
2585    OP[1] = 16;
2586
2587  trace_input ("slli", OP_ACCUM, OP_CONSTANT16, OP_VOID);
2588  tmp = SEXT40(ACC (OP[0])) << OP[1];
2589
2590  if (PSW_ST)
2591    {
2592      if (tmp > SEXT40(MAX32))
2593	tmp = (MAX32);
2594      else if (tmp < SEXT40(MIN32))
2595	tmp = (MIN32);
2596      else
2597	tmp = (tmp & MASK40);
2598    }
2599  else
2600    tmp = (tmp & MASK40);
2601  SET_ACC (OP[0], tmp);
2602  trace_output_40 (tmp);
2603}
2604
2605/* slx */
2606void
2607OP_460B ()
2608{
2609  int16 tmp;
2610  trace_input ("slx", OP_REG, OP_VOID, OP_VOID);
2611  tmp = ((GPR (OP[0]) << 1) | PSW_F0);
2612  SET_GPR (OP[0], tmp);
2613  trace_output_16 (tmp);
2614}
2615
2616/* sra */
2617void
2618OP_2400 ()
2619{
2620  int16 tmp;
2621  trace_input ("sra", OP_REG, OP_REG, OP_VOID);
2622  tmp = (((int16)(GPR (OP[0]))) >> (GPR (OP[1]) & 0xf));
2623  SET_GPR (OP[0], tmp);
2624  trace_output_16 (tmp);
2625}
2626
2627/* sra */
2628void
2629OP_3400 ()
2630{
2631  trace_input ("sra", OP_ACCUM, OP_REG, OP_VOID);
2632  if ((GPR (OP[1]) & 31) <= 16)
2633    {
2634      int64 tmp = ((SEXT40(ACC (OP[0])) >> (GPR (OP[1]) & 31)) & MASK40);
2635      SET_ACC (OP[0], tmp);
2636      trace_output_40 (tmp);
2637    }
2638  else
2639    {
2640      (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: shift value %d too large.\n", GPR (OP[1]) & 31);
2641      State.exception = SIGILL;
2642      return;
2643    }
2644}
2645
2646/* srai */
2647void
2648OP_2401 ()
2649{
2650  int16 tmp;
2651  trace_input ("srai", OP_REG, OP_CONSTANT16, OP_VOID);
2652  tmp = (((int16)(GPR (OP[0]))) >> OP[1]);
2653  SET_GPR (OP[0], tmp);
2654  trace_output_16 (tmp);
2655}
2656
2657/* srai */
2658void
2659OP_3401 ()
2660{
2661  int64 tmp;
2662  if (OP[1] == 0)
2663    OP[1] = 16;
2664
2665  trace_input ("srai", OP_ACCUM, OP_CONSTANT16, OP_VOID);
2666  tmp = ((SEXT40(ACC (OP[0])) >> OP[1]) & MASK40);
2667  SET_ACC (OP[0], tmp);
2668  trace_output_40 (tmp);
2669}
2670
2671/* srl */
2672void
2673OP_2000 ()
2674{
2675  int16 tmp;
2676  trace_input ("srl", OP_REG, OP_REG, OP_VOID);
2677  tmp = (GPR (OP[0]) >>  (GPR (OP[1]) & 0xf));
2678  SET_GPR (OP[0], tmp);
2679  trace_output_16 (tmp);
2680}
2681
2682/* srl */
2683void
2684OP_3000 ()
2685{
2686  trace_input ("srl", OP_ACCUM, OP_REG, OP_VOID);
2687  if ((GPR (OP[1]) & 31) <= 16)
2688    {
2689      int64 tmp = ((uint64)((ACC (OP[0]) & MASK40) >> (GPR (OP[1]) & 31)));
2690      SET_ACC (OP[0], tmp);
2691      trace_output_40 (tmp);
2692    }
2693  else
2694    {
2695      (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: shift value %d too large.\n", GPR (OP[1]) & 31);
2696      State.exception = SIGILL;
2697      return;
2698    }
2699
2700}
2701
2702/* srli */
2703void
2704OP_2001 ()
2705{
2706  int16 tmp;
2707  trace_input ("srli", OP_REG, OP_CONSTANT16, OP_VOID);
2708  tmp = (GPR (OP[0]) >> OP[1]);
2709  SET_GPR (OP[0], tmp);
2710  trace_output_16 (tmp);
2711}
2712
2713/* srli */
2714void
2715OP_3001 ()
2716{
2717  int64 tmp;
2718  if (OP[1] == 0)
2719    OP[1] = 16;
2720
2721  trace_input ("srli", OP_ACCUM, OP_CONSTANT16, OP_VOID);
2722  tmp = ((uint64)(ACC (OP[0]) & MASK40) >> OP[1]);
2723  SET_ACC (OP[0], tmp);
2724  trace_output_40 (tmp);
2725}
2726
2727/* srx */
2728void
2729OP_4609 ()
2730{
2731  uint16 tmp;
2732  trace_input ("srx", OP_REG, OP_VOID, OP_VOID);
2733  tmp = PSW_F0 << 15;
2734  tmp = ((GPR (OP[0]) >> 1) | tmp);
2735  SET_GPR (OP[0], tmp);
2736  trace_output_16 (tmp);
2737}
2738
2739/* st */
2740void
2741OP_34000000 ()
2742{
2743  uint16 addr = OP[1] + GPR (OP[2]);
2744  trace_input ("st", OP_REG, OP_MEMREF2, OP_VOID);
2745  if ((addr & 1))
2746    {
2747      State.exception = SIG_D10V_BUS;
2748      State.pc_changed = 1; /* Don't increment the PC. */
2749      trace_output_void ();
2750      return;
2751    }
2752  SW (addr, GPR (OP[0]));
2753  trace_output_void ();
2754}
2755
2756/* st */
2757void
2758OP_6800 ()
2759{
2760  uint16 addr = GPR (OP[1]);
2761  trace_input ("st", OP_REG, OP_MEMREF, OP_VOID);
2762  if ((addr & 1))
2763    {
2764      State.exception = SIG_D10V_BUS;
2765      State.pc_changed = 1; /* Don't increment the PC. */
2766      trace_output_void ();
2767      return;
2768    }
2769  SW (addr, GPR (OP[0]));
2770  trace_output_void ();
2771}
2772
2773/* st */
2774/* st Rsrc1,@-SP */
2775void
2776OP_6C1F ()
2777{
2778  uint16 addr = GPR (OP[1]) - 2;
2779  trace_input ("st", OP_REG, OP_PREDEC, OP_VOID);
2780  if (OP[1] != 15)
2781    {
2782      (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot pre-decrement any registers but r15 (SP).\n");
2783      State.exception = SIGILL;
2784      return;
2785    }
2786  if ((addr & 1))
2787    {
2788      State.exception = SIG_D10V_BUS;
2789      State.pc_changed = 1; /* Don't increment the PC. */
2790      trace_output_void ();
2791      return;
2792    }
2793  SW (addr, GPR (OP[0]));
2794  SET_GPR (OP[1], addr);
2795  trace_output_void ();
2796}
2797
2798/* st */
2799void
2800OP_6801 ()
2801{
2802  uint16 addr = GPR (OP[1]);
2803  trace_input ("st", OP_REG, OP_POSTINC, OP_VOID);
2804  if ((addr & 1))
2805    {
2806      State.exception = SIG_D10V_BUS;
2807      State.pc_changed = 1; /* Don't increment the PC. */
2808      trace_output_void ();
2809      return;
2810    }
2811  SW (addr, GPR (OP[0]));
2812  INC_ADDR (OP[1], 2);
2813  trace_output_void ();
2814}
2815
2816/* st */
2817void
2818OP_6C01 ()
2819{
2820  uint16 addr = GPR (OP[1]);
2821  trace_input ("st", OP_REG, OP_POSTDEC, OP_VOID);
2822  if ( OP[1] == 15 )
2823    {
2824      (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot post-decrement register r15 (SP).\n");
2825      State.exception = SIGILL;
2826      return;
2827    }
2828  if ((addr & 1))
2829    {
2830      State.exception = SIG_D10V_BUS;
2831      State.pc_changed = 1; /* Don't increment the PC. */
2832      trace_output_void ();
2833      return;
2834    }
2835  SW (addr, GPR (OP[0]));
2836  INC_ADDR (OP[1], -2);
2837  trace_output_void ();
2838}
2839
2840/* st */
2841void
2842OP_36010000 ()
2843{
2844  uint16 addr = OP[1];
2845  trace_input ("st", OP_REG, OP_MEMREF3, OP_VOID);
2846  if ((addr & 1))
2847    {
2848      State.exception = SIG_D10V_BUS;
2849      State.pc_changed = 1; /* Don't increment the PC. */
2850      trace_output_void ();
2851      return;
2852    }
2853  SW (addr, GPR (OP[0]));
2854  trace_output_void ();
2855}
2856
2857/* st2w */
2858void
2859OP_35000000 ()
2860{
2861  uint16 addr = GPR (OP[2])+ OP[1];
2862  trace_input ("st2w", OP_DREG, OP_MEMREF2, OP_VOID);
2863  if ((addr & 1))
2864    {
2865      State.exception = SIG_D10V_BUS;
2866      State.pc_changed = 1; /* Don't increment the PC. */
2867      trace_output_void ();
2868      return;
2869    }
2870  SW (addr + 0, GPR (OP[0] + 0));
2871  SW (addr + 2, GPR (OP[0] + 1));
2872  trace_output_void ();
2873}
2874
2875/* st2w */
2876void
2877OP_6A00 ()
2878{
2879  uint16 addr = GPR (OP[1]);
2880  trace_input ("st2w", OP_DREG, OP_MEMREF, OP_VOID);
2881  if ((addr & 1))
2882    {
2883      State.exception = SIG_D10V_BUS;
2884      State.pc_changed = 1; /* Don't increment the PC. */
2885      trace_output_void ();
2886      return;
2887    }
2888  SW (addr + 0, GPR (OP[0] + 0));
2889  SW (addr + 2, GPR (OP[0] + 1));
2890  trace_output_void ();
2891}
2892
2893/* st2w */
2894void
2895OP_6E1F ()
2896{
2897  uint16 addr = GPR (OP[1]) - 4;
2898  trace_input ("st2w", OP_DREG, OP_PREDEC, OP_VOID);
2899  if ( OP[1] != 15 )
2900    {
2901      (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot pre-decrement any registers but r15 (SP).\n");
2902      State.exception = SIGILL;
2903      return;
2904    }
2905  if ((addr & 1))
2906    {
2907      State.exception = SIG_D10V_BUS;
2908      State.pc_changed = 1; /* Don't increment the PC. */
2909      trace_output_void ();
2910      return;
2911    }
2912  SW (addr + 0, GPR (OP[0] + 0));
2913  SW (addr + 2, GPR (OP[0] + 1));
2914  SET_GPR (OP[1], addr);
2915  trace_output_void ();
2916}
2917
2918/* st2w */
2919void
2920OP_6A01 ()
2921{
2922  uint16 addr = GPR (OP[1]);
2923  trace_input ("st2w", OP_DREG, OP_POSTINC, OP_VOID);
2924  if ((addr & 1))
2925    {
2926      State.exception = SIG_D10V_BUS;
2927      State.pc_changed = 1; /* Don't increment the PC. */
2928      trace_output_void ();
2929      return;
2930    }
2931  SW (addr + 0, GPR (OP[0] + 0));
2932  SW (addr + 2, GPR (OP[0] + 1));
2933  INC_ADDR (OP[1], 4);
2934  trace_output_void ();
2935}
2936
2937/* st2w */
2938void
2939OP_6E01 ()
2940{
2941  uint16 addr = GPR (OP[1]);
2942  trace_input ("st2w", OP_DREG, OP_POSTDEC, OP_VOID);
2943  if ( OP[1] == 15 )
2944    {
2945      (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot post-decrement register r15 (SP).\n");
2946      State.exception = SIGILL;
2947      return;
2948    }
2949  if ((addr & 1))
2950    {
2951      State.exception = SIG_D10V_BUS;
2952      State.pc_changed = 1; /* Don't increment the PC. */
2953      trace_output_void ();
2954      return;
2955    }
2956  SW (addr + 0, GPR (OP[0] + 0));
2957  SW (addr + 2, GPR (OP[0] + 1));
2958  INC_ADDR (OP[1], -4);
2959  trace_output_void ();
2960}
2961
2962/* st2w */
2963void
2964OP_37010000 ()
2965{
2966  uint16 addr = OP[1];
2967  trace_input ("st2w", OP_DREG, OP_MEMREF3, OP_VOID);
2968  if ((addr & 1))
2969    {
2970      State.exception = SIG_D10V_BUS;
2971      State.pc_changed = 1; /* Don't increment the PC. */
2972      trace_output_void ();
2973      return;
2974    }
2975  SW (addr + 0, GPR (OP[0] + 0));
2976  SW (addr + 2, GPR (OP[0] + 1));
2977  trace_output_void ();
2978}
2979
2980/* stb */
2981void
2982OP_3C000000 ()
2983{
2984  trace_input ("stb", OP_REG, OP_MEMREF2, OP_VOID);
2985  SB (GPR (OP[2]) + OP[1], GPR (OP[0]));
2986  trace_output_void ();
2987}
2988
2989/* stb */
2990void
2991OP_7800 ()
2992{
2993  trace_input ("stb", OP_REG, OP_MEMREF, OP_VOID);
2994  SB (GPR (OP[1]), GPR (OP[0]));
2995  trace_output_void ();
2996}
2997
2998/* stop */
2999void
3000OP_5FE0 ()
3001{
3002  trace_input ("stop", OP_VOID, OP_VOID, OP_VOID);
3003  State.exception = SIG_D10V_STOP;
3004  trace_output_void ();
3005}
3006
3007/* sub */
3008void
3009OP_0 ()
3010{
3011  uint16 a = GPR (OP[0]);
3012  uint16 b = GPR (OP[1]);
3013  uint16 tmp = (a - b);
3014  trace_input ("sub", OP_REG, OP_REG, OP_VOID);
3015  /* see ../common/sim-alu.h for a more extensive discussion on how to
3016     compute the carry/overflow bits. */
3017  SET_PSW_C (a >= b);
3018  SET_GPR (OP[0], tmp);
3019  trace_output_16 (tmp);
3020}
3021
3022/* sub */
3023void
3024OP_1001 ()
3025{
3026  int64 tmp;
3027
3028  trace_input ("sub", OP_ACCUM, OP_DREG, OP_VOID);
3029  tmp = SEXT40(ACC (OP[0])) - (SEXT16 (GPR (OP[1])) << 16 | GPR (OP[1] + 1));
3030  if (PSW_ST)
3031    {
3032      if (tmp > SEXT40(MAX32))
3033	tmp = (MAX32);
3034      else if (tmp < SEXT40(MIN32))
3035	tmp = (MIN32);
3036      else
3037	tmp = (tmp & MASK40);
3038    }
3039  else
3040    tmp = (tmp & MASK40);
3041  SET_ACC (OP[0], tmp);
3042
3043  trace_output_40 (tmp);
3044}
3045
3046/* sub */
3047
3048void
3049OP_1003 ()
3050{
3051  int64 tmp;
3052
3053  trace_input ("sub", OP_ACCUM, OP_ACCUM, OP_VOID);
3054  tmp = SEXT40(ACC (OP[0])) - SEXT40(ACC (OP[1]));
3055  if (PSW_ST)
3056    {
3057      if (tmp > SEXT40(MAX32))
3058	tmp = (MAX32);
3059      else if (tmp < SEXT40(MIN32))
3060	tmp = (MIN32);
3061      else
3062	tmp = (tmp & MASK40);
3063    }
3064  else
3065    tmp = (tmp & MASK40);
3066  SET_ACC (OP[0], tmp);
3067
3068  trace_output_40 (tmp);
3069}
3070
3071/* sub2w */
3072void
3073OP_1000 ()
3074{
3075  uint32 tmp, a, b;
3076
3077  trace_input ("sub2w", OP_DREG, OP_DREG, OP_VOID);
3078  a = (uint32)((GPR (OP[0]) << 16) | GPR (OP[0] + 1));
3079  b = (uint32)((GPR (OP[1]) << 16) | GPR (OP[1] + 1));
3080  /* see ../common/sim-alu.h for a more extensive discussion on how to
3081     compute the carry/overflow bits */
3082  tmp = a - b;
3083  SET_PSW_C (a >= b);
3084  SET_GPR32 (OP[0], tmp);
3085  trace_output_32 (tmp);
3086}
3087
3088/* subac3 */
3089void
3090OP_17000000 ()
3091{
3092  int64 tmp;
3093
3094  trace_input ("subac3", OP_DREG_OUTPUT, OP_DREG, OP_ACCUM);
3095  tmp = SEXT40 ((GPR (OP[1]) << 16) | GPR (OP[1] + 1)) - SEXT40 (ACC (OP[2]));
3096  SET_GPR32 (OP[0], tmp);
3097  trace_output_32 (tmp);
3098}
3099
3100/* subac3 */
3101void
3102OP_17000002 ()
3103{
3104  int64 tmp;
3105
3106  trace_input ("subac3", OP_DREG_OUTPUT, OP_ACCUM, OP_ACCUM);
3107  tmp = SEXT40 (ACC (OP[1])) - SEXT40(ACC (OP[2]));
3108  SET_GPR32 (OP[0], tmp);
3109  trace_output_32 (tmp);
3110}
3111
3112/* subac3s */
3113void
3114OP_17001000 ()
3115{
3116  int64 tmp;
3117
3118  trace_input ("subac3s", OP_DREG_OUTPUT, OP_DREG, OP_ACCUM);
3119  SET_PSW_F1 (PSW_F0);
3120  tmp = SEXT40 ((GPR (OP[1]) << 16) | GPR (OP[1] + 1)) - SEXT40(ACC (OP[2]));
3121  if (tmp > SEXT40(MAX32))
3122    {
3123      tmp = (MAX32);
3124      SET_PSW_F0 (1);
3125    }
3126  else if (tmp < SEXT40(MIN32))
3127    {
3128      tmp = (MIN32);
3129      SET_PSW_F0 (1);
3130    }
3131  else
3132    {
3133      SET_PSW_F0 (0);
3134    }
3135  SET_GPR32 (OP[0], tmp);
3136  trace_output_32 (tmp);
3137}
3138
3139/* subac3s */
3140void
3141OP_17001002 ()
3142{
3143  int64 tmp;
3144
3145  trace_input ("subac3s", OP_DREG_OUTPUT, OP_ACCUM, OP_ACCUM);
3146  SET_PSW_F1 (PSW_F0);
3147  tmp = SEXT40(ACC (OP[1])) - SEXT40(ACC (OP[2]));
3148  if (tmp > SEXT40(MAX32))
3149    {
3150      tmp = (MAX32);
3151      SET_PSW_F0 (1);
3152    }
3153  else if (tmp < SEXT40(MIN32))
3154    {
3155      tmp = (MIN32);
3156      SET_PSW_F0 (1);
3157    }
3158  else
3159    {
3160      SET_PSW_F0 (0);
3161    }
3162  SET_GPR32 (OP[0], tmp);
3163  trace_output_32 (tmp);
3164}
3165
3166/* subi */
3167void
3168OP_1 ()
3169{
3170  unsigned tmp;
3171  if (OP[1] == 0)
3172    OP[1] = 16;
3173
3174  trace_input ("subi", OP_REG, OP_CONSTANT16, OP_VOID);
3175  /* see ../common/sim-alu.h for a more extensive discussion on how to
3176     compute the carry/overflow bits. */
3177  /* since OP[1] is never <= 0, -OP[1] == ~OP[1]+1 can never overflow */
3178  tmp = ((unsigned)(unsigned16) GPR (OP[0])
3179	 + (unsigned)(unsigned16) ( - OP[1]));
3180  SET_PSW_C (tmp >= (1 << 16));
3181  SET_GPR (OP[0], tmp);
3182  trace_output_16 (tmp);
3183}
3184
3185/* trap */
3186void
3187OP_5F00 ()
3188{
3189  trace_input ("trap", OP_CONSTANT4, OP_VOID, OP_VOID);
3190  trace_output_void ();
3191
3192  switch (OP[0])
3193    {
3194    default:
3195#if (DEBUG & DEBUG_TRAP) == 0
3196      {
3197	uint16 vec = OP[0] + TRAP_VECTOR_START;
3198	SET_BPC (PC + 1);
3199	SET_BPSW (PSW);
3200	SET_PSW (PSW & PSW_SM_BIT);
3201	JMP (vec);
3202	break;
3203      }
3204#else			/* if debugging use trap to print registers */
3205      {
3206	int i;
3207	static int first_time = 1;
3208
3209	if (first_time)
3210	  {
3211	    first_time = 0;
3212	    (*d10v_callback->printf_filtered) (d10v_callback, "Trap  #     PC ");
3213	    for (i = 0; i < 16; i++)
3214	      (*d10v_callback->printf_filtered) (d10v_callback, "  %sr%d", (i > 9) ? "" : " ", i);
3215	    (*d10v_callback->printf_filtered) (d10v_callback, "         a0         a1 f0 f1 c\n");
3216	  }
3217
3218	(*d10v_callback->printf_filtered) (d10v_callback, "Trap %2d 0x%.4x:", (int)OP[0], (int)PC);
3219
3220	for (i = 0; i < 16; i++)
3221	  (*d10v_callback->printf_filtered) (d10v_callback, " %.4x", (int) GPR (i));
3222
3223	for (i = 0; i < 2; i++)
3224	  (*d10v_callback->printf_filtered) (d10v_callback, " %.2x%.8lx",
3225					     ((int)(ACC (i) >> 32) & 0xff),
3226					     ((unsigned long) ACC (i)) & 0xffffffff);
3227
3228	(*d10v_callback->printf_filtered) (d10v_callback, "  %d  %d %d\n",
3229					   PSW_F0 != 0, PSW_F1 != 0, PSW_C != 0);
3230	(*d10v_callback->flush_stdout) (d10v_callback);
3231	break;
3232      }
3233#endif
3234    case 15:			/* new system call trap */
3235      /* Trap 15 is used for simulating low-level I/O */
3236      {
3237	unsigned32 result = 0;
3238	errno = 0;
3239
3240/* Registers passed to trap 0 */
3241
3242#define FUNC   GPR (4)	/* function number */
3243#define PARM1  GPR (0)	/* optional parm 1 */
3244#define PARM2  GPR (1)	/* optional parm 2 */
3245#define PARM3  GPR (2)	/* optional parm 3 */
3246#define PARM4  GPR (3)	/* optional parm 3 */
3247
3248/* Registers set by trap 0 */
3249
3250#define RETVAL(X)   do { result = (X); SET_GPR (0, result); } while (0)
3251#define RETVAL32(X) do { result = (X); SET_GPR (0, result >> 16); SET_GPR (1, result); } while (0)
3252#define RETERR(X) SET_GPR (4, (X))		/* return error code */
3253
3254/* Turn a pointer in a register into a pointer into real memory. */
3255
3256#define MEMPTR(x) ((char *)(dmem_addr(x)))
3257
3258	switch (FUNC)
3259	  {
3260#if !defined(__GO32__) && !defined(_WIN32)
3261	  case TARGET_SYS_fork:
3262	    trace_input ("<fork>", OP_VOID, OP_VOID, OP_VOID);
3263	    RETVAL (fork ());
3264	    trace_output_16 (result);
3265	    break;
3266
3267#define getpid() 47
3268	  case TARGET_SYS_getpid:
3269	    trace_input ("<getpid>", OP_VOID, OP_VOID, OP_VOID);
3270	    RETVAL (getpid ());
3271	    trace_output_16 (result);
3272	    break;
3273
3274	  case TARGET_SYS_kill:
3275	    trace_input ("<kill>", OP_R0, OP_R1, OP_VOID);
3276	    if (PARM1 == getpid ())
3277	      {
3278		trace_output_void ();
3279		State.exception = PARM2;
3280	      }
3281	    else
3282	      {
3283		int os_sig = -1;
3284		switch (PARM2)
3285		  {
3286#ifdef SIGHUP
3287		  case 1: os_sig = SIGHUP;	break;
3288#endif
3289#ifdef SIGINT
3290		  case 2: os_sig = SIGINT;	break;
3291#endif
3292#ifdef SIGQUIT
3293		  case 3: os_sig = SIGQUIT;	break;
3294#endif
3295#ifdef SIGILL
3296		  case 4: os_sig = SIGILL;	break;
3297#endif
3298#ifdef SIGTRAP
3299		  case 5: os_sig = SIGTRAP;	break;
3300#endif
3301#ifdef SIGABRT
3302		  case 6: os_sig = SIGABRT;	break;
3303#elif defined(SIGIOT)
3304		  case 6: os_sig = SIGIOT;	break;
3305#endif
3306#ifdef SIGEMT
3307		  case 7: os_sig = SIGEMT;	break;
3308#endif
3309#ifdef SIGFPE
3310		  case 8: os_sig = SIGFPE;	break;
3311#endif
3312#ifdef SIGKILL
3313		  case 9: os_sig = SIGKILL;	break;
3314#endif
3315#ifdef SIGBUS
3316		  case 10: os_sig = SIGBUS;	break;
3317#endif
3318#ifdef SIGSEGV
3319		  case 11: os_sig = SIGSEGV;	break;
3320#endif
3321#ifdef SIGSYS
3322		  case 12: os_sig = SIGSYS;	break;
3323#endif
3324#ifdef SIGPIPE
3325		  case 13: os_sig = SIGPIPE;	break;
3326#endif
3327#ifdef SIGALRM
3328		  case 14: os_sig = SIGALRM;	break;
3329#endif
3330#ifdef SIGTERM
3331		  case 15: os_sig = SIGTERM;	break;
3332#endif
3333#ifdef SIGURG
3334		  case 16: os_sig = SIGURG;	break;
3335#endif
3336#ifdef SIGSTOP
3337		  case 17: os_sig = SIGSTOP;	break;
3338#endif
3339#ifdef SIGTSTP
3340		  case 18: os_sig = SIGTSTP;	break;
3341#endif
3342#ifdef SIGCONT
3343		  case 19: os_sig = SIGCONT;	break;
3344#endif
3345#ifdef SIGCHLD
3346		  case 20: os_sig = SIGCHLD;	break;
3347#elif defined(SIGCLD)
3348		  case 20: os_sig = SIGCLD;	break;
3349#endif
3350#ifdef SIGTTIN
3351		  case 21: os_sig = SIGTTIN;	break;
3352#endif
3353#ifdef SIGTTOU
3354		  case 22: os_sig = SIGTTOU;	break;
3355#endif
3356#ifdef SIGIO
3357		  case 23: os_sig = SIGIO;	break;
3358#elif defined (SIGPOLL)
3359		  case 23: os_sig = SIGPOLL;	break;
3360#endif
3361#ifdef SIGXCPU
3362		  case 24: os_sig = SIGXCPU;	break;
3363#endif
3364#ifdef SIGXFSZ
3365		  case 25: os_sig = SIGXFSZ;	break;
3366#endif
3367#ifdef SIGVTALRM
3368		  case 26: os_sig = SIGVTALRM;	break;
3369#endif
3370#ifdef SIGPROF
3371		  case 27: os_sig = SIGPROF;	break;
3372#endif
3373#ifdef SIGWINCH
3374		  case 28: os_sig = SIGWINCH;	break;
3375#endif
3376#ifdef SIGLOST
3377		  case 29: os_sig = SIGLOST;	break;
3378#endif
3379#ifdef SIGUSR1
3380		  case 30: os_sig = SIGUSR1;	break;
3381#endif
3382#ifdef SIGUSR2
3383		  case 31: os_sig = SIGUSR2;	break;
3384#endif
3385		  }
3386
3387		if (os_sig == -1)
3388		  {
3389		    trace_output_void ();
3390		    (*d10v_callback->printf_filtered) (d10v_callback, "Unknown signal %d\n", PARM2);
3391		    (*d10v_callback->flush_stdout) (d10v_callback);
3392		    State.exception = SIGILL;
3393		  }
3394		else
3395		  {
3396		    RETVAL (kill (PARM1, PARM2));
3397		    trace_output_16 (result);
3398		  }
3399	      }
3400	    break;
3401
3402	  case TARGET_SYS_execve:
3403	    trace_input ("<execve>", OP_R0, OP_R1, OP_R2);
3404	    RETVAL (execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2),
3405			     (char **)MEMPTR (PARM3)));
3406	    trace_output_16 (result);
3407	    break;
3408
3409#ifdef TARGET_SYS_execv
3410	  case TARGET_SYS_execv:
3411	    trace_input ("<execv>", OP_R0, OP_R1, OP_VOID);
3412	    RETVAL (execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), NULL));
3413	    trace_output_16 (result);
3414	    break;
3415#endif
3416
3417	  case TARGET_SYS_pipe:
3418	    {
3419	      reg_t buf;
3420	      int host_fd[2];
3421
3422	      trace_input ("<pipe>", OP_R0, OP_VOID, OP_VOID);
3423	      buf = PARM1;
3424	      RETVAL (pipe (host_fd));
3425	      SW (buf, host_fd[0]);
3426	      buf += sizeof(uint16);
3427	      SW (buf, host_fd[1]);
3428	      trace_output_16 (result);
3429	    }
3430	  break;
3431
3432#if 0
3433#ifdef TARGET_SYS_wait
3434	  case TARGET_SYS_wait:
3435	    {
3436	      int status;
3437	      trace_input ("<wait>", OP_R0, OP_VOID, OP_VOID);
3438	      RETVAL (wait (&status));
3439	      if (PARM1)
3440		SW (PARM1, status);
3441	      trace_output_16 (result);
3442	    }
3443	  break;
3444#endif
3445#endif
3446#else
3447	  case TARGET_SYS_getpid:
3448	    trace_input ("<getpid>", OP_VOID, OP_VOID, OP_VOID);
3449	    RETVAL (1);
3450	    trace_output_16 (result);
3451	    break;
3452
3453	  case TARGET_SYS_kill:
3454	    trace_input ("<kill>", OP_REG, OP_REG, OP_VOID);
3455	    trace_output_void ();
3456	    State.exception = PARM2;
3457	    break;
3458#endif
3459
3460	  case TARGET_SYS_read:
3461	    trace_input ("<read>", OP_R0, OP_R1, OP_R2);
3462	    RETVAL (d10v_callback->read (d10v_callback, PARM1, MEMPTR (PARM2),
3463					  PARM3));
3464	    trace_output_16 (result);
3465	    break;
3466
3467	  case TARGET_SYS_write:
3468	    trace_input ("<write>", OP_R0, OP_R1, OP_R2);
3469	    if (PARM1 == 1)
3470	      RETVAL ((int)d10v_callback->write_stdout (d10v_callback,
3471							 MEMPTR (PARM2), PARM3));
3472	    else
3473	      RETVAL ((int)d10v_callback->write (d10v_callback, PARM1,
3474						  MEMPTR (PARM2), PARM3));
3475	    trace_output_16 (result);
3476	    break;
3477
3478	  case TARGET_SYS_lseek:
3479	    trace_input ("<lseek>", OP_R0, OP_R1, OP_R2);
3480	    RETVAL32 (d10v_callback->lseek (d10v_callback, PARM1,
3481					    ((((unsigned long) PARM2) << 16)
3482					     || (unsigned long) PARM3),
3483					    PARM4));
3484	    trace_output_32 (result);
3485	    break;
3486
3487	  case TARGET_SYS_close:
3488	    trace_input ("<close>", OP_R0, OP_VOID, OP_VOID);
3489	    RETVAL (d10v_callback->close (d10v_callback, PARM1));
3490	    trace_output_16 (result);
3491	    break;
3492
3493	  case TARGET_SYS_open:
3494	    trace_input ("<open>", OP_R0, OP_R1, OP_R2);
3495	    RETVAL (d10v_callback->open (d10v_callback, MEMPTR (PARM1), PARM2));
3496	    trace_output_16 (result);
3497	    break;
3498
3499	  case TARGET_SYS_exit:
3500	    trace_input ("<exit>", OP_R0, OP_VOID, OP_VOID);
3501	    State.exception = SIG_D10V_EXIT;
3502	    trace_output_void ();
3503	    break;
3504
3505#ifdef TARGET_SYS_stat
3506	  case TARGET_SYS_stat:
3507	    trace_input ("<stat>", OP_R0, OP_R1, OP_VOID);
3508	    /* stat system call */
3509	    {
3510	      struct stat host_stat;
3511	      reg_t buf;
3512
3513	      RETVAL (stat (MEMPTR (PARM1), &host_stat));
3514
3515	      buf = PARM2;
3516
3517	      /* The hard-coded offsets and sizes were determined by using
3518	       * the D10V compiler on a test program that used struct stat.
3519	       */
3520	      SW  (buf,    host_stat.st_dev);
3521	      SW  (buf+2,  host_stat.st_ino);
3522	      SW  (buf+4,  host_stat.st_mode);
3523	      SW  (buf+6,  host_stat.st_nlink);
3524	      SW  (buf+8,  host_stat.st_uid);
3525	      SW  (buf+10, host_stat.st_gid);
3526	      SW  (buf+12, host_stat.st_rdev);
3527	      SLW (buf+16, host_stat.st_size);
3528	      SLW (buf+20, host_stat.st_atime);
3529	      SLW (buf+28, host_stat.st_mtime);
3530	      SLW (buf+36, host_stat.st_ctime);
3531	    }
3532	    trace_output_16 (result);
3533	    break;
3534#endif
3535
3536	  case TARGET_SYS_chown:
3537	    trace_input ("<chown>", OP_R0, OP_R1, OP_R2);
3538	    RETVAL (chown (MEMPTR (PARM1), PARM2, PARM3));
3539	    trace_output_16 (result);
3540	    break;
3541
3542	  case TARGET_SYS_chmod:
3543	    trace_input ("<chmod>", OP_R0, OP_R1, OP_R2);
3544	    RETVAL (chmod (MEMPTR (PARM1), PARM2));
3545	    trace_output_16 (result);
3546	    break;
3547
3548#if 0
3549#ifdef TARGET_SYS_utime
3550	  case TARGET_SYS_utime:
3551	    trace_input ("<utime>", OP_R0, OP_R1, OP_R2);
3552	    /* Cast the second argument to void *, to avoid type mismatch
3553	       if a prototype is present.  */
3554	    RETVAL (utime (MEMPTR (PARM1), (void *) MEMPTR (PARM2)));
3555	    trace_output_16 (result);
3556	    break;
3557#endif
3558#endif
3559
3560#if 0
3561#ifdef TARGET_SYS_time
3562	  case TARGET_SYS_time:
3563	    trace_input ("<time>", OP_R0, OP_R1, OP_R2);
3564	    RETVAL32 (time (PARM1 ? MEMPTR (PARM1) : NULL));
3565	    trace_output_32 (result);
3566	    break;
3567#endif
3568#endif
3569
3570	  default:
3571	    d10v_callback->error (d10v_callback, "Unknown syscall %d", FUNC);
3572	  }
3573	if ((uint16) result == (uint16) -1)
3574	  RETERR (d10v_callback->get_errno(d10v_callback));
3575	else
3576	  RETERR (0);
3577	break;
3578      }
3579    }
3580}
3581
3582/* tst0i */
3583void
3584OP_7000000 ()
3585{
3586  trace_input ("tst0i", OP_REG, OP_CONSTANT16, OP_VOID);
3587  SET_PSW_F1 (PSW_F0);;
3588  SET_PSW_F0 ((GPR (OP[0]) & OP[1]) ? 1 : 0);
3589  trace_output_flag ();
3590}
3591
3592/* tst1i */
3593void
3594OP_F000000 ()
3595{
3596  trace_input ("tst1i", OP_REG, OP_CONSTANT16, OP_VOID);
3597  SET_PSW_F1 (PSW_F0);
3598  SET_PSW_F0 ((~(GPR (OP[0])) & OP[1]) ? 1 : 0);
3599  trace_output_flag ();
3600}
3601
3602/* wait */
3603void
3604OP_5F80 ()
3605{
3606  trace_input ("wait", OP_VOID, OP_VOID, OP_VOID);
3607  SET_PSW_IE (1);
3608  trace_output_void ();
3609}
3610
3611/* xor */
3612void
3613OP_A00 ()
3614{
3615  int16 tmp;
3616  trace_input ("xor", OP_REG, OP_REG, OP_VOID);
3617  tmp = (GPR (OP[0]) ^ GPR (OP[1]));
3618  SET_GPR (OP[0], tmp);
3619  trace_output_16 (tmp);
3620}
3621
3622/* xor3 */
3623void
3624OP_5000000 ()
3625{
3626  int16 tmp;
3627  trace_input ("xor3", OP_REG_OUTPUT, OP_REG, OP_CONSTANT16);
3628  tmp = (GPR (OP[1]) ^ OP[2]);
3629  SET_GPR (OP[0], tmp);
3630  trace_output_16 (tmp);
3631}
3632