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