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