]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/h8300/compile.c
gdb/sim: add support for exporting memory map
[thirdparty/binutils-gdb.git] / sim / h8300 / compile.c
CommitLineData
c906108c 1/*
9f70f8ec 2 * Simulator for the Renesas (formerly Hitachi) H8/300 architecture.
c906108c
SS
3 *
4 * Written by Steve Chamberlain of Cygnus Support. sac@cygnus.com
5 *
6 * This file is part of H8/300 sim
7 *
8 *
9 * THIS SOFTWARE IS NOT COPYRIGHTED
10 *
11 * Cygnus offers the following for use in the public domain. Cygnus makes no
12 * warranty with regard to the software or its performance and the user
13 * accepts the software "AS IS" with all faults.
14 *
15 * CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS
16 * SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
17 * AND FITNESS FOR A PARTICULAR PURPOSE.
18 */
19
a6ff997c 20#include "config.h"
c906108c
SS
21#include <signal.h>
22#ifdef HAVE_TIME_H
23#include <time.h>
24#endif
25#ifdef HAVE_STDLIB_H
26#include <stdlib.h>
27#endif
28#ifdef HAVE_SYS_PARAM_H
29#include <sys/param.h>
30#endif
dc5c3759 31
c906108c 32#include "bfd.h"
dc5c3759 33#include "sim-main.h"
a64bfde3 34#include "gdb/sim-h8300.h"
bf174226
V
35#include "sys/stat.h"
36#include "sys/types.h"
f95f4ed2 37#include "sim-options.h"
c906108c
SS
38
39#ifndef SIGTRAP
40# define SIGTRAP 5
41#endif
42
43int debug;
44
c906108c
SS
45/* FIXME: Needs to live in header file.
46 This header should also include the things in remote-sim.h.
47 One could move this to remote-sim.h but this function isn't needed
48 by gdb. */
dc5c3759 49static void set_simcache_size (SIM_DESC, int);
c906108c 50
dc5c3759 51#define X(op, size) (op * 4 + size)
c906108c 52
59768597 53#define SP (h8300hmode && !h8300_normal_mode ? SL : SW)
dc5c3759 54
c906108c
SS
55#define h8_opcodes ops
56#define DEFINE_TABLE
57#include "opcode/h8300.h"
58
dc5c3759 59/* CPU data object: */
c906108c 60
dc5c3759
MS
61static unsigned int
62h8_get_pc (SIM_DESC sd)
63{
64 return (STATE_CPU (sd, 0)) -> pc;
65}
7a292a7a 66
dc5c3759
MS
67static void
68h8_set_pc (SIM_DESC sd, unsigned int val)
69{
70 (STATE_CPU (sd, 0)) -> pc = val;
71}
fc974602 72
dc5c3759
MS
73static unsigned int
74h8_get_ccr (SIM_DESC sd)
75{
76 return (STATE_CPU (sd, 0)) -> regs[CCR_REGNUM];
77}
c906108c 78
dc5c3759
MS
79static void
80h8_set_ccr (SIM_DESC sd, unsigned int val)
81{
82 (STATE_CPU (sd, 0)) -> regs[CCR_REGNUM] = val;
83}
c906108c 84
dc5c3759
MS
85static unsigned int
86h8_get_exr (SIM_DESC sd)
87{
88 return (STATE_CPU (sd, 0)) -> regs[EXR_REGNUM];
89}
c906108c 90
dc5c3759
MS
91static void
92h8_set_exr (SIM_DESC sd, unsigned int val)
93{
94 (STATE_CPU (sd, 0)) -> regs[EXR_REGNUM] = val;
95}
c906108c 96
dc5c3759
MS
97static int
98h8_get_sbr (SIM_DESC sd)
99{
100 return (STATE_CPU (sd, 0)) -> regs[SBR_REGNUM];
101}
c906108c 102
dc5c3759
MS
103static void
104h8_set_sbr (SIM_DESC sd, int val)
105{
106 (STATE_CPU (sd, 0)) -> regs[SBR_REGNUM] = val;
107}
c906108c 108
c906108c 109static int
dc5c3759
MS
110h8_get_vbr (SIM_DESC sd)
111{
112 return (STATE_CPU (sd, 0)) -> regs[VBR_REGNUM];
113}
114
115static void
116h8_set_vbr (SIM_DESC sd, int val)
c906108c 117{
dc5c3759 118 (STATE_CPU (sd, 0)) -> regs[VBR_REGNUM] = val;
c906108c
SS
119}
120
121static int
dc5c3759 122h8_get_cache_top (SIM_DESC sd)
c906108c 123{
dc5c3759
MS
124 return sd -> cache_top;
125}
126
127static void
128h8_set_cache_top (SIM_DESC sd, int val)
129{
130 sd -> cache_top = val;
c906108c
SS
131}
132
c906108c 133static int
dc5c3759 134h8_get_mask (SIM_DESC sd)
c906108c 135{
dc5c3759 136 return (STATE_CPU (sd, 0)) -> mask;
c906108c
SS
137}
138
dc5c3759
MS
139static void
140h8_set_mask (SIM_DESC sd, int val)
c906108c 141{
dc5c3759
MS
142 (STATE_CPU (sd, 0)) -> mask = val;
143}
144#if 0
145static int
146h8_get_exception (SIM_DESC sd)
147{
148 return (STATE_CPU (sd, 0)) -> exception;
149}
c906108c 150
dc5c3759
MS
151static void
152h8_set_exception (SIM_DESC sd, int val)
153{
154 (STATE_CPU (sd, 0)) -> exception = val;
155}
0ef9643e 156
dc5c3759
MS
157static enum h8300_sim_state
158h8_get_state (SIM_DESC sd)
159{
160 return sd -> state;
c906108c
SS
161}
162
dc5c3759
MS
163static void
164h8_set_state (SIM_DESC sd, enum h8300_sim_state val)
d1360fb0 165{
dc5c3759
MS
166 sd -> state = val;
167}
168#endif
169static unsigned int
170h8_get_cycles (SIM_DESC sd)
171{
172 return (STATE_CPU (sd, 0)) -> regs[CYCLE_REGNUM];
173}
174
175static void
176h8_set_cycles (SIM_DESC sd, unsigned int val)
177{
178 (STATE_CPU (sd, 0)) -> regs[CYCLE_REGNUM] = val;
d1360fb0
V
179}
180
c906108c 181static unsigned int
dc5c3759 182h8_get_insts (SIM_DESC sd)
c906108c 183{
dc5c3759
MS
184 return (STATE_CPU (sd, 0)) -> regs[INST_REGNUM];
185}
0ef9643e 186
dc5c3759
MS
187static void
188h8_set_insts (SIM_DESC sd, unsigned int val)
189{
190 (STATE_CPU (sd, 0)) -> regs[INST_REGNUM] = val;
191}
0ef9643e 192
dc5c3759
MS
193static unsigned int
194h8_get_ticks (SIM_DESC sd)
195{
196 return (STATE_CPU (sd, 0)) -> regs[TICK_REGNUM];
197}
c906108c 198
dc5c3759
MS
199static void
200h8_set_ticks (SIM_DESC sd, unsigned int val)
201{
202 (STATE_CPU (sd, 0)) -> regs[TICK_REGNUM] = val;
203}
c906108c 204
dc5c3759
MS
205static unsigned int
206h8_get_mach (SIM_DESC sd)
207{
208 return (STATE_CPU (sd, 0)) -> regs[MACH_REGNUM];
209}
c906108c 210
dc5c3759
MS
211static void
212h8_set_mach (SIM_DESC sd, unsigned int val)
213{
214 (STATE_CPU (sd, 0)) -> regs[MACH_REGNUM] = val;
215}
0ef9643e 216
dc5c3759
MS
217static unsigned int
218h8_get_macl (SIM_DESC sd)
219{
220 return (STATE_CPU (sd, 0)) -> regs[MACL_REGNUM];
221}
0ef9643e 222
dc5c3759
MS
223static void
224h8_set_macl (SIM_DESC sd, unsigned int val)
225{
226 (STATE_CPU (sd, 0)) -> regs[MACL_REGNUM] = val;
227}
0ef9643e 228
dc5c3759
MS
229static int
230h8_get_compiles (SIM_DESC sd)
231{
232 return sd -> compiles;
233}
0ef9643e 234
dc5c3759
MS
235static void
236h8_increment_compiles (SIM_DESC sd)
237{
238 sd -> compiles ++;
239}
0ef9643e 240
dc5c3759
MS
241static unsigned int *
242h8_get_reg_buf (SIM_DESC sd)
243{
244 return &(((STATE_CPU (sd, 0)) -> regs)[0]);
245}
0ef9643e 246
dc5c3759
MS
247static unsigned int
248h8_get_reg (SIM_DESC sd, int regnum)
249{
250 return (STATE_CPU (sd, 0)) -> regs[regnum];
251}
c906108c 252
dc5c3759
MS
253static void
254h8_set_reg (SIM_DESC sd, int regnum, int val)
255{
256 (STATE_CPU (sd, 0)) -> regs[regnum] = val;
257}
0ef9643e 258
dc5c3759
MS
259#ifdef ADEBUG
260static int
261h8_get_stats (SIM_DESC sd, int idx)
262{
263 return sd -> stats[idx];
264}
c906108c 265
dc5c3759
MS
266static void
267h8_increment_stats (SIM_DESC sd, int idx)
268{
269 sd -> stats[idx] ++;
270}
271#endif /* ADEBUG */
c906108c 272
dc5c3759
MS
273static unsigned short *
274h8_get_cache_idx_buf (SIM_DESC sd)
275{
276 return sd -> cache_idx;
277}
c906108c 278
dc5c3759
MS
279static void
280h8_set_cache_idx_buf (SIM_DESC sd, unsigned short *ptr)
281{
282 sd -> cache_idx = ptr;
283}
c906108c 284
dc5c3759
MS
285static unsigned short
286h8_get_cache_idx (SIM_DESC sd, unsigned int idx)
287{
288 if (idx > sd->memory_size)
289 return (unsigned short) -1;
290 return sd -> cache_idx[idx];
291}
c906108c 292
dc5c3759
MS
293static void
294h8_set_cache_idx (SIM_DESC sd, int idx, unsigned int val)
295{
296 sd -> cache_idx[idx] = (unsigned short) val;
297}
c906108c 298
dc5c3759
MS
299static unsigned char *
300h8_get_memory_buf (SIM_DESC sd)
301{
302 return (STATE_CPU (sd, 0)) -> memory;
303}
c906108c 304
dc5c3759
MS
305static void
306h8_set_memory_buf (SIM_DESC sd, unsigned char *ptr)
307{
308 (STATE_CPU (sd, 0)) -> memory = ptr;
309}
c906108c 310
dc5c3759
MS
311static unsigned char
312h8_get_memory (SIM_DESC sd, int idx)
313{
314 return (STATE_CPU (sd, 0)) -> memory[idx];
315}
c906108c 316
dc5c3759
MS
317static void
318h8_set_memory (SIM_DESC sd, int idx, unsigned int val)
319{
320 (STATE_CPU (sd, 0)) -> memory[idx] = (unsigned char) val;
321}
c906108c 322
dc5c3759
MS
323static unsigned char *
324h8_get_eightbit_buf (SIM_DESC sd)
325{
326 return (STATE_CPU (sd, 0)) -> eightbit;
327}
c906108c 328
dc5c3759
MS
329static void
330h8_set_eightbit_buf (SIM_DESC sd, unsigned char *ptr)
331{
332 (STATE_CPU (sd, 0)) -> eightbit = ptr;
333}
c906108c 334
dc5c3759
MS
335static unsigned char
336h8_get_eightbit (SIM_DESC sd, int idx)
337{
338 return (STATE_CPU (sd, 0)) -> eightbit[idx];
339}
c906108c 340
dc5c3759
MS
341static void
342h8_set_eightbit (SIM_DESC sd, int idx, unsigned int val)
343{
344 (STATE_CPU (sd, 0)) -> eightbit[idx] = (unsigned char) val;
345}
c906108c 346
dc5c3759
MS
347static unsigned int
348h8_get_delayed_branch (SIM_DESC sd)
349{
350 return (STATE_CPU (sd, 0)) -> delayed_branch;
c906108c
SS
351}
352
c906108c 353static void
dc5c3759 354h8_set_delayed_branch (SIM_DESC sd, unsigned int dest)
c906108c 355{
dc5c3759
MS
356 (STATE_CPU (sd, 0)) -> delayed_branch = dest;
357}
c906108c 358
dc5c3759
MS
359static char **
360h8_get_command_line (SIM_DESC sd)
361{
362 return (STATE_CPU (sd, 0)) -> command_line;
363}
c906108c 364
dc5c3759
MS
365static void
366h8_set_command_line (SIM_DESC sd, char ** val)
367{
368 (STATE_CPU (sd, 0)) -> command_line = val;
369}
c906108c 370
dc5c3759
MS
371static char *
372h8_get_cmdline_arg (SIM_DESC sd, int index)
373{
374 return (STATE_CPU (sd, 0)) -> command_line[index];
375}
c906108c 376
dc5c3759
MS
377static void
378h8_set_cmdline_arg (SIM_DESC sd, int index, char * val)
379{
380 (STATE_CPU (sd, 0)) -> command_line[index] = val;
381}
c906108c 382
dc5c3759
MS
383/* MAC Saturation Mode */
384static int
385h8_get_macS (SIM_DESC sd)
386{
387 return (STATE_CPU (sd, 0)) -> macS;
c906108c
SS
388}
389
dc5c3759
MS
390static void
391h8_set_macS (SIM_DESC sd, int val)
392{
393 (STATE_CPU (sd, 0)) -> macS = (val != 0);
394}
c906108c 395
dc5c3759
MS
396/* MAC Zero Flag */
397static int
398h8_get_macZ (SIM_DESC sd)
399{
400 return (STATE_CPU (sd, 0)) -> macZ;
401}
c906108c 402
dc5c3759
MS
403static void
404h8_set_macZ (SIM_DESC sd, int val)
405{
406 (STATE_CPU (sd, 0)) -> macZ = (val != 0);
407}
c906108c 408
dc5c3759
MS
409/* MAC Negative Flag */
410static int
411h8_get_macN (SIM_DESC sd)
412{
413 return (STATE_CPU (sd, 0)) -> macN;
414}
c906108c 415
dc5c3759
MS
416static void
417h8_set_macN (SIM_DESC sd, int val)
418{
419 (STATE_CPU (sd, 0)) -> macN = (val != 0);
420}
c906108c 421
dc5c3759
MS
422/* MAC Overflow Flag */
423static int
424h8_get_macV (SIM_DESC sd)
425{
426 return (STATE_CPU (sd, 0)) -> macV;
427}
c906108c 428
dc5c3759
MS
429static void
430h8_set_macV (SIM_DESC sd, int val)
431{
432 (STATE_CPU (sd, 0)) -> macV = (val != 0);
433}
c906108c 434
dc5c3759 435/* End CPU data object. */
c906108c 436
dc5c3759 437/* The rate at which to call the host's poll_quit callback. */
c906108c 438
dc5c3759 439enum { POLL_QUIT_INTERVAL = 0x80000 };
c906108c 440
dc5c3759
MS
441#define LOW_BYTE(x) ((x) & 0xff)
442#define HIGH_BYTE(x) (((x) >> 8) & 0xff)
443#define P(X, Y) ((X << 8) | Y)
c906108c 444
dc5c3759
MS
445#define C (c != 0)
446#define Z (nz == 0)
447#define V (v != 0)
448#define N (n != 0)
449#define U (u != 0)
450#define H (h != 0)
451#define UI (ui != 0)
452#define I (intMaskBit != 0)
c906108c 453
dc5c3759
MS
454#define BUILDSR(SD) \
455 h8_set_ccr (SD, (I << 7) | (UI << 6) | (H << 5) | (U << 4) \
456 | (N << 3) | (Z << 2) | (V << 1) | C)
c906108c 457
9f70f8ec
MS
458#define GETSR(SD) \
459 /* Get Status Register (flags). */ \
460 c = (h8_get_ccr (sd) >> 0) & 1; \
461 v = (h8_get_ccr (sd) >> 1) & 1; \
462 nz = !((h8_get_ccr (sd) >> 2) & 1); \
463 n = (h8_get_ccr (sd) >> 3) & 1; \
464 u = (h8_get_ccr (sd) >> 4) & 1; \
465 h = (h8_get_ccr (sd) >> 5) & 1; \
466 ui = ((h8_get_ccr (sd) >> 6) & 1); \
467 intMaskBit = (h8_get_ccr (sd) >> 7) & 1
468
469
dc5c3759
MS
470#ifdef __CHAR_IS_SIGNED__
471#define SEXTCHAR(x) ((char) (x))
472#endif
c906108c 473
dc5c3759
MS
474#ifndef SEXTCHAR
475#define SEXTCHAR(x) ((x & 0x80) ? (x | ~0xff) : x & 0xff)
476#endif
c906108c 477
dc5c3759
MS
478#define UEXTCHAR(x) ((x) & 0xff)
479#define UEXTSHORT(x) ((x) & 0xffff)
480#define SEXTSHORT(x) ((short) (x))
c906108c 481
dc5c3759
MS
482int h8300hmode = 0;
483int h8300smode = 0;
59768597 484int h8300_normal_mode = 0;
dc5c3759 485int h8300sxmode = 0;
c906108c 486
dc5c3759 487static int memory_size;
c906108c 488
dc5c3759
MS
489static int
490get_now (void)
491{
492 return time (0); /* WinXX HAS UNIX like 'time', so why not use it? */
493}
c906108c 494
dc5c3759
MS
495static int
496now_persec (void)
497{
498 return 1;
499}
c906108c 500
dc5c3759
MS
501static int
502bitfrom (int x)
503{
504 switch (x & SIZE)
505 {
506 case L_8:
507 return SB;
508 case L_16:
509 case L_16U:
510 return SW;
511 case L_32:
512 return SL;
513 case L_P:
59768597 514 return (h8300hmode && !h8300_normal_mode)? SL : SW;
c906108c 515 }
dc5c3759 516 return 0;
c906108c
SS
517}
518
dc5c3759
MS
519/* Simulate an indirection / dereference.
520 return 0 for success, -1 for failure.
521*/
c906108c 522
dc5c3759
MS
523static unsigned int
524lvalue (SIM_DESC sd, int x, int rn, unsigned int *val)
c906108c 525{
4ca9d09e
MF
526 SIM_CPU *cpu = STATE_CPU (sd, 0);
527
dc5c3759
MS
528 if (val == NULL) /* Paranoia. */
529 return -1;
c906108c 530
dc5c3759 531 switch (x / 4)
c906108c 532 {
dc5c3759
MS
533 case OP_DISP:
534 if (rn == ZERO_REGNUM)
535 *val = X (OP_IMM, SP);
536 else
537 *val = X (OP_REG, SP);
c906108c 538 break;
dc5c3759
MS
539 case OP_MEM:
540 *val = X (OP_MEM, SP);
c906108c
SS
541 break;
542 default:
4ca9d09e 543 sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV);
dc5c3759 544 return -1;
c906108c 545 }
dc5c3759 546 return 0;
c906108c
SS
547}
548
dc5c3759
MS
549static int
550cmdline_location()
c906108c 551{
59768597 552 if (h8300smode && !h8300_normal_mode)
dc5c3759 553 return 0xffff00L;
59768597 554 else if (h8300hmode && !h8300_normal_mode)
dc5c3759
MS
555 return 0x2ff00L;
556 else
557 return 0xff00L;
c906108c
SS
558}
559
de9b1892 560static void
dc5c3759 561decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
c906108c 562{
dc5c3759
MS
563 int cst[3] = {0, 0, 0};
564 int reg[3] = {0, 0, 0};
565 int rdisp[3] = {0, 0, 0};
566 int opnum;
567 const struct h8_opcode *q;
c906108c 568
dc5c3759
MS
569 dst->dst.type = -1;
570 dst->src.type = -1;
c906108c 571
dc5c3759
MS
572 /* Find the exact opcode/arg combo. */
573 for (q = h8_opcodes; q->name; q++)
574 {
c4212d37 575 const op_type *nib = q->data.nib;
dc5c3759 576 unsigned int len = 0;
c906108c 577
dc5c3759 578 if ((q->available == AV_H8SX && !h8300sxmode) ||
9f70f8ec 579 (q->available == AV_H8S && !h8300smode) ||
dc5c3759
MS
580 (q->available == AV_H8H && !h8300hmode))
581 continue;
c906108c 582
f408565c
MS
583 cst[0] = cst[1] = cst[2] = 0;
584 reg[0] = reg[1] = reg[2] = 0;
585 rdisp[0] = rdisp[1] = rdisp[2] = 0;
586
dc5c3759 587 while (1)
c906108c 588 {
dc5c3759
MS
589 op_type looking_for = *nib;
590 int thisnib = data[len / 2];
c906108c 591
dc5c3759
MS
592 thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf);
593 opnum = ((looking_for & OP3) ? 2 :
594 (looking_for & DST) ? 1 : 0);
595
596 if (looking_for < 16 && looking_for >= 0)
c906108c 597 {
dc5c3759
MS
598 if (looking_for != thisnib)
599 goto fail;
c906108c 600 }
dc5c3759 601 else
c906108c 602 {
dc5c3759 603 if (looking_for & B31)
c906108c 604 {
dc5c3759
MS
605 if (!((thisnib & 0x8) != 0))
606 goto fail;
607
608 looking_for = (op_type) (looking_for & ~B31);
609 thisnib &= 0x7;
c906108c 610 }
dc5c3759 611 else if (looking_for & B30)
c906108c 612 {
dc5c3759
MS
613 if (!((thisnib & 0x8) == 0))
614 goto fail;
615
616 looking_for = (op_type) (looking_for & ~B30);
c906108c 617 }
c906108c 618
dc5c3759
MS
619 if (looking_for & B21)
620 {
621 if (!((thisnib & 0x4) != 0))
622 goto fail;
c906108c 623
dc5c3759
MS
624 looking_for = (op_type) (looking_for & ~B21);
625 thisnib &= 0xb;
626 }
627 else if (looking_for & B20)
628 {
629 if (!((thisnib & 0x4) == 0))
630 goto fail;
c906108c 631
dc5c3759
MS
632 looking_for = (op_type) (looking_for & ~B20);
633 }
c906108c 634
dc5c3759
MS
635 if (looking_for & B11)
636 {
637 if (!((thisnib & 0x2) != 0))
638 goto fail;
c906108c 639
dc5c3759
MS
640 looking_for = (op_type) (looking_for & ~B11);
641 thisnib &= 0xd;
642 }
643 else if (looking_for & B10)
644 {
645 if (!((thisnib & 0x2) == 0))
646 goto fail;
c906108c 647
dc5c3759
MS
648 looking_for = (op_type) (looking_for & ~B10);
649 }
c906108c 650
dc5c3759
MS
651 if (looking_for & B01)
652 {
653 if (!((thisnib & 0x1) != 0))
654 goto fail;
c906108c 655
dc5c3759
MS
656 looking_for = (op_type) (looking_for & ~B01);
657 thisnib &= 0xe;
658 }
659 else if (looking_for & B00)
660 {
661 if (!((thisnib & 0x1) == 0))
662 goto fail;
c906108c 663
dc5c3759
MS
664 looking_for = (op_type) (looking_for & ~B00);
665 }
c906108c 666
dc5c3759
MS
667 if (looking_for & IGNORE)
668 {
669 /* Hitachi has declared that IGNORE must be zero. */
670 if (thisnib != 0)
671 goto fail;
672 }
673 else if ((looking_for & MODE) == DATA)
674 {
675 ; /* Skip embedded data. */
676 }
677 else if ((looking_for & MODE) == DBIT)
678 {
679 /* Exclude adds/subs by looking at bit 0 and 2, and
680 make sure the operand size, either w or l,
681 matches by looking at bit 1. */
682 if ((looking_for & 7) != (thisnib & 7))
683 goto fail;
c906108c 684
dc5c3759
MS
685 cst[opnum] = (thisnib & 0x8) ? 2 : 1;
686 }
687 else if ((looking_for & MODE) == REG ||
688 (looking_for & MODE) == LOWREG ||
689 (looking_for & MODE) == IND ||
690 (looking_for & MODE) == PREINC ||
691 (looking_for & MODE) == POSTINC ||
692 (looking_for & MODE) == PREDEC ||
693 (looking_for & MODE) == POSTDEC)
694 {
695 reg[opnum] = thisnib;
696 }
697 else if (looking_for & CTRL)
698 {
699 thisnib &= 7;
700 if (((looking_for & MODE) == CCR && (thisnib != C_CCR)) ||
701 ((looking_for & MODE) == EXR && (thisnib != C_EXR)) ||
702 ((looking_for & MODE) == MACH && (thisnib != C_MACH)) ||
703 ((looking_for & MODE) == MACL && (thisnib != C_MACL)) ||
704 ((looking_for & MODE) == VBR && (thisnib != C_VBR)) ||
705 ((looking_for & MODE) == SBR && (thisnib != C_SBR)))
706 goto fail;
707 if (((looking_for & MODE) == CCR_EXR &&
708 (thisnib != C_CCR && thisnib != C_EXR)) ||
709 ((looking_for & MODE) == VBR_SBR &&
710 (thisnib != C_VBR && thisnib != C_SBR)) ||
711 ((looking_for & MODE) == MACREG &&
712 (thisnib != C_MACH && thisnib != C_MACL)))
713 goto fail;
714 if (((looking_for & MODE) == CC_EX_VB_SB &&
715 (thisnib != C_CCR && thisnib != C_EXR &&
716 thisnib != C_VBR && thisnib != C_SBR)))
717 goto fail;
c906108c 718
dc5c3759
MS
719 reg[opnum] = thisnib;
720 }
721 else if ((looking_for & MODE) == ABS)
722 {
723 /* Absolute addresses are unsigned. */
724 switch (looking_for & SIZE)
725 {
726 case L_8:
727 cst[opnum] = UEXTCHAR (data[len / 2]);
728 break;
729 case L_16:
730 case L_16U:
731 cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
732 break;
733 case L_32:
734 cst[opnum] =
735 (data[len / 2 + 0] << 24) +
736 (data[len / 2 + 1] << 16) +
737 (data[len / 2 + 2] << 8) +
738 (data[len / 2 + 3]);
739 break;
740 default:
741 printf ("decode: bad size ABS: %d\n",
742 (looking_for & SIZE));
743 goto end;
744 }
745 }
746 else if ((looking_for & MODE) == DISP ||
747 (looking_for & MODE) == PCREL ||
748 (looking_for & MODE) == INDEXB ||
749 (looking_for & MODE) == INDEXW ||
750 (looking_for & MODE) == INDEXL)
dc5c3759
MS
751 {
752 switch (looking_for & SIZE)
753 {
754 case L_2:
755 cst[opnum] = thisnib & 3;
dc5c3759
MS
756 break;
757 case L_8:
758 cst[opnum] = SEXTCHAR (data[len / 2]);
759 break;
760 case L_16:
761 cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
762 cst[opnum] = (short) cst[opnum]; /* Sign extend. */
763 break;
764 case L_16U:
765 cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
766 break;
767 case L_32:
768 cst[opnum] =
769 (data[len / 2 + 0] << 24) +
770 (data[len / 2 + 1] << 16) +
771 (data[len / 2 + 2] << 8) +
772 (data[len / 2 + 3]);
773 break;
774 default:
775 printf ("decode: bad size DISP/PCREL/INDEX: %d\n",
776 (looking_for & SIZE));
777 goto end;
778 }
779 }
780 else if ((looking_for & SIZE) == L_16 ||
781 (looking_for & SIZE) == L_16U)
782 {
783 cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
0f42aa71
MS
784 /* Immediates are always unsigned. */
785 if ((looking_for & SIZE) != L_16U &&
786 (looking_for & MODE) != IMM)
dc5c3759
MS
787 cst[opnum] = (short) cst[opnum]; /* Sign extend. */
788 }
789 else if (looking_for & ABSJMP)
790 {
791 switch (looking_for & SIZE) {
792 case L_24:
793 cst[opnum] = (data[1] << 16) | (data[2] << 8) | (data[3]);
794 break;
795 case L_32:
796 cst[opnum] =
797 (data[len / 2 + 0] << 24) +
798 (data[len / 2 + 1] << 16) +
799 (data[len / 2 + 2] << 8) +
800 (data[len / 2 + 3]);
801 break;
802 default:
803 printf ("decode: bad size ABSJMP: %d\n",
804 (looking_for & SIZE));
805 goto end;
806 }
807 }
808 else if ((looking_for & MODE) == MEMIND)
809 {
810 cst[opnum] = data[1];
811 }
9f70f8ec
MS
812 else if ((looking_for & MODE) == VECIND)
813 {
59768597
SA
814 if(h8300_normal_mode)
815 cst[opnum] = ((data[1] & 0x7f) + 0x80) * 2;
816 else
817 cst[opnum] = ((data[1] & 0x7f) + 0x80) * 4;
9f70f8ec
MS
818 cst[opnum] += h8_get_vbr (sd); /* Add vector base reg. */
819 }
dc5c3759
MS
820 else if ((looking_for & SIZE) == L_32)
821 {
822 int i = len / 2;
6147b1f6 823
dc5c3759
MS
824 cst[opnum] =
825 (data[i + 0] << 24) |
826 (data[i + 1] << 16) |
827 (data[i + 2] << 8) |
828 (data[i + 3]);
829 }
830 else if ((looking_for & SIZE) == L_24)
831 {
832 int i = len / 2;
6147b1f6 833
dc5c3759
MS
834 cst[opnum] =
835 (data[i + 0] << 16) |
836 (data[i + 1] << 8) |
837 (data[i + 2]);
838 }
839 else if (looking_for & DISPREG)
840 {
841 rdisp[opnum] = thisnib & 0x7;
842 }
843 else if ((looking_for & MODE) == KBIT)
844 {
845 switch (thisnib)
846 {
847 case 9:
848 cst[opnum] = 4;
849 break;
850 case 8:
851 cst[opnum] = 2;
852 break;
853 case 0:
854 cst[opnum] = 1;
855 break;
856 default:
857 goto fail;
858 }
859 }
860 else if ((looking_for & SIZE) == L_8)
861 {
862 if ((looking_for & MODE) == ABS)
863 {
864 /* Will be combined with contents of SBR_REGNUM
865 by fetch (). For all modes except h8sx, this
866 will always contain the value 0xFFFFFF00. */
867 cst[opnum] = data[len / 2] & 0xff;
868 }
869 else
870 {
871 cst[opnum] = data[len / 2] & 0xff;
872 }
873 }
9f70f8ec
MS
874 else if ((looking_for & SIZE) == L_2)
875 {
876 cst[opnum] = thisnib & 3;
877 }
dc5c3759
MS
878 else if ((looking_for & SIZE) == L_3 ||
879 (looking_for & SIZE) == L_3NZ)
880 {
881 cst[opnum] = thisnib & 7;
882 if (cst[opnum] == 0 && (looking_for & SIZE) == L_3NZ)
883 goto fail;
884 }
885 else if ((looking_for & SIZE) == L_4)
886 {
887 cst[opnum] = thisnib & 15;
888 }
889 else if ((looking_for & SIZE) == L_5)
890 {
891 cst[opnum] = data[len / 2] & 0x1f;
892 }
893 else if (looking_for == E)
894 {
895#ifdef ADEBUG
896 dst->op = q;
897#endif
898 /* Fill in the args. */
899 {
c4212d37 900 const op_type *args = q->args.nib;
dc5c3759
MS
901 int hadone = 0;
902 int nargs;
6147b1f6 903
dc5c3759
MS
904 for (nargs = 0;
905 nargs < 3 && *args != E;
906 nargs++)
907 {
908 int x = *args;
909 ea_type *p;
c906108c 910
dc5c3759
MS
911 opnum = ((x & OP3) ? 2 :
912 (x & DST) ? 1 : 0);
913 if (x & DST)
914 p = &dst->dst;
915 else if (x & OP3)
916 p = &dst->op3;
917 else
918 p = &dst->src;
c906108c 919
dc5c3759
MS
920 if ((x & MODE) == IMM ||
921 (x & MODE) == KBIT ||
922 (x & MODE) == DBIT)
923 {
924 /* Use the instruction to determine
925 the operand size. */
926 p->type = X (OP_IMM, OP_SIZE (q->how));
927 p->literal = cst[opnum];
928 }
929 else if ((x & MODE) == CONST_2 ||
930 (x & MODE) == CONST_4 ||
931 (x & MODE) == CONST_8 ||
932 (x & MODE) == CONST_16)
933 {
934 /* Use the instruction to determine
935 the operand size. */
936 p->type = X (OP_IMM, OP_SIZE (q->how));
937 switch (x & MODE) {
938 case CONST_2: p->literal = 2; break;
939 case CONST_4: p->literal = 4; break;
940 case CONST_8: p->literal = 8; break;
941 case CONST_16: p->literal = 16; break;
942 }
943 }
944 else if ((x & MODE) == REG)
945 {
946 p->type = X (OP_REG, bitfrom (x));
947 p->reg = reg[opnum];
948 }
949 else if ((x & MODE) == LOWREG)
950 {
951 p->type = X (OP_LOWREG, bitfrom (x));
952 p->reg = reg[opnum];
953 }
954 else if ((x & MODE) == PREINC)
955 {
956 /* Use the instruction to determine
957 the operand size. */
958 p->type = X (OP_PREINC, OP_SIZE (q->how));
959 p->reg = reg[opnum] & 0x7;
960 }
961 else if ((x & MODE) == POSTINC)
962 {
963 /* Use the instruction to determine
964 the operand size. */
965 p->type = X (OP_POSTINC, OP_SIZE (q->how));
966 p->reg = reg[opnum] & 0x7;
967 }
968 else if ((x & MODE) == PREDEC)
969 {
970 /* Use the instruction to determine
971 the operand size. */
972 p->type = X (OP_PREDEC, OP_SIZE (q->how));
973 p->reg = reg[opnum] & 0x7;
974 }
975 else if ((x & MODE) == POSTDEC)
976 {
977 /* Use the instruction to determine
978 the operand size. */
979 p->type = X (OP_POSTDEC, OP_SIZE (q->how));
980 p->reg = reg[opnum] & 0x7;
981 }
982 else if ((x & MODE) == IND)
983 {
984 /* Note: an indirect is transformed into
985 a displacement of zero.
986 */
987 /* Use the instruction to determine
988 the operand size. */
989 p->type = X (OP_DISP, OP_SIZE (q->how));
990 p->reg = reg[opnum] & 0x7;
991 p->literal = 0;
992 if (OP_KIND (q->how) == O_JSR ||
993 OP_KIND (q->how) == O_JMP)
b86015ea 994 if (lvalue (sd, p->type, p->reg, (unsigned int *)&p->type))
dc5c3759
MS
995 goto end;
996 }
997 else if ((x & MODE) == ABS)
998 {
999 /* Note: a 16 or 32 bit ABS is transformed into a
1000 displacement from pseudo-register ZERO_REGNUM,
1001 which is always zero. An 8 bit ABS becomes
1002 a displacement from SBR_REGNUM.
1003 */
1004 /* Use the instruction to determine
1005 the operand size. */
1006 p->type = X (OP_DISP, OP_SIZE (q->how));
1007 p->literal = cst[opnum];
1008
1009 /* 8-bit ABS is displacement from SBR.
1010 16 and 32-bit ABS are displacement from ZERO.
1011 (SBR will always be zero except for h8/sx)
1012 */
1013 if ((x & SIZE) == L_8)
1014 p->reg = SBR_REGNUM;
1015 else
1016 p->reg = ZERO_REGNUM;;
1017 }
9f70f8ec
MS
1018 else if ((x & MODE) == MEMIND ||
1019 (x & MODE) == VECIND)
dc5c3759
MS
1020 {
1021 /* Size doesn't matter. */
1022 p->type = X (OP_MEM, SB);
1023 p->literal = cst[opnum];
1024 if (OP_KIND (q->how) == O_JSR ||
1025 OP_KIND (q->how) == O_JMP)
b86015ea 1026 if (lvalue (sd, p->type, p->reg, (unsigned int *)&p->type))
dc5c3759
MS
1027 goto end;
1028 }
1029 else if ((x & MODE) == PCREL)
1030 {
1031 /* Size doesn't matter. */
1032 p->type = X (OP_PCREL, SB);
1033 p->literal = cst[opnum];
1034 }
1035 else if (x & ABSJMP)
1036 {
1037 p->type = X (OP_IMM, SP);
1038 p->literal = cst[opnum];
1039 }
f408565c 1040 else if ((x & MODE) == INDEXB)
dc5c3759 1041 {
f408565c
MS
1042 p->type = X (OP_INDEXB, OP_SIZE (q->how));
1043 p->literal = cst[opnum];
1044 p->reg = rdisp[opnum];
1045 }
1046 else if ((x & MODE) == INDEXW)
1047 {
1048 p->type = X (OP_INDEXW, OP_SIZE (q->how));
dc5c3759
MS
1049 p->literal = cst[opnum];
1050 p->reg = rdisp[opnum];
1051 }
f408565c
MS
1052 else if ((x & MODE) == INDEXL)
1053 {
1054 p->type = X (OP_INDEXL, OP_SIZE (q->how));
1055 p->literal = cst[opnum];
1056 p->reg = rdisp[opnum];
1057 }
1058 else if ((x & MODE) == DISP)
1059 {
1060 /* Yuck -- special for mova args. */
1061 if (strncmp (q->name, "mova", 4) == 0 &&
1062 (x & SIZE) == L_2)
1063 {
1064 /* Mova can have a DISP2 dest, with an
1065 INDEXB or INDEXW src. The multiplier
1066 for the displacement value is determined
1067 by the src operand, not by the insn. */
1068
1069 switch (OP_KIND (dst->src.type))
1070 {
1071 case OP_INDEXB:
1072 p->type = X (OP_DISP, SB);
1073 p->literal = cst[opnum];
1074 break;
1075 case OP_INDEXW:
1076 p->type = X (OP_DISP, SW);
1077 p->literal = cst[opnum] * 2;
1078 break;
1079 default:
1080 goto fail;
1081 }
1082 }
1083 else
1084 {
1085 p->type = X (OP_DISP, OP_SIZE (q->how));
1086 p->literal = cst[opnum];
1087 /* DISP2 is special. */
1088 if ((x & SIZE) == L_2)
1089 switch (OP_SIZE (q->how))
1090 {
1091 case SB: break;
1092 case SW: p->literal *= 2; break;
1093 case SL: p->literal *= 4; break;
1094 }
1095 }
1096 p->reg = rdisp[opnum];
1097 }
dc5c3759
MS
1098 else if (x & CTRL)
1099 {
1100 switch (reg[opnum])
1101 {
1102 case C_CCR:
1103 p->type = X (OP_CCR, SB);
1104 break;
1105 case C_EXR:
1106 p->type = X (OP_EXR, SB);
1107 break;
1108 case C_MACH:
1109 p->type = X (OP_MACH, SL);
1110 break;
1111 case C_MACL:
1112 p->type = X (OP_MACL, SL);
1113 break;
1114 case C_VBR:
1115 p->type = X (OP_VBR, SL);
1116 break;
1117 case C_SBR:
1118 p->type = X (OP_SBR, SL);
1119 break;
1120 }
1121 }
1122 else if ((x & MODE) == CCR)
1123 {
1124 p->type = OP_CCR;
1125 }
1126 else if ((x & MODE) == EXR)
1127 {
1128 p->type = OP_EXR;
1129 }
1130 else
9f70f8ec 1131 printf ("Hmmmm 0x%x...\n", x);
c906108c 1132
dc5c3759
MS
1133 args++;
1134 }
1135 }
c906108c 1136
dc5c3759
MS
1137 /* Unary operators: treat src and dst as equivalent. */
1138 if (dst->dst.type == -1)
1139 dst->dst = dst->src;
1140 if (dst->src.type == -1)
1141 dst->src = dst->dst;
1142
1143 dst->opcode = q->how;
1144 dst->cycles = q->time;
c906108c 1145
dc5c3759
MS
1146 /* And jsr's to these locations are turned into
1147 magic traps. */
fc974602 1148
dc5c3759
MS
1149 if (OP_KIND (dst->opcode) == O_JSR)
1150 {
1151 switch (dst->src.literal)
1152 {
1153 case 0xc5:
1154 dst->opcode = O (O_SYS_OPEN, SB);
1155 break;
1156 case 0xc6:
1157 dst->opcode = O (O_SYS_READ, SB);
1158 break;
1159 case 0xc7:
1160 dst->opcode = O (O_SYS_WRITE, SB);
1161 break;
1162 case 0xc8:
1163 dst->opcode = O (O_SYS_LSEEK, SB);
1164 break;
1165 case 0xc9:
1166 dst->opcode = O (O_SYS_CLOSE, SB);
1167 break;
1168 case 0xca:
1169 dst->opcode = O (O_SYS_STAT, SB);
1170 break;
1171 case 0xcb:
1172 dst->opcode = O (O_SYS_FSTAT, SB);
1173 break;
1174 case 0xcc:
1175 dst->opcode = O (O_SYS_CMDLINE, SB);
1176 break;
1177 }
1178 /* End of Processing for system calls. */
1179 }
1180
1181 dst->next_pc = addr + len / 2;
1182 return;
1183 }
1184 else
9f70f8ec 1185 printf ("Don't understand 0x%x \n", looking_for);
dc5c3759
MS
1186 }
1187
1188 len++;
1189 nib++;
1190 }
1191
1192 fail:
1193 ;
1194 }
1195 end:
1196 /* Fell off the end. */
1197 dst->opcode = O (O_ILL, SB);
1198}
1199
1200static void
1201compile (SIM_DESC sd, int pc)
1202{
1203 int idx;
1204
1205 /* Find the next cache entry to use. */
1206 idx = h8_get_cache_top (sd) + 1;
1207 h8_increment_compiles (sd);
1208 if (idx >= sd->sim_cache_size)
c906108c 1209 {
dc5c3759
MS
1210 idx = 1;
1211 }
1212 h8_set_cache_top (sd, idx);
c906108c 1213
dc5c3759
MS
1214 /* Throw away its old meaning. */
1215 h8_set_cache_idx (sd, sd->sim_cache[idx].oldpc, 0);
1216
1217 /* Set to new address. */
1218 sd->sim_cache[idx].oldpc = pc;
c906108c 1219
dc5c3759
MS
1220 /* Fill in instruction info. */
1221 decode (sd, pc, h8_get_memory_buf (sd) + pc, sd->sim_cache + idx);
c906108c 1222
dc5c3759
MS
1223 /* Point to new cache entry. */
1224 h8_set_cache_idx (sd, pc, idx);
1225}
c906108c
SS
1226
1227
dc5c3759
MS
1228static unsigned char *breg[32];
1229static unsigned short *wreg[16];
dc5c3759
MS
1230
1231#define GET_B_REG(X) *(breg[X])
1232#define SET_B_REG(X, Y) (*(breg[X])) = (Y)
1233#define GET_W_REG(X) *(wreg[X])
1234#define SET_W_REG(X, Y) (*(wreg[X])) = (Y)
1235#define GET_L_REG(X) h8_get_reg (sd, X)
1236#define SET_L_REG(X, Y) h8_set_reg (sd, X, Y)
1237
1238#define GET_MEMORY_L(X) \
1239 ((X) < memory_size \
1240 ? ((h8_get_memory (sd, (X)+0) << 24) | (h8_get_memory (sd, (X)+1) << 16) \
1241 | (h8_get_memory (sd, (X)+2) << 8) | (h8_get_memory (sd, (X)+3) << 0)) \
1242 : ((h8_get_eightbit (sd, ((X)+0) & 0xff) << 24) \
1243 | (h8_get_eightbit (sd, ((X)+1) & 0xff) << 16) \
1244 | (h8_get_eightbit (sd, ((X)+2) & 0xff) << 8) \
1245 | (h8_get_eightbit (sd, ((X)+3) & 0xff) << 0)))
1246
1247#define GET_MEMORY_W(X) \
1248 ((X) < memory_size \
1249 ? ((h8_get_memory (sd, (X)+0) << 8) \
1250 | (h8_get_memory (sd, (X)+1) << 0)) \
1251 : ((h8_get_eightbit (sd, ((X)+0) & 0xff) << 8) \
1252 | (h8_get_eightbit (sd, ((X)+1) & 0xff) << 0)))
1253
1254
1255#define GET_MEMORY_B(X) \
1256 ((X) < memory_size ? (h8_get_memory (sd, (X))) \
1257 : (h8_get_eightbit (sd, (X) & 0xff)))
1258
1259#define SET_MEMORY_L(X, Y) \
1260{ register unsigned char *_p; register int __y = (Y); \
1261 _p = ((X) < memory_size ? h8_get_memory_buf (sd) + (X) : \
1262 h8_get_eightbit_buf (sd) + ((X) & 0xff)); \
1263 _p[0] = __y >> 24; _p[1] = __y >> 16; \
1264 _p[2] = __y >> 8; _p[3] = __y >> 0; \
1265}
c906108c 1266
dc5c3759
MS
1267#define SET_MEMORY_W(X, Y) \
1268{ register unsigned char *_p; register int __y = (Y); \
1269 _p = ((X) < memory_size ? h8_get_memory_buf (sd) + (X) : \
1270 h8_get_eightbit_buf (sd) + ((X) & 0xff)); \
1271 _p[0] = __y >> 8; _p[1] = __y; \
1272}
c906108c 1273
dc5c3759
MS
1274#define SET_MEMORY_B(X, Y) \
1275 ((X) < memory_size ? (h8_set_memory (sd, (X), (Y))) \
1276 : (h8_set_eightbit (sd, (X) & 0xff, (Y))))
c906108c 1277
dc5c3759
MS
1278/* Simulate a memory fetch.
1279 Return 0 for success, -1 for failure.
1280*/
c906108c 1281
dc5c3759
MS
1282static int
1283fetch_1 (SIM_DESC sd, ea_type *arg, int *val, int twice)
1284{
4ca9d09e 1285 SIM_CPU *cpu = STATE_CPU (sd, 0);
dc5c3759
MS
1286 int rn = arg->reg;
1287 int abs = arg->literal;
1288 int r;
1289 int t;
1290
1291 if (val == NULL)
1292 return -1; /* Paranoia. */
1293
1294 switch (arg->type)
1295 {
1296 /* Indexed register plus displacement mode:
1297
1298 This new family of addressing modes are similar to OP_DISP
1299 (register plus displacement), with two differences:
1300 1) INDEXB uses only the least significant byte of the register,
1301 INDEXW uses only the least significant word, and
1302 INDEXL uses the entire register (just like OP_DISP).
1303 and
1304 2) The displacement value in abs is multiplied by two
1305 for SW-sized operations, and by four for SL-size.
1306
1307 This gives nine possible variations.
1308 */
1309
1310 case X (OP_INDEXB, SB):
1311 case X (OP_INDEXB, SW):
1312 case X (OP_INDEXB, SL):
1313 case X (OP_INDEXW, SB):
1314 case X (OP_INDEXW, SW):
1315 case X (OP_INDEXW, SL):
1316 case X (OP_INDEXL, SB):
1317 case X (OP_INDEXL, SW):
1318 case X (OP_INDEXL, SL):
1319 t = GET_L_REG (rn);
1320 switch (OP_KIND (arg->type)) {
1321 case OP_INDEXB: t &= 0xff; break;
1322 case OP_INDEXW: t &= 0xffff; break;
1323 case OP_INDEXL:
1324 default: break;
1325 }
1326 switch (OP_SIZE (arg->type)) {
1327 case SB:
1328 *val = GET_MEMORY_B ((t * 1 + abs) & h8_get_mask (sd));
1329 break;
1330 case SW:
1331 *val = GET_MEMORY_W ((t * 2 + abs) & h8_get_mask (sd));
1332 break;
1333 case SL:
1334 *val = GET_MEMORY_L ((t * 4 + abs) & h8_get_mask (sd));
1335 break;
1336 }
1337 break;
1338
1339 case X (OP_LOWREG, SB):
1340 *val = GET_L_REG (rn) & 0xff;
1341 break;
1342 case X (OP_LOWREG, SW):
1343 *val = GET_L_REG (rn) & 0xffff;
1344 break;
1345
1346 case X (OP_REG, SB): /* Register direct, byte. */
1347 *val = GET_B_REG (rn);
1348 break;
1349 case X (OP_REG, SW): /* Register direct, word. */
1350 *val = GET_W_REG (rn);
1351 break;
1352 case X (OP_REG, SL): /* Register direct, long. */
1353 *val = GET_L_REG (rn);
1354 break;
1355 case X (OP_IMM, SB): /* Immediate, byte. */
1356 case X (OP_IMM, SW): /* Immediate, word. */
1357 case X (OP_IMM, SL): /* Immediate, long. */
1358 *val = abs;
1359 break;
1360 case X (OP_POSTINC, SB): /* Register indirect w/post-incr: byte. */
1361 t = GET_L_REG (rn);
3a6c31f9 1362 r = GET_MEMORY_B (t & h8_get_mask (sd));
dc5c3759
MS
1363 if (!twice)
1364 t += 1;
dc5c3759
MS
1365 SET_L_REG (rn, t);
1366 *val = r;
1367 break;
1368 case X (OP_POSTINC, SW): /* Register indirect w/post-incr: word. */
1369 t = GET_L_REG (rn);
3a6c31f9 1370 r = GET_MEMORY_W (t & h8_get_mask (sd));
dc5c3759
MS
1371 if (!twice)
1372 t += 2;
dc5c3759
MS
1373 SET_L_REG (rn, t);
1374 *val = r;
1375 break;
1376 case X (OP_POSTINC, SL): /* Register indirect w/post-incr: long. */
1377 t = GET_L_REG (rn);
3a6c31f9 1378 r = GET_MEMORY_L (t & h8_get_mask (sd));
dc5c3759
MS
1379 if (!twice)
1380 t += 4;
dc5c3759
MS
1381 SET_L_REG (rn, t);
1382 *val = r;
1383 break;
1384
1385 case X (OP_POSTDEC, SB): /* Register indirect w/post-decr: byte. */
1386 t = GET_L_REG (rn);
3a6c31f9 1387 r = GET_MEMORY_B (t & h8_get_mask (sd));
dc5c3759
MS
1388 if (!twice)
1389 t -= 1;
dc5c3759
MS
1390 SET_L_REG (rn, t);
1391 *val = r;
1392 break;
1393 case X (OP_POSTDEC, SW): /* Register indirect w/post-decr: word. */
1394 t = GET_L_REG (rn);
3a6c31f9 1395 r = GET_MEMORY_W (t & h8_get_mask (sd));
dc5c3759
MS
1396 if (!twice)
1397 t -= 2;
dc5c3759
MS
1398 SET_L_REG (rn, t);
1399 *val = r;
1400 break;
1401 case X (OP_POSTDEC, SL): /* Register indirect w/post-decr: long. */
1402 t = GET_L_REG (rn);
3a6c31f9 1403 r = GET_MEMORY_L (t & h8_get_mask (sd));
dc5c3759
MS
1404 if (!twice)
1405 t -= 4;
dc5c3759
MS
1406 SET_L_REG (rn, t);
1407 *val = r;
1408 break;
1409
1410 case X (OP_PREDEC, SB): /* Register indirect w/pre-decr: byte. */
1411 t = GET_L_REG (rn) - 1;
dc5c3759 1412 SET_L_REG (rn, t);
3a6c31f9 1413 t &= h8_get_mask (sd);
dc5c3759
MS
1414 *val = GET_MEMORY_B (t);
1415 break;
1416
1417 case X (OP_PREDEC, SW): /* Register indirect w/pre-decr: word. */
1418 t = GET_L_REG (rn) - 2;
dc5c3759 1419 SET_L_REG (rn, t);
3a6c31f9 1420 t &= h8_get_mask (sd);
dc5c3759
MS
1421 *val = GET_MEMORY_W (t);
1422 break;
1423
1424 case X (OP_PREDEC, SL): /* Register indirect w/pre-decr: long. */
1425 t = GET_L_REG (rn) - 4;
dc5c3759 1426 SET_L_REG (rn, t);
3a6c31f9 1427 t &= h8_get_mask (sd);
dc5c3759
MS
1428 *val = GET_MEMORY_L (t);
1429 break;
1430
1431 case X (OP_PREINC, SB): /* Register indirect w/pre-incr: byte. */
1432 t = GET_L_REG (rn) + 1;
dc5c3759 1433 SET_L_REG (rn, t);
3a6c31f9 1434 t &= h8_get_mask (sd);
dc5c3759
MS
1435 *val = GET_MEMORY_B (t);
1436 break;
1437
1438 case X (OP_PREINC, SW): /* Register indirect w/pre-incr: long. */
1439 t = GET_L_REG (rn) + 2;
dc5c3759 1440 SET_L_REG (rn, t);
3a6c31f9 1441 t &= h8_get_mask (sd);
dc5c3759
MS
1442 *val = GET_MEMORY_W (t);
1443 break;
1444
1445 case X (OP_PREINC, SL): /* Register indirect w/pre-incr: long. */
1446 t = GET_L_REG (rn) + 4;
dc5c3759 1447 SET_L_REG (rn, t);
3a6c31f9 1448 t &= h8_get_mask (sd);
dc5c3759
MS
1449 *val = GET_MEMORY_L (t);
1450 break;
1451
1452 case X (OP_DISP, SB): /* Register indirect w/displacement: byte. */
1453 t = GET_L_REG (rn) + abs;
1454 t &= h8_get_mask (sd);
1455 *val = GET_MEMORY_B (t);
1456 break;
1457
1458 case X (OP_DISP, SW): /* Register indirect w/displacement: word. */
1459 t = GET_L_REG (rn) + abs;
1460 t &= h8_get_mask (sd);
1461 *val = GET_MEMORY_W (t);
1462 break;
1463
1464 case X (OP_DISP, SL): /* Register indirect w/displacement: long. */
1465 t = GET_L_REG (rn) + abs;
1466 t &= h8_get_mask (sd);
1467 *val =GET_MEMORY_L (t);
1468 break;
1469
1470 case X (OP_MEM, SL): /* Absolute memory address, long. */
1471 t = GET_MEMORY_L (abs);
1472 t &= h8_get_mask (sd);
1473 *val = t;
1474 break;
1475
1476 case X (OP_MEM, SW): /* Absolute memory address, word. */
1477 t = GET_MEMORY_W (abs);
1478 t &= h8_get_mask (sd);
1479 *val = t;
1480 break;
1481
1482 case X (OP_PCREL, SB): /* PC relative (for jump, branch etc). */
1483 case X (OP_PCREL, SW):
1484 case X (OP_PCREL, SL):
1485 case X (OP_PCREL, SN):
1486 *val = abs;
1487 break;
1488
1489 case X (OP_MEM, SB): /* Why isn't this implemented? */
1490 default:
4ca9d09e 1491 sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV);
dc5c3759
MS
1492 return -1;
1493 }
1494 return 0; /* Success. */
1495}
1496
1497/* Normal fetch. */
1498
1499static int
1500fetch (SIM_DESC sd, ea_type *arg, int *val)
1501{
1502 return fetch_1 (sd, arg, val, 0);
1503}
1504
1505/* Fetch which will be followed by a store to the same location.
1506 The difference being that we don't want to do a post-increment
1507 or post-decrement at this time: we'll do it when we store. */
1508
1509static int
1510fetch2 (SIM_DESC sd, ea_type *arg, int *val)
1511{
1512 return fetch_1 (sd, arg, val, 1);
1513}
1514
1515/* Simulate a memory store.
1516 Return 0 for success, -1 for failure.
1517*/
1518
1519static int
1520store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
1521{
4ca9d09e 1522 SIM_CPU *cpu = STATE_CPU (sd, 0);
dc5c3759
MS
1523 int rn = arg->reg;
1524 int abs = arg->literal;
1525 int t;
1526
1527 switch (arg->type)
1528 {
1529 /* Indexed register plus displacement mode:
1530
1531 This new family of addressing modes are similar to OP_DISP
1532 (register plus displacement), with two differences:
1533 1) INDEXB uses only the least significant byte of the register,
1534 INDEXW uses only the least significant word, and
1535 INDEXL uses the entire register (just like OP_DISP).
1536 and
1537 2) The displacement value in abs is multiplied by two
1538 for SW-sized operations, and by four for SL-size.
1539
1540 This gives nine possible variations.
1541 */
1542
1543 case X (OP_INDEXB, SB):
1544 case X (OP_INDEXB, SW):
1545 case X (OP_INDEXB, SL):
1546 case X (OP_INDEXW, SB):
1547 case X (OP_INDEXW, SW):
1548 case X (OP_INDEXW, SL):
1549 case X (OP_INDEXL, SB):
1550 case X (OP_INDEXL, SW):
1551 case X (OP_INDEXL, SL):
1552 t = GET_L_REG (rn);
1553 switch (OP_KIND (arg->type)) {
1554 case OP_INDEXB: t &= 0xff; break;
1555 case OP_INDEXW: t &= 0xffff; break;
1556 case OP_INDEXL:
1557 default: break;
1558 }
1559 switch (OP_SIZE (arg->type)) {
1560 case SB:
1561 SET_MEMORY_B ((t * 1 + abs) & h8_get_mask (sd), n);
1562 break;
1563 case SW:
1564 SET_MEMORY_W ((t * 2 + abs) & h8_get_mask (sd), n);
1565 break;
1566 case SL:
1567 SET_MEMORY_L ((t * 4 + abs) & h8_get_mask (sd), n);
1568 break;
1569 }
1570 break;
1571
1572 case X (OP_REG, SB): /* Register direct, byte. */
1573 SET_B_REG (rn, n);
1574 break;
1575 case X (OP_REG, SW): /* Register direct, word. */
1576 SET_W_REG (rn, n);
1577 break;
1578 case X (OP_REG, SL): /* Register direct, long. */
1579 SET_L_REG (rn, n);
1580 break;
1581
1582 case X (OP_PREDEC, SB): /* Register indirect w/pre-decr, byte. */
1583 t = GET_L_REG (rn);
1584 if (!twice)
1585 t -= 1;
dc5c3759 1586 SET_L_REG (rn, t);
3a6c31f9 1587 t &= h8_get_mask (sd);
dc5c3759
MS
1588 SET_MEMORY_B (t, n);
1589
1590 break;
1591 case X (OP_PREDEC, SW): /* Register indirect w/pre-decr, word. */
1592 t = GET_L_REG (rn);
1593 if (!twice)
1594 t -= 2;
dc5c3759 1595 SET_L_REG (rn, t);
3a6c31f9 1596 t &= h8_get_mask (sd);
dc5c3759
MS
1597 SET_MEMORY_W (t, n);
1598 break;
1599
1600 case X (OP_PREDEC, SL): /* Register indirect w/pre-decr, long. */
1601 t = GET_L_REG (rn);
1602 if (!twice)
1603 t -= 4;
dc5c3759 1604 SET_L_REG (rn, t);
3a6c31f9 1605 t &= h8_get_mask (sd);
dc5c3759
MS
1606 SET_MEMORY_L (t, n);
1607 break;
1608
1609 case X (OP_PREINC, SB): /* Register indirect w/pre-incr, byte. */
1610 t = GET_L_REG (rn);
1611 if (!twice)
1612 t += 1;
dc5c3759 1613 SET_L_REG (rn, t);
3a6c31f9 1614 t &= h8_get_mask (sd);
dc5c3759
MS
1615 SET_MEMORY_B (t, n);
1616
1617 break;
1618 case X (OP_PREINC, SW): /* Register indirect w/pre-incr, word. */
1619 t = GET_L_REG (rn);
1620 if (!twice)
1621 t += 2;
dc5c3759 1622 SET_L_REG (rn, t);
3a6c31f9 1623 t &= h8_get_mask (sd);
dc5c3759
MS
1624 SET_MEMORY_W (t, n);
1625 break;
1626
1627 case X (OP_PREINC, SL): /* Register indirect w/pre-incr, long. */
1628 t = GET_L_REG (rn);
1629 if (!twice)
1630 t += 4;
dc5c3759 1631 SET_L_REG (rn, t);
3a6c31f9 1632 t &= h8_get_mask (sd);
dc5c3759
MS
1633 SET_MEMORY_L (t, n);
1634 break;
1635
1636 case X (OP_POSTDEC, SB): /* Register indirect w/post-decr, byte. */
3a6c31f9 1637 t = GET_L_REG (rn);
dc5c3759 1638 SET_L_REG (rn, t - 1);
3a6c31f9
YS
1639 t &= h8_get_mask (sd);
1640 SET_MEMORY_B (t, n);
dc5c3759
MS
1641 break;
1642
1643 case X (OP_POSTDEC, SW): /* Register indirect w/post-decr, word. */
3a6c31f9 1644 t = GET_L_REG (rn);
dc5c3759 1645 SET_L_REG (rn, t - 2);
3a6c31f9
YS
1646 t &= h8_get_mask (sd);
1647 SET_MEMORY_W (t, n);
dc5c3759
MS
1648 break;
1649
1650 case X (OP_POSTDEC, SL): /* Register indirect w/post-decr, long. */
3a6c31f9 1651 t = GET_L_REG (rn);
dc5c3759 1652 SET_L_REG (rn, t - 4);
3a6c31f9
YS
1653 t &= h8_get_mask (sd);
1654 SET_MEMORY_L (t, n);
dc5c3759
MS
1655 break;
1656
1657 case X (OP_POSTINC, SB): /* Register indirect w/post-incr, byte. */
3a6c31f9 1658 t = GET_L_REG (rn);
dc5c3759 1659 SET_L_REG (rn, t + 1);
3a6c31f9
YS
1660 t &= h8_get_mask (sd);
1661 SET_MEMORY_B (t, n);
dc5c3759
MS
1662 break;
1663
1664 case X (OP_POSTINC, SW): /* Register indirect w/post-incr, word. */
3a6c31f9 1665 t = GET_L_REG (rn);
dc5c3759 1666 SET_L_REG (rn, t + 2);
3a6c31f9
YS
1667 t &= h8_get_mask (sd);
1668 SET_MEMORY_W (t, n);
dc5c3759
MS
1669 break;
1670
1671 case X (OP_POSTINC, SL): /* Register indirect w/post-incr, long. */
3a6c31f9 1672 t = GET_L_REG (rn);
dc5c3759 1673 SET_L_REG (rn, t + 4);
3a6c31f9
YS
1674 t &= h8_get_mask (sd);
1675 SET_MEMORY_L (t, n);
dc5c3759
MS
1676 break;
1677
1678 case X (OP_DISP, SB): /* Register indirect w/displacement, byte. */
1679 t = GET_L_REG (rn) + abs;
1680 t &= h8_get_mask (sd);
1681 SET_MEMORY_B (t, n);
1682 break;
1683
1684 case X (OP_DISP, SW): /* Register indirect w/displacement, word. */
1685 t = GET_L_REG (rn) + abs;
1686 t &= h8_get_mask (sd);
1687 SET_MEMORY_W (t, n);
1688 break;
1689
1690 case X (OP_DISP, SL): /* Register indirect w/displacement, long. */
1691 t = GET_L_REG (rn) + abs;
1692 t &= h8_get_mask (sd);
1693 SET_MEMORY_L (t, n);
1694 break;
1695
1696
1697 case X (OP_MEM, SB): /* Why isn't this implemented? */
1698 case X (OP_MEM, SW): /* Why isn't this implemented? */
1699 case X (OP_MEM, SL): /* Why isn't this implemented? */
1700 default:
4ca9d09e 1701 sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV);
dc5c3759
MS
1702 return -1;
1703 }
1704 return 0;
1705}
1706
1707/* Normal store. */
1708
1709static int
1710store (SIM_DESC sd, ea_type *arg, int n)
1711{
1712 return store_1 (sd, arg, n, 0);
1713}
1714
1715/* Store which follows a fetch from the same location.
1716 The difference being that we don't want to do a pre-increment
1717 or pre-decrement at this time: it was already done when we fetched. */
1718
1719static int
1720store2 (SIM_DESC sd, ea_type *arg, int n)
1721{
1722 return store_1 (sd, arg, n, 1);
1723}
1724
dc5c3759
MS
1725/* Flag to be set whenever a new SIM_DESC object is created. */
1726static int init_pointers_needed = 1;
1727
1728static void
1729init_pointers (SIM_DESC sd)
1730{
1731 if (init_pointers_needed)
1732 {
1733 int i;
1734
59768597 1735 if (h8300smode && !h8300_normal_mode)
dc5c3759 1736 memory_size = H8300S_MSIZE;
59768597 1737 else if (h8300hmode && !h8300_normal_mode)
dc5c3759
MS
1738 memory_size = H8300H_MSIZE;
1739 else
1740 memory_size = H8300_MSIZE;
1741 /* `msize' must be a power of two. */
1742 if ((memory_size & (memory_size - 1)) != 0)
1743 {
c1fc4b4d
MF
1744 sim_io_printf
1745 (sd,
dc5c3759
MS
1746 "init_pointers: bad memory size %d, defaulting to %d.\n",
1747 memory_size, memory_size = H8300S_MSIZE);
1748 }
1749
1750 if (h8_get_memory_buf (sd))
1751 free (h8_get_memory_buf (sd));
1752 if (h8_get_cache_idx_buf (sd))
1753 free (h8_get_cache_idx_buf (sd));
1754 if (h8_get_eightbit_buf (sd))
1755 free (h8_get_eightbit_buf (sd));
1756
1757 h8_set_memory_buf (sd, (unsigned char *)
1758 calloc (sizeof (char), memory_size));
1759 h8_set_cache_idx_buf (sd, (unsigned short *)
1760 calloc (sizeof (short), memory_size));
1761 sd->memory_size = memory_size;
1762 h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256));
1763
1764 h8_set_mask (sd, memory_size - 1);
1765
1766 memset (h8_get_reg_buf (sd), 0, sizeof (((STATE_CPU (sd, 0))->regs)));
1767
1768 for (i = 0; i < 8; i++)
1769 {
1770 /* FIXME: rewrite using local buffer. */
1771 unsigned char *p = (unsigned char *) (h8_get_reg_buf (sd) + i);
1772 unsigned char *e = (unsigned char *) (h8_get_reg_buf (sd) + i + 1);
1773 unsigned short *q = (unsigned short *) (h8_get_reg_buf (sd) + i);
1774 unsigned short *u = (unsigned short *) (h8_get_reg_buf (sd) + i + 1);
1775 h8_set_reg (sd, i, 0x00112233);
1776
1777 while (p < e)
1778 {
1779 if (*p == 0x22)
1780 breg[i] = p;
1781 if (*p == 0x33)
1782 breg[i + 8] = p;
1783 if (*p == 0x11)
1784 breg[i + 16] = p;
1785 if (*p == 0x00)
1786 breg[i + 24] = p;
1787 p++;
1788 }
1789
1790 wreg[i] = wreg[i + 8] = 0;
1791 while (q < u)
1792 {
1793 if (*q == 0x2233)
1794 {
1795 wreg[i] = q;
1796 }
1797 if (*q == 0x0011)
1798 {
1799 wreg[i + 8] = q;
1800 }
1801 q++;
1802 }
1803
1804 if (wreg[i] == 0 || wreg[i + 8] == 0)
c1fc4b4d 1805 sim_io_printf (sd, "init_pointers: internal error.\n");
dc5c3759
MS
1806
1807 h8_set_reg (sd, i, 0);
dc5c3759
MS
1808 }
1809
dc5c3759
MS
1810 init_pointers_needed = 0;
1811
1812 /* Initialize the seg registers. */
1813 if (!sd->sim_cache)
1814 set_simcache_size (sd, CSIZE);
1815 }
1816}
1817
dc5c3759
MS
1818#define OBITOP(name, f, s, op) \
1819case O (name, SB): \
1820{ \
1821 int m, tmp; \
1822 \
1823 if (f) \
1824 if (fetch (sd, &code->dst, &ea)) \
1825 goto end; \
1826 if (fetch (sd, &code->src, &tmp)) \
1827 goto end; \
b86015ea 1828 m = 1 << (tmp & 7); \
dc5c3759
MS
1829 op; \
1830 if (s) \
1831 if (store (sd, &code->dst,ea)) \
1832 goto end; \
1833 goto next; \
1834}
1835
4ca9d09e
MF
1836static void
1837step_once (SIM_DESC sd, SIM_CPU *cpu)
dc5c3759 1838{
dc5c3759
MS
1839 int cycles = 0;
1840 int insts = 0;
1841 int tick_start = get_now ();
dc5c3759
MS
1842 int res;
1843 int tmp;
1844 int rd;
1845 int ea;
1846 int bit;
1847 int pc;
1848 int c, nz, v, n, u, h, ui, intMaskBit;
1849 int trace, intMask;
1850 int oldmask;
c1fc4b4d 1851 host_callback *sim_callback = STATE_CALLBACK (sd);
dc5c3759
MS
1852
1853 init_pointers (sd);
1854
dc5c3759
MS
1855 pc = h8_get_pc (sd);
1856
1857 /* The PC should never be odd. */
1858 if (pc & 0x1)
1859 {
4ca9d09e 1860 sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGBUS);
dc5c3759
MS
1861 return;
1862 }
1863
1864 /* Get Status Register (flags). */
9f70f8ec 1865 GETSR (sd);
dc5c3759
MS
1866
1867 if (h8300smode) /* Get exr. */
1868 {
1869 trace = (h8_get_exr (sd) >> 7) & 1;
1870 intMask = h8_get_exr (sd) & 7;
1871 }
1872
1873 oldmask = h8_get_mask (sd);
59768597 1874 if (!h8300hmode || h8300_normal_mode)
dc5c3759
MS
1875 h8_set_mask (sd, 0xffff);
1876 do
1877 {
1878 unsigned short cidx;
1879 decoded_inst *code;
1880
1881 top:
1882 cidx = h8_get_cache_idx (sd, pc);
1883 if (cidx == (unsigned short) -1 ||
1884 cidx >= sd->sim_cache_size)
1885 goto illegal;
1886
1887 code = sd->sim_cache + cidx;
1888
1889#if ADEBUG
1890 if (debug)
1891 {
1892 printf ("%x %d %s\n", pc, code->opcode,
1893 code->op ? code->op->name : "**");
1894 }
1895 h8_increment_stats (sd, code->opcode);
1896#endif
1897
1898 if (code->opcode)
1899 {
1900 cycles += code->cycles;
1901 insts++;
1902 }
1903
1904 switch (code->opcode)
1905 {
1906 case 0:
1907 /*
1908 * This opcode is a fake for when we get to an
1909 * instruction which hasnt been compiled
1910 */
1911 compile (sd, pc);
1912 goto top;
1913 break;
1914
1915 case O (O_MOVAB, SL):
1916 case O (O_MOVAW, SL):
1917 case O (O_MOVAL, SL):
1918 /* 1) Evaluate 2nd argument (dst).
1919 2) Mask / zero extend according to whether 1st argument (src)
1920 is INDEXB, INDEXW, or INDEXL.
1921 3) Left-shift the result by 0, 1 or 2, according to size of mova
1922 (mova/b, mova/w, mova/l).
1923 4) Add literal value of 1st argument (src).
1924 5) Store result in 3rd argument (op3).
f408565c
MS
1925 */
1926
1927 /* Alas, since this is the only instruction with 3 arguments,
1928 decode doesn't handle them very well. Some fix-up is required.
1929
1930 a) The size of dst is determined by whether src is
1931 INDEXB or INDEXW. */
dc5c3759 1932
f408565c
MS
1933 if (OP_KIND (code->src.type) == OP_INDEXB)
1934 code->dst.type = X (OP_KIND (code->dst.type), SB);
1935 else if (OP_KIND (code->src.type) == OP_INDEXW)
1936 code->dst.type = X (OP_KIND (code->dst.type), SW);
1937
1938 /* b) If op3 == null, then this is the short form of the insn.
1939 Dst is the dispreg of src, and op3 is the 32-bit form
1940 of the same register.
dc5c3759 1941 */
f408565c
MS
1942
1943 if (code->op3.type == 0)
1944 {
1945 /* Short form: src == INDEXB/INDEXW, dst == op3 == 0.
1946 We get to compose dst and op3 as follows:
1947
1948 op3 is a 32-bit register, ID == src.reg.
1949 dst is the same register, but 8 or 16 bits
1950 depending on whether src is INDEXB or INDEXW.
1951 */
1952
1953 code->op3.type = X (OP_REG, SL);
1954 code->op3.reg = code->src.reg;
1955 code->op3.literal = 0;
1956
1957 if (OP_KIND (code->src.type) == OP_INDEXB)
e073c474
AO
1958 {
1959 code->dst.type = X (OP_REG, SB);
1960 code->dst.reg = code->op3.reg + 8;
1961 }
f408565c
MS
1962 else
1963 code->dst.type = X (OP_REG, SW);
1964 }
1965
dc5c3759
MS
1966 if (fetch (sd, &code->dst, &ea))
1967 goto end;
1968
1969 switch (OP_KIND (code->src.type)) {
1970 case OP_INDEXB: ea = ea & 0xff; break;
1971 case OP_INDEXW: ea = ea & 0xffff; break;
1972 case OP_INDEXL: break;
1973 default: goto illegal;
1974 }
1975
1976 switch (code->opcode) {
1977 case O (O_MOVAB, SL): break;
1978 case O (O_MOVAW, SL): ea = ea << 1; break;
1979 case O (O_MOVAL, SL): ea = ea << 2; break;
1980 default: goto illegal;
1981 }
1982
1983 ea = ea + code->src.literal;
1984
1985 if (store (sd, &code->op3, ea))
1986 goto end;
1987
1988 goto next;
1989
1990 case O (O_SUBX, SB): /* subx, extended sub */
1991 if (fetch2 (sd, &code->dst, &rd))
1992 goto end;
1993 if (fetch (sd, &code->src, &ea))
1994 goto end;
1995 ea = -(ea + C);
1996 res = rd + ea;
1997 goto alu8;
1998
1999 case O (O_SUBX, SW): /* subx, extended sub */
2000 if (fetch2 (sd, &code->dst, &rd))
2001 goto end;
2002 if (fetch (sd, &code->src, &ea))
2003 goto end;
2004 ea = -(ea + C);
2005 res = rd + ea;
2006 goto alu16;
2007
2008 case O (O_SUBX, SL): /* subx, extended sub */
2009 if (fetch2 (sd, &code->dst, &rd))
2010 goto end;
2011 if (fetch (sd, &code->src, &ea))
2012 goto end;
2013 ea = -(ea + C);
2014 res = rd + ea;
2015 goto alu32;
2016
2017 case O (O_ADDX, SB): /* addx, extended add */
2018 if (fetch2 (sd, &code->dst, &rd))
2019 goto end;
2020 if (fetch (sd, &code->src, &ea))
2021 goto end;
2022 ea = ea + C;
2023 res = rd + ea;
2024 goto alu8;
2025
2026 case O (O_ADDX, SW): /* addx, extended add */
2027 if (fetch2 (sd, &code->dst, &rd))
2028 goto end;
2029 if (fetch (sd, &code->src, &ea))
2030 goto end;
2031 ea = ea + C;
2032 res = rd + ea;
2033 goto alu16;
2034
2035 case O (O_ADDX, SL): /* addx, extended add */
2036 if (fetch2 (sd, &code->dst, &rd))
2037 goto end;
2038 if (fetch (sd, &code->src, &ea))
2039 goto end;
2040 ea = ea + C;
2041 res = rd + ea;
2042 goto alu32;
2043
2044 case O (O_SUB, SB): /* sub.b */
2045 /* Fetch rd and ea. */
2046 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2047 goto end;
2048 ea = -ea;
2049 res = rd + ea;
2050 goto alu8;
2051
2052 case O (O_SUB, SW): /* sub.w */
2053 /* Fetch rd and ea. */
2054 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2055 goto end;
2056 ea = -ea;
2057 res = rd + ea;
2058 goto alu16;
2059
2060 case O (O_SUB, SL): /* sub.l */
2061 /* Fetch rd and ea. */
2062 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2063 goto end;
2064 ea = -ea;
2065 res = rd + ea;
2066 goto alu32;
2067
2068 case O (O_NEG, SB): /* neg.b */
2069 /* Fetch ea. */
2070 if (fetch2 (sd, &code->src, &ea))
2071 goto end;
2072 ea = -ea;
2073 rd = 0;
2074 res = rd + ea;
2075 goto alu8;
2076
2077 case O (O_NEG, SW): /* neg.w */
2078 /* Fetch ea. */
2079 if (fetch2 (sd, &code->src, &ea))
2080 goto end;
2081 ea = -ea;
2082 rd = 0;
2083 res = rd + ea;
2084 goto alu16;
2085
2086 case O (O_NEG, SL): /* neg.l */
2087 /* Fetch ea. */
2088 if (fetch2 (sd, &code->src, &ea))
2089 goto end;
2090 ea = -ea;
2091 rd = 0;
2092 res = rd + ea;
2093 goto alu32;
2094
2095 case O (O_ADD, SB): /* add.b */
2096 if (fetch2 (sd, &code->dst, &rd))
2097 goto end;
2098 if (fetch (sd, &code->src, &ea))
2099 goto end;
2100 res = rd + ea;
2101 goto alu8;
2102
2103 case O (O_ADD, SW): /* add.w */
2104 if (fetch2 (sd, &code->dst, &rd))
2105 goto end;
2106 if (fetch (sd, &code->src, &ea))
2107 goto end;
2108 res = rd + ea;
2109 goto alu16;
2110
2111 case O (O_ADD, SL): /* add.l */
2112 if (fetch2 (sd, &code->dst, &rd))
2113 goto end;
2114 if (fetch (sd, &code->src, &ea))
2115 goto end;
2116 res = rd + ea;
2117 goto alu32;
2118
2119 case O (O_AND, SB): /* and.b */
2120 /* Fetch rd and ea. */
2121 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2122 goto end;
2123 res = rd & ea;
2124 goto log8;
2125
2126 case O (O_AND, SW): /* and.w */
2127 /* Fetch rd and ea. */
2128 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2129 goto end;
2130 res = rd & ea;
2131 goto log16;
2132
2133 case O (O_AND, SL): /* and.l */
2134 /* Fetch rd and ea. */
2135 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2136 goto end;
2137 res = rd & ea;
2138 goto log32;
2139
2140 case O (O_OR, SB): /* or.b */
2141 /* Fetch rd and ea. */
2142 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2143 goto end;
2144 res = rd | ea;
2145 goto log8;
2146
2147 case O (O_OR, SW): /* or.w */
2148 /* Fetch rd and ea. */
2149 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2150 goto end;
2151 res = rd | ea;
2152 goto log16;
2153
2154 case O (O_OR, SL): /* or.l */
2155 /* Fetch rd and ea. */
2156 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2157 goto end;
2158 res = rd | ea;
2159 goto log32;
2160
2161 case O (O_XOR, SB): /* xor.b */
2162 /* Fetch rd and ea. */
2163 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2164 goto end;
2165 res = rd ^ ea;
2166 goto log8;
2167
2168 case O (O_XOR, SW): /* xor.w */
2169 /* Fetch rd and ea. */
2170 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2171 goto end;
2172 res = rd ^ ea;
2173 goto log16;
2174
2175 case O (O_XOR, SL): /* xor.l */
2176 /* Fetch rd and ea. */
2177 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2178 goto end;
2179 res = rd ^ ea;
2180 goto log32;
2181
2182 case O (O_MOV, SB):
2183 if (fetch (sd, &code->src, &res))
2184 goto end;
2185 if (store (sd, &code->dst, res))
2186 goto end;
2187 goto just_flags_log8;
2188 case O (O_MOV, SW):
2189 if (fetch (sd, &code->src, &res))
2190 goto end;
2191 if (store (sd, &code->dst, res))
2192 goto end;
2193 goto just_flags_log16;
2194 case O (O_MOV, SL):
2195 if (fetch (sd, &code->src, &res))
2196 goto end;
2197 if (store (sd, &code->dst, res))
2198 goto end;
2199 goto just_flags_log32;
2200
9f70f8ec 2201 case O (O_MOVMD, SB): /* movmd.b */
dc5c3759
MS
2202 ea = GET_W_REG (4);
2203 if (ea == 0)
2204 ea = 0x10000;
2205
2206 while (ea--)
2207 {
2208 rd = GET_MEMORY_B (GET_L_REG (5));
2209 SET_MEMORY_B (GET_L_REG (6), rd);
2210 SET_L_REG (5, GET_L_REG (5) + 1);
2211 SET_L_REG (6, GET_L_REG (6) + 1);
2212 SET_W_REG (4, ea);
2213 }
2214 goto next;
2215
9f70f8ec 2216 case O (O_MOVMD, SW): /* movmd.w */
dc5c3759
MS
2217 ea = GET_W_REG (4);
2218 if (ea == 0)
2219 ea = 0x10000;
2220
2221 while (ea--)
2222 {
2223 rd = GET_MEMORY_W (GET_L_REG (5));
2224 SET_MEMORY_W (GET_L_REG (6), rd);
2225 SET_L_REG (5, GET_L_REG (5) + 2);
2226 SET_L_REG (6, GET_L_REG (6) + 2);
2227 SET_W_REG (4, ea);
2228 }
2229 goto next;
2230
9f70f8ec 2231 case O (O_MOVMD, SL): /* movmd.l */
dc5c3759
MS
2232 ea = GET_W_REG (4);
2233 if (ea == 0)
2234 ea = 0x10000;
2235
2236 while (ea--)
2237 {
2238 rd = GET_MEMORY_L (GET_L_REG (5));
2239 SET_MEMORY_L (GET_L_REG (6), rd);
2240 SET_L_REG (5, GET_L_REG (5) + 4);
2241 SET_L_REG (6, GET_L_REG (6) + 4);
2242 SET_W_REG (4, ea);
2243 }
2244 goto next;
2245
2246 case O (O_MOVSD, SB): /* movsd.b */
2247 /* This instruction implements strncpy, with a conditional branch.
2248 r4 contains n, r5 contains src, and r6 contains dst.
2249 The 16-bit displacement operand is added to the pc
2250 if and only if the end of string is reached before
2251 n bytes are transferred. */
2252
2253 ea = GET_L_REG (4) & 0xffff;
2254 if (ea == 0)
2255 ea = 0x10000;
2256
2257 while (ea--)
2258 {
2259 rd = GET_MEMORY_B (GET_L_REG (5));
2260 SET_MEMORY_B (GET_L_REG (6), rd);
2261 SET_L_REG (5, GET_L_REG (5) + 1);
2262 SET_L_REG (6, GET_L_REG (6) + 1);
2263 SET_W_REG (4, ea);
2264 if (rd == 0)
2265 goto condtrue;
2266 }
2267 goto next;
2268
2269 case O (O_EEPMOV, SB): /* eepmov.b */
2270 case O (O_EEPMOV, SW): /* eepmov.w */
2271 if (h8300hmode || h8300smode)
2272 {
2273 register unsigned char *_src, *_dst;
2274 unsigned int count = ((code->opcode == O (O_EEPMOV, SW))
2275 ? h8_get_reg (sd, R4_REGNUM) & 0xffff
2276 : h8_get_reg (sd, R4_REGNUM) & 0xff);
2277
2278 _src = (h8_get_reg (sd, R5_REGNUM) < memory_size
2279 ? h8_get_memory_buf (sd) + h8_get_reg (sd, R5_REGNUM)
2280 : h8_get_eightbit_buf (sd) +
2281 (h8_get_reg (sd, R5_REGNUM) & 0xff));
2282 if ((_src + count) >= (h8_get_memory_buf (sd) + memory_size))
2283 {
2284 if ((_src + count) >= (h8_get_eightbit_buf (sd) + 0x100))
2285 goto illegal;
2286 }
2287 _dst = (h8_get_reg (sd, R6_REGNUM) < memory_size
2288 ? h8_get_memory_buf (sd) + h8_get_reg (sd, R6_REGNUM)
2289 : h8_get_eightbit_buf (sd) +
2290 (h8_get_reg (sd, R6_REGNUM) & 0xff));
2291
2292 if ((_dst + count) >= (h8_get_memory_buf (sd) + memory_size))
2293 {
2294 if ((_dst + count) >= (h8_get_eightbit_buf (sd) + 0x100))
2295 goto illegal;
2296 }
2297 memcpy (_dst, _src, count);
2298
2299 h8_set_reg (sd, R5_REGNUM, h8_get_reg (sd, R5_REGNUM) + count);
2300 h8_set_reg (sd, R6_REGNUM, h8_get_reg (sd, R6_REGNUM) + count);
2301 h8_set_reg (sd, R4_REGNUM, h8_get_reg (sd, R4_REGNUM) &
2302 ((code->opcode == O (O_EEPMOV, SW))
2303 ? (~0xffff) : (~0xff)));
2304 cycles += 2 * count;
2305 goto next;
2306 }
2307 goto illegal;
2308
2309 case O (O_ADDS, SL): /* adds (.l) */
2310 /* FIXME fetch.
2311 * This insn only uses register operands, but still
2312 * it would be cleaner to use fetch and store... */
2313 SET_L_REG (code->dst.reg,
2314 GET_L_REG (code->dst.reg)
2315 + code->src.literal);
2316
2317 goto next;
2318
2319 case O (O_SUBS, SL): /* subs (.l) */
2320 /* FIXME fetch.
2321 * This insn only uses register operands, but still
2322 * it would be cleaner to use fetch and store... */
2323 SET_L_REG (code->dst.reg,
2324 GET_L_REG (code->dst.reg)
2325 - code->src.literal);
2326 goto next;
2327
2328 case O (O_CMP, SB): /* cmp.b */
2329 if (fetch (sd, &code->dst, &rd))
2330 goto end;
2331 if (fetch (sd, &code->src, &ea))
2332 goto end;
2333 ea = -ea;
2334 res = rd + ea;
2335 goto just_flags_alu8;
2336
2337 case O (O_CMP, SW): /* cmp.w */
2338 if (fetch (sd, &code->dst, &rd))
2339 goto end;
2340 if (fetch (sd, &code->src, &ea))
2341 goto end;
2342 ea = -ea;
2343 res = rd + ea;
2344 goto just_flags_alu16;
2345
2346 case O (O_CMP, SL): /* cmp.l */
2347 if (fetch (sd, &code->dst, &rd))
2348 goto end;
2349 if (fetch (sd, &code->src, &ea))
2350 goto end;
2351 ea = -ea;
2352 res = rd + ea;
2353 goto just_flags_alu32;
2354
2355 case O (O_DEC, SB): /* dec.b */
2356 /* FIXME fetch.
2357 * This insn only uses register operands, but still
2358 * it would be cleaner to use fetch and store... */
2359 rd = GET_B_REG (code->src.reg);
2360 ea = -1;
2361 res = rd + ea;
2362 SET_B_REG (code->src.reg, res);
2363 goto just_flags_inc8;
2364
2365 case O (O_DEC, SW): /* dec.w */
2366 /* FIXME fetch.
2367 * This insn only uses register operands, but still
2368 * it would be cleaner to use fetch and store... */
2369 rd = GET_W_REG (code->dst.reg);
2370 ea = -code->src.literal;
2371 res = rd + ea;
2372 SET_W_REG (code->dst.reg, res);
2373 goto just_flags_inc16;
2374
2375 case O (O_DEC, SL): /* dec.l */
2376 /* FIXME fetch.
2377 * This insn only uses register operands, but still
2378 * it would be cleaner to use fetch and store... */
2379 rd = GET_L_REG (code->dst.reg);
2380 ea = -code->src.literal;
2381 res = rd + ea;
2382 SET_L_REG (code->dst.reg, res);
2383 goto just_flags_inc32;
2384
2385 case O (O_INC, SB): /* inc.b */
2386 /* FIXME fetch.
2387 * This insn only uses register operands, but still
2388 * it would be cleaner to use fetch and store... */
2389 rd = GET_B_REG (code->src.reg);
2390 ea = 1;
2391 res = rd + ea;
2392 SET_B_REG (code->src.reg, res);
2393 goto just_flags_inc8;
2394
2395 case O (O_INC, SW): /* inc.w */
2396 /* FIXME fetch.
2397 * This insn only uses register operands, but still
2398 * it would be cleaner to use fetch and store... */
2399 rd = GET_W_REG (code->dst.reg);
2400 ea = code->src.literal;
2401 res = rd + ea;
2402 SET_W_REG (code->dst.reg, res);
2403 goto just_flags_inc16;
2404
2405 case O (O_INC, SL): /* inc.l */
2406 /* FIXME fetch.
2407 * This insn only uses register operands, but still
2408 * it would be cleaner to use fetch and store... */
2409 rd = GET_L_REG (code->dst.reg);
2410 ea = code->src.literal;
2411 res = rd + ea;
2412 SET_L_REG (code->dst.reg, res);
2413 goto just_flags_inc32;
2414
2415 case O (O_LDC, SB): /* ldc.b */
2416 if (fetch (sd, &code->src, &res))
2417 goto end;
2418 goto setc;
2419
2420 case O (O_LDC, SW): /* ldc.w */
2421 if (fetch (sd, &code->src, &res))
2422 goto end;
2423
2424 /* Word operand, value from MSB, must be shifted. */
2425 res >>= 8;
2426 goto setc;
2427
2428 case O (O_LDC, SL): /* ldc.l */
2429 if (fetch (sd, &code->src, &res))
2430 goto end;
2431 switch (code->dst.type) {
2432 case X (OP_SBR, SL):
2433 h8_set_sbr (sd, res);
2434 break;
2435 case X (OP_VBR, SL):
2436 h8_set_vbr (sd, res);
2437 break;
2438 default:
2439 goto illegal;
2440 }
2441 goto next;
2442
2443 case O (O_STC, SW): /* stc.w */
2444 case O (O_STC, SB): /* stc.b */
2445 if (code->src.type == X (OP_CCR, SB))
2446 {
2447 BUILDSR (sd);
2448 res = h8_get_ccr (sd);
2449 }
2450 else if (code->src.type == X (OP_EXR, SB) && h8300smode)
2451 {
2452 if (h8300smode)
2453 h8_set_exr (sd, (trace << 7) | intMask);
2454 res = h8_get_exr (sd);
2455 }
2456 else
2457 goto illegal;
2458
2459 /* Word operand, value to MSB, must be shifted. */
2460 if (code->opcode == X (O_STC, SW))
2461 res <<= 8;
2462 if (store (sd, &code->dst, res))
2463 goto end;
2464 goto next;
2465 case O (O_STC, SL): /* stc.l */
2466 switch (code->src.type) {
2467 case X (OP_SBR, SL):
2468 res = h8_get_sbr (sd);
2469 break;
2470 case X (OP_VBR, SL):
2471 res = h8_get_vbr (sd);
2472 break;
2473 default:
2474 goto illegal;
2475 }
2476 if (store (sd, &code->dst, res))
2477 goto end;
2478 goto next;
2479
2480 case O (O_ANDC, SB): /* andc.b */
2481 if (code->dst.type == X (OP_CCR, SB))
2482 {
2483 BUILDSR (sd);
2484 rd = h8_get_ccr (sd);
2485 }
2486 else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
2487 {
2488 if (h8300smode)
2489 h8_set_exr (sd, (trace << 7) | intMask);
d6fd015d 2490 rd = h8_get_exr (sd);
dc5c3759
MS
2491 }
2492 else
2493 goto illegal;
2494 ea = code->src.literal;
2495 res = rd & ea;
2496 goto setc;
2497
2498 case O (O_ORC, SB): /* orc.b */
2499 if (code->dst.type == X (OP_CCR, SB))
2500 {
2501 BUILDSR (sd);
2502 rd = h8_get_ccr (sd);
2503 }
2504 else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
2505 {
2506 if (h8300smode)
2507 h8_set_exr (sd, (trace << 7) | intMask);
2508 rd = h8_get_exr (sd);
2509 }
2510 else
2511 goto illegal;
2512 ea = code->src.literal;
2513 res = rd | ea;
2514 goto setc;
2515
2516 case O (O_XORC, SB): /* xorc.b */
2517 if (code->dst.type == X (OP_CCR, SB))
2518 {
2519 BUILDSR (sd);
2520 rd = h8_get_ccr (sd);
2521 }
2522 else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
2523 {
2524 if (h8300smode)
2525 h8_set_exr (sd, (trace << 7) | intMask);
2526 rd = h8_get_exr (sd);
2527 }
2528 else
2529 goto illegal;
2530 ea = code->src.literal;
2531 res = rd ^ ea;
2532 goto setc;
2533
2534 case O (O_BRAS, SB): /* bra/s */
2535 /* This is basically an ordinary branch, with a delay slot. */
2536 if (fetch (sd, &code->src, &res))
2537 goto end;
2538
2539 if ((res & 1) == 0)
2540 goto illegal;
2541
2542 res -= 1;
2543
2544 /* Execution continues at next instruction, but
2545 delayed_branch is set up for next cycle. */
2546 h8_set_delayed_branch (sd, code->next_pc + res);
2547 pc = code->next_pc;
2548 goto end;
2549
2550 case O (O_BRAB, SB): /* bra rd.b */
2551 case O (O_BRAW, SW): /* bra rd.w */
2552 case O (O_BRAL, SL): /* bra erd.l */
2553 if (fetch (sd, &code->src, &rd))
2554 goto end;
2555 switch (OP_SIZE (code->opcode)) {
2556 case SB: rd &= 0xff; break;
2557 case SW: rd &= 0xffff; break;
2558 case SL: rd &= 0xffffffff; break;
2559 }
2560 pc = code->next_pc + rd;
2561 goto end;
2562
2563 case O (O_BRABC, SB): /* bra/bc, branch if bit clear */
2564 case O (O_BRABS, SB): /* bra/bs, branch if bit set */
2565 case O (O_BSRBC, SB): /* bsr/bc, call if bit clear */
2566 case O (O_BSRBS, SB): /* bsr/bs, call if bit set */
2567 if (fetch (sd, &code->dst, &rd) ||
2568 fetch (sd, &code->src, &bit))
2569 goto end;
2570
2571 if (code->opcode == O (O_BRABC, SB) || /* branch if clear */
2572 code->opcode == O (O_BSRBC, SB)) /* call if clear */
2573 {
2574 if ((rd & (1 << bit))) /* no branch */
2575 goto next;
2576 }
2577 else /* branch/call if set */
2578 {
2579 if (!(rd & (1 << bit))) /* no branch */
2580 goto next;
2581 }
2582
2583 if (fetch (sd, &code->op3, &res)) /* branch */
2584 goto end;
2585 pc = code->next_pc + res;
2586
2587 if (code->opcode == O (O_BRABC, SB) ||
2588 code->opcode == O (O_BRABS, SB)) /* branch */
2589 goto end;
2590 else /* call */
2591 goto call;
2592
2593 case O (O_BRA, SN):
2594 case O (O_BRA, SL):
2595 case O (O_BRA, SW):
2596 case O (O_BRA, SB): /* bra, branch always */
2597 if (1)
2598 goto condtrue;
2599 goto next;
2600
2601 case O (O_BRN, SB): /* brn, ;-/ branch never? */
2602 if (0)
2603 goto condtrue;
2604 goto next;
2605
2606 case O (O_BHI, SB): /* bhi */
2607 if ((C || Z) == 0)
2608 goto condtrue;
2609 goto next;
2610
2611
2612 case O (O_BLS, SB): /* bls */
2613 if ((C || Z))
2614 goto condtrue;
2615 goto next;
2616
2617 case O (O_BCS, SB): /* bcs, branch if carry set */
2618 if ((C == 1))
2619 goto condtrue;
2620 goto next;
2621
2622 case O (O_BCC, SB): /* bcc, branch if carry clear */
2623 if ((C == 0))
2624 goto condtrue;
2625 goto next;
2626
2627 case O (O_BEQ, SB): /* beq, branch if zero set */
2628 if (Z)
2629 goto condtrue;
2630 goto next;
2631 case O (O_BGT, SB): /* bgt */
2632 if (((Z || (N ^ V)) == 0))
2633 goto condtrue;
2634 goto next;
2635
2636 case O (O_BLE, SB): /* ble */
2637 if (((Z || (N ^ V)) == 1))
2638 goto condtrue;
2639 goto next;
2640
2641 case O (O_BGE, SB): /* bge */
2642 if ((N ^ V) == 0)
2643 goto condtrue;
2644 goto next;
2645 case O (O_BLT, SB): /* blt */
2646 if ((N ^ V))
2647 goto condtrue;
2648 goto next;
2649 case O (O_BMI, SB): /* bmi */
2650 if ((N))
2651 goto condtrue;
2652 goto next;
2653 case O (O_BNE, SB): /* bne, branch if zero clear */
2654 if ((Z == 0))
2655 goto condtrue;
2656 goto next;
2657
2658 case O (O_BPL, SB): /* bpl */
2659 if (N == 0)
2660 goto condtrue;
2661 goto next;
2662 case O (O_BVC, SB): /* bvc */
2663 if ((V == 0))
2664 goto condtrue;
2665 goto next;
2666 case O (O_BVS, SB): /* bvs */
2667 if ((V == 1))
2668 goto condtrue;
2669 goto next;
2670
2671 /* Trap for Command Line setup. */
2672 case O (O_SYS_CMDLINE, SB):
2673 {
2674 int i = 0; /* Loop counter. */
2675 int j = 0; /* Loop counter. */
2676 int ind_arg_len = 0; /* Length of each argument. */
2677 int no_of_args = 0; /* The no. or cmdline args. */
2678 int current_location = 0; /* Location of string. */
2679 int old_sp = 0; /* The Initial Stack Pointer. */
2680 int no_of_slots = 0; /* No. of slots required on the stack
2681 for storing cmdline args. */
2682 int sp_move = 0; /* No. of locations by which the stack needs
2683 to grow. */
2684 int new_sp = 0; /* The final stack pointer location passed
2685 back. */
2686 int *argv_ptrs; /* Pointers of argv strings to be stored. */
2687 int argv_ptrs_location = 0; /* Location of pointers to cmdline
2688 args on the stack. */
2689 int char_ptr_size = 0; /* Size of a character pointer on
2690 target machine. */
2691 int addr_cmdline = 0; /* Memory location where cmdline has
2692 to be stored. */
2693 int size_cmdline = 0; /* Size of cmdline. */
2694
2695 /* Set the address of 256 free locations where command line is
2696 stored. */
2697 addr_cmdline = cmdline_location();
2698 h8_set_reg (sd, 0, addr_cmdline);
2699
2700 /* Counting the no. of commandline arguments. */
2701 for (i = 0; h8_get_cmdline_arg (sd, i) != NULL; i++)
2702 continue;
2703
2704 /* No. of arguments in the command line. */
2705 no_of_args = i;
2706
2707 /* Current location is just a temporary variable,which we are
2708 setting to the point to the start of our commandline string. */
2709 current_location = addr_cmdline;
2710
2711 /* Allocating space for storing pointers of the command line
2712 arguments. */
2713 argv_ptrs = (int *) malloc (sizeof (int) * no_of_args);
2714
2715 /* Setting char_ptr_size to the sizeof (char *) on the different
2716 architectures. */
59768597 2717 if ((h8300hmode || h8300smode) && !h8300_normal_mode)
dc5c3759
MS
2718 {
2719 char_ptr_size = 4;
2720 }
2721 else
2722 {
2723 char_ptr_size = 2;
2724 }
2725
2726 for (i = 0; i < no_of_args; i++)
2727 {
2728 ind_arg_len = 0;
2729
2730 /* The size of the commandline argument. */
917c78f9 2731 ind_arg_len = strlen (h8_get_cmdline_arg (sd, i)) + 1;
dc5c3759
MS
2732
2733 /* The total size of the command line string. */
2734 size_cmdline += ind_arg_len;
2735
2736 /* As we have only 256 bytes, we need to provide a graceful
2737 exit. Anyways, a program using command line arguments
2738 where we cannot store all the command line arguments
2739 given may behave unpredictably. */
2740 if (size_cmdline >= 256)
2741 {
2742 h8_set_reg (sd, 0, 0);
2743 goto next;
2744 }
2745 else
2746 {
2747 /* current_location points to the memory where the next
2748 commandline argument is stored. */
2749 argv_ptrs[i] = current_location;
2750 for (j = 0; j < ind_arg_len; j++)
2751 {
2752 SET_MEMORY_B ((current_location +
2753 (sizeof (char) * j)),
2754 *(h8_get_cmdline_arg (sd, i) +
2755 sizeof (char) * j));
2756 }
2757
2758 /* Setting current_location to the starting of next
2759 argument. */
2760 current_location += ind_arg_len;
2761 }
2762 }
2763
2764 /* This is the original position of the stack pointer. */
2765 old_sp = h8_get_reg (sd, SP_REGNUM);
2766
2767 /* We need space from the stack to store the pointers to argvs. */
2768 /* As we will infringe on the stack, we need to shift the stack
2769 pointer so that the data is not overwritten. We calculate how
2770 much space is required. */
2771 sp_move = (no_of_args) * (char_ptr_size);
2772
2773 /* The final position of stack pointer, we have thus taken some
2774 space from the stack. */
2775 new_sp = old_sp - sp_move;
2776
2777 /* Temporary variable holding value where the argv pointers need
2778 to be stored. */
2779 argv_ptrs_location = new_sp;
2780
2781 /* The argv pointers are stored at sequential locations. As per
2782 the H8300 ABI. */
2783 for (i = 0; i < no_of_args; i++)
2784 {
2785 /* Saving the argv pointer. */
59768597 2786 if ((h8300hmode || h8300smode) && !h8300_normal_mode)
dc5c3759
MS
2787 {
2788 SET_MEMORY_L (argv_ptrs_location, argv_ptrs[i]);
2789 }
2790 else
2791 {
2792 SET_MEMORY_W (argv_ptrs_location, argv_ptrs[i]);
2793 }
2794
2795 /* The next location where the pointer to the next argv
2796 string has to be stored. */
2797 argv_ptrs_location += char_ptr_size;
2798 }
2799
2800 /* Required by POSIX, Setting 0x0 at the end of the list of argv
2801 pointers. */
59768597 2802 if ((h8300hmode || h8300smode) && !h8300_normal_mode)
dc5c3759
MS
2803 {
2804 SET_MEMORY_L (old_sp, 0x0);
2805 }
2806 else
2807 {
2808 SET_MEMORY_W (old_sp, 0x0);
2809 }
2810
2811 /* Freeing allocated memory. */
2812 free (argv_ptrs);
2813 for (i = 0; i <= no_of_args; i++)
2814 {
2815 free (h8_get_cmdline_arg (sd, i));
2816 }
2817 free (h8_get_command_line (sd));
2818
2819 /* The no. of argv arguments are returned in Reg 0. */
2820 h8_set_reg (sd, 0, no_of_args);
2821 /* The Pointer to argv in Register 1. */
2822 h8_set_reg (sd, 1, new_sp);
2823 /* Setting the stack pointer to the new value. */
2824 h8_set_reg (sd, SP_REGNUM, new_sp);
2825 }
2826 goto next;
2827
2828 /* System call processing starts. */
2829 case O (O_SYS_OPEN, SB):
2830 {
2831 int len = 0; /* Length of filename. */
2832 char *filename; /* Filename would go here. */
2833 char temp_char; /* Temporary character */
2834 int mode = 0; /* Mode bits for the file. */
2835 int open_return; /* Return value of open, file descriptor. */
2836 int i; /* Loop counter */
2837 int filename_ptr; /* Pointer to filename in cpu memory. */
2838
2839 /* Setting filename_ptr to first argument of open, */
2840 /* and trying to get mode. */
59768597 2841 if ((h8300sxmode || h8300hmode || h8300smode) && !h8300_normal_mode)
dc5c3759
MS
2842 {
2843 filename_ptr = GET_L_REG (0);
2844 mode = GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM) + 4);
2845 }
2846 else
2847 {
2848 filename_ptr = GET_W_REG (0);
2849 mode = GET_MEMORY_W (h8_get_reg (sd, SP_REGNUM) + 2);
2850 }
2851
2852 /* Trying to find the length of the filename. */
2853 temp_char = GET_MEMORY_B (h8_get_reg (sd, 0));
2854
2855 len = 1;
2856 while (temp_char != '\0')
2857 {
2858 temp_char = GET_MEMORY_B (filename_ptr + len);
2859 len++;
2860 }
2861
2862 /* Allocating space for the filename. */
2863 filename = (char *) malloc (sizeof (char) * len);
2864
2865 /* String copying the filename from memory. */
2866 for (i = 0; i < len; i++)
2867 {
2868 temp_char = GET_MEMORY_B (filename_ptr + i);
2869 filename[i] = temp_char;
2870 }
2871
2872 /* Callback to open and return the file descriptor. */
2873 open_return = sim_callback->open (sim_callback, filename, mode);
2874
2875 /* Return value in register 0. */
2876 h8_set_reg (sd, 0, open_return);
2877
2878 /* Freeing memory used for filename. */
2879 free (filename);
2880 }
2881 goto next;
2882
2883 case O (O_SYS_READ, SB):
2884 {
2885 char *char_ptr; /* Where characters read would be stored. */
2886 int fd; /* File descriptor */
2887 int buf_size; /* BUF_SIZE parameter in read. */
2888 int i = 0; /* Temporary Loop counter */
2889 int read_return = 0; /* Return value from callback to
2890 read. */
2891
59768597
SA
2892 fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
2893 buf_size = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
dc5c3759
MS
2894
2895 char_ptr = (char *) malloc (sizeof (char) * buf_size);
2896
2897 /* Callback to read and return the no. of characters read. */
2898 read_return =
2899 sim_callback->read (sim_callback, fd, char_ptr, buf_size);
2900
2901 /* The characters read are stored in cpu memory. */
2902 for (i = 0; i < buf_size; i++)
2903 {
2904 SET_MEMORY_B ((h8_get_reg (sd, 1) + (sizeof (char) * i)),
2905 *(char_ptr + (sizeof (char) * i)));
2906 }
2907
2908 /* Return value in Register 0. */
2909 h8_set_reg (sd, 0, read_return);
2910
2911 /* Freeing memory used as buffer. */
2912 free (char_ptr);
2913 }
2914 goto next;
2915
2916 case O (O_SYS_WRITE, SB):
2917 {
2918 int fd; /* File descriptor */
2919 char temp_char; /* Temporary character */
2920 int len; /* Length of write, Parameter II to write. */
2921 int char_ptr; /* Character Pointer, Parameter I of write. */
2922 char *ptr; /* Where characters to be written are stored.
2923 */
2924 int write_return; /* Return value from callback to write. */
2925 int i = 0; /* Loop counter */
2926
59768597
SA
2927 fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
2928 char_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
2929 len = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
dc5c3759
MS
2930
2931 /* Allocating space for the characters to be written. */
2932 ptr = (char *) malloc (sizeof (char) * len);
2933
2934 /* Fetching the characters from cpu memory. */
2935 for (i = 0; i < len; i++)
2936 {
2937 temp_char = GET_MEMORY_B (char_ptr + i);
2938 ptr[i] = temp_char;
2939 }
2940
2941 /* Callback write and return the no. of characters written. */
2942 write_return = sim_callback->write (sim_callback, fd, ptr, len);
2943
2944 /* Return value in Register 0. */
2945 h8_set_reg (sd, 0, write_return);
2946
2947 /* Freeing memory used as buffer. */
2948 free (ptr);
2949 }
2950 goto next;
2951
2952 case O (O_SYS_LSEEK, SB):
2953 {
2954 int fd; /* File descriptor */
2955 int offset; /* Offset */
2956 int origin; /* Origin */
2957 int lseek_return; /* Return value from callback to lseek. */
2958
59768597
SA
2959 fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
2960 offset = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
2961 origin = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
c906108c 2962
dc5c3759
MS
2963 /* Callback lseek and return offset. */
2964 lseek_return =
2965 sim_callback->lseek (sim_callback, fd, offset, origin);
3b02cf92 2966
dc5c3759
MS
2967 /* Return value in register 0. */
2968 h8_set_reg (sd, 0, lseek_return);
2969 }
2970 goto next;
c906108c 2971
dc5c3759
MS
2972 case O (O_SYS_CLOSE, SB):
2973 {
2974 int fd; /* File descriptor */
2975 int close_return; /* Return value from callback to close. */
c906108c 2976
59768597 2977 fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
c906108c 2978
dc5c3759
MS
2979 /* Callback close and return. */
2980 close_return = sim_callback->close (sim_callback, fd);
c906108c 2981
dc5c3759
MS
2982 /* Return value in register 0. */
2983 h8_set_reg (sd, 0, close_return);
2984 }
2985 goto next;
c906108c 2986
dc5c3759
MS
2987 case O (O_SYS_FSTAT, SB):
2988 {
2989 int fd; /* File descriptor */
2990 struct stat stat_rec; /* Stat record */
2991 int fstat_return; /* Return value from callback to stat. */
2992 int stat_ptr; /* Pointer to stat record. */
2993 char *temp_stat_ptr; /* Temporary stat_rec pointer. */
c906108c 2994
59768597 2995 fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
c906108c 2996
dc5c3759 2997 /* Setting stat_ptr to second argument of stat. */
59768597 2998 stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
c906108c 2999
dc5c3759 3000 /* Callback stat and return. */
2d7bb758
JB
3001 fstat_return = sim_callback->to_fstat (sim_callback, fd,
3002 &stat_rec);
c906108c 3003
dc5c3759
MS
3004 /* Have stat_ptr point to starting of stat_rec. */
3005 temp_stat_ptr = (char *) (&stat_rec);
c906108c 3006
dc5c3759
MS
3007 /* Setting up the stat structure returned. */
3008 SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
3009 stat_ptr += 2;
3010 SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
3011 stat_ptr += 2;
3012 SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
3013 stat_ptr += 4;
3014 SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
3015 stat_ptr += 2;
3016 SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
3017 stat_ptr += 2;
3018 SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
3019 stat_ptr += 2;
3020 SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
3021 stat_ptr += 2;
3022 SET_MEMORY_L (stat_ptr, stat_rec.st_size);
3023 stat_ptr += 4;
3024 SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
3025 stat_ptr += 8;
3026 SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
3027 stat_ptr += 8;
3028 SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
c906108c 3029
dc5c3759
MS
3030 /* Return value in register 0. */
3031 h8_set_reg (sd, 0, fstat_return);
3032 }
3033 goto next;
c906108c 3034
dc5c3759
MS
3035 case O (O_SYS_STAT, SB):
3036 {
3037 int len = 0; /* Length of filename. */
3038 char *filename; /* Filename would go here. */
3039 char temp_char; /* Temporary character */
3040 int filename_ptr; /* Pointer to filename in cpu memory. */
3041 struct stat stat_rec; /* Stat record */
3042 int stat_return; /* Return value from callback to stat */
3043 int stat_ptr; /* Pointer to stat record. */
3044 char *temp_stat_ptr; /* Temporary stat_rec pointer. */
3045 int i = 0; /* Loop Counter */
c906108c 3046
dc5c3759 3047 /* Setting filename_ptr to first argument of open. */
59768597 3048 filename_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
c906108c 3049
dc5c3759
MS
3050 /* Trying to find the length of the filename. */
3051 temp_char = GET_MEMORY_B (h8_get_reg (sd, 0));
c906108c 3052
dc5c3759
MS
3053 len = 1;
3054 while (temp_char != '\0')
3055 {
3056 temp_char = GET_MEMORY_B (filename_ptr + len);
3057 len++;
3058 }
d0fe2f7e 3059
dc5c3759
MS
3060 /* Allocating space for the filename. */
3061 filename = (char *) malloc (sizeof (char) * len);
c3f4437e 3062
dc5c3759
MS
3063 /* String copying the filename from memory. */
3064 for (i = 0; i < len; i++)
3065 {
3066 temp_char = GET_MEMORY_B (filename_ptr + i);
3067 filename[i] = temp_char;
3068 }
c906108c 3069
dc5c3759
MS
3070 /* Setting stat_ptr to second argument of stat. */
3071 /* stat_ptr = h8_get_reg (sd, 1); */
59768597 3072 stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
c906108c 3073
dc5c3759
MS
3074 /* Callback stat and return. */
3075 stat_return =
2d7bb758 3076 sim_callback->to_stat (sim_callback, filename, &stat_rec);
c906108c 3077
dc5c3759
MS
3078 /* Have stat_ptr point to starting of stat_rec. */
3079 temp_stat_ptr = (char *) (&stat_rec);
3080
3081 /* Freeing memory used for filename. */
3082 free (filename);
3083
3084 /* Setting up the stat structure returned. */
3085 SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
3086 stat_ptr += 2;
3087 SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
3088 stat_ptr += 2;
3089 SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
3090 stat_ptr += 4;
3091 SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
3092 stat_ptr += 2;
3093 SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
3094 stat_ptr += 2;
3095 SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
3096 stat_ptr += 2;
3097 SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
3098 stat_ptr += 2;
3099 SET_MEMORY_L (stat_ptr, stat_rec.st_size);
3100 stat_ptr += 4;
3101 SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
3102 stat_ptr += 8;
3103 SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
3104 stat_ptr += 8;
3105 SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
3106
3107 /* Return value in register 0. */
3108 h8_set_reg (sd, 0, stat_return);
3109 }
c906108c 3110 goto next;
dc5c3759 3111 /* End of system call processing. */
c906108c 3112
dc5c3759
MS
3113 case O (O_NOT, SB): /* not.b */
3114 if (fetch2 (sd, &code->src, &rd))
3115 goto end;
3116 rd = ~rd;
3117 v = 0;
3118 goto shift8;
c906108c 3119
dc5c3759
MS
3120 case O (O_NOT, SW): /* not.w */
3121 if (fetch2 (sd, &code->src, &rd))
3122 goto end;
3123 rd = ~rd;
3124 v = 0;
3125 goto shift16;
c906108c 3126
dc5c3759
MS
3127 case O (O_NOT, SL): /* not.l */
3128 if (fetch2 (sd, &code->src, &rd))
3129 goto end;
3130 rd = ~rd;
3131 v = 0;
3132 goto shift32;
c906108c 3133
dc5c3759
MS
3134 case O (O_SHLL, SB): /* shll.b */
3135 case O (O_SHLR, SB): /* shlr.b */
3136 if (fetch2 (sd, &code->dst, &rd))
3137 goto end;
c906108c 3138
55acb21b
MS
3139 if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
3140 ea = 1; /* unary op */
3141 else /* binary op */
dc5c3759 3142 fetch (sd, &code->src, &ea);
c906108c 3143
dc5c3759
MS
3144 if (code->opcode == O (O_SHLL, SB))
3145 {
3146 v = (ea > 8);
3147 c = rd & (0x80 >> (ea - 1));
3148 rd <<= ea;
3149 }
3150 else
3151 {
3152 v = 0;
3153 c = rd & (1 << (ea - 1));
3154 rd = (unsigned char) rd >> ea;
3155 }
3156 goto shift8;
c906108c 3157
dc5c3759
MS
3158 case O (O_SHLL, SW): /* shll.w */
3159 case O (O_SHLR, SW): /* shlr.w */
3160 if (fetch2 (sd, &code->dst, &rd))
3161 goto end;
c906108c 3162
55acb21b
MS
3163 if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
3164 ea = 1; /* unary op */
dc5c3759 3165 else
55acb21b 3166 fetch (sd, &code->src, &ea);
c906108c 3167
dc5c3759
MS
3168 if (code->opcode == O (O_SHLL, SW))
3169 {
3170 v = (ea > 16);
3171 c = rd & (0x8000 >> (ea - 1));
3172 rd <<= ea;
3173 }
3174 else
3175 {
3176 v = 0;
3177 c = rd & (1 << (ea - 1));
3178 rd = (unsigned short) rd >> ea;
3179 }
3180 goto shift16;
c906108c 3181
dc5c3759
MS
3182 case O (O_SHLL, SL): /* shll.l */
3183 case O (O_SHLR, SL): /* shlr.l */
3184 if (fetch2 (sd, &code->dst, &rd))
3185 goto end;
c906108c 3186
55acb21b
MS
3187 if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
3188 ea = 1; /* unary op */
dc5c3759 3189 else
55acb21b 3190 fetch (sd, &code->src, &ea);
c906108c 3191
dc5c3759 3192 if (code->opcode == O (O_SHLL, SL))
c3f4437e 3193 {
dc5c3759
MS
3194 v = (ea > 32);
3195 c = rd & (0x80000000 >> (ea - 1));
3196 rd <<= ea;
c3f4437e 3197 }
dc5c3759 3198 else
c3f4437e 3199 {
dc5c3759
MS
3200 v = 0;
3201 c = rd & (1 << (ea - 1));
3202 rd = (unsigned int) rd >> ea;
c3f4437e 3203 }
dc5c3759
MS
3204 goto shift32;
3205
3206 case O (O_SHAL, SB):
3207 case O (O_SHAR, SB):
3208 if (fetch2 (sd, &code->dst, &rd))
3209 goto end;
3210
3211 if (code->src.type == X (OP_IMM, SB))
3212 fetch (sd, &code->src, &ea);
c3f4437e 3213 else
dc5c3759 3214 ea = 1;
6147b1f6 3215
dc5c3759 3216 if (code->opcode == O (O_SHAL, SB))
c3f4437e 3217 {
dc5c3759
MS
3218 c = rd & (0x80 >> (ea - 1));
3219 res = rd >> (7 - ea);
3220 v = ((res & 1) && !(res & 2))
3221 || (!(res & 1) && (res & 2));
3222 rd <<= ea;
c3f4437e 3223 }
dc5c3759 3224 else
c3f4437e 3225 {
dc5c3759
MS
3226 c = rd & (1 << (ea - 1));
3227 v = 0;
3228 rd = ((signed char) rd) >> ea;
c3f4437e 3229 }
dc5c3759
MS
3230 goto shift8;
3231
3232 case O (O_SHAL, SW):
3233 case O (O_SHAR, SW):
3234 if (fetch2 (sd, &code->dst, &rd))
3235 goto end;
3236
3237 if (code->src.type == X (OP_IMM, SW))
3238 fetch (sd, &code->src, &ea);
c3f4437e 3239 else
dc5c3759 3240 ea = 1;
c906108c 3241
dc5c3759 3242 if (code->opcode == O (O_SHAL, SW))
c3f4437e 3243 {
dc5c3759
MS
3244 c = rd & (0x8000 >> (ea - 1));
3245 res = rd >> (15 - ea);
3246 v = ((res & 1) && !(res & 2))
3247 || (!(res & 1) && (res & 2));
3248 rd <<= ea;
c3f4437e 3249 }
dc5c3759 3250 else
c3f4437e 3251 {
dc5c3759
MS
3252 c = rd & (1 << (ea - 1));
3253 v = 0;
3254 rd = ((signed short) rd) >> ea;
c3f4437e 3255 }
dc5c3759
MS
3256 goto shift16;
3257
3258 case O (O_SHAL, SL):
3259 case O (O_SHAR, SL):
3260 if (fetch2 (sd, &code->dst, &rd))
3261 goto end;
3262
3263 if (code->src.type == X (OP_IMM, SL))
3264 fetch (sd, &code->src, &ea);
3265 else
3266 ea = 1;
c906108c 3267
dc5c3759 3268 if (code->opcode == O (O_SHAL, SL))
c3f4437e 3269 {
dc5c3759
MS
3270 c = rd & (0x80000000 >> (ea - 1));
3271 res = rd >> (31 - ea);
3272 v = ((res & 1) && !(res & 2))
3273 || (!(res & 1) && (res & 2));
3274 rd <<= ea;
c3f4437e 3275 }
dc5c3759 3276 else
c3f4437e 3277 {
dc5c3759
MS
3278 c = rd & (1 << (ea - 1));
3279 v = 0;
3280 rd = ((signed int) rd) >> ea;
c3f4437e 3281 }
dc5c3759 3282 goto shift32;
c906108c 3283
dc5c3759
MS
3284 case O (O_ROTL, SB):
3285 case O (O_ROTR, SB):
3286 if (fetch2 (sd, &code->dst, &rd))
3287 goto end;
c906108c 3288
dc5c3759
MS
3289 if (code->src.type == X (OP_IMM, SB))
3290 fetch (sd, &code->src, &ea);
3291 else
3292 ea = 1;
c906108c 3293
dc5c3759
MS
3294 while (ea--)
3295 if (code->opcode == O (O_ROTL, SB))
3296 {
3297 c = rd & 0x80;
3298 rd <<= 1;
3299 if (c)
3300 rd |= 1;
3301 }
3302 else
3303 {
3304 c = rd & 1;
3305 rd = ((unsigned char) rd) >> 1;
3306 if (c)
3307 rd |= 0x80;
3308 }
c906108c 3309
dc5c3759
MS
3310 v = 0;
3311 goto shift8;
c906108c 3312
dc5c3759
MS
3313 case O (O_ROTL, SW):
3314 case O (O_ROTR, SW):
3315 if (fetch2 (sd, &code->dst, &rd))
3316 goto end;
c906108c 3317
dc5c3759
MS
3318 if (code->src.type == X (OP_IMM, SW))
3319 fetch (sd, &code->src, &ea);
3320 else
3321 ea = 1;
c906108c 3322
dc5c3759
MS
3323 while (ea--)
3324 if (code->opcode == O (O_ROTL, SW))
3325 {
3326 c = rd & 0x8000;
3327 rd <<= 1;
3328 if (c)
3329 rd |= 1;
3330 }
3331 else
3332 {
3333 c = rd & 1;
3334 rd = ((unsigned short) rd) >> 1;
3335 if (c)
3336 rd |= 0x8000;
3337 }
c906108c 3338
dc5c3759
MS
3339 v = 0;
3340 goto shift16;
c906108c 3341
dc5c3759
MS
3342 case O (O_ROTL, SL):
3343 case O (O_ROTR, SL):
3344 if (fetch2 (sd, &code->dst, &rd))
3345 goto end;
c906108c 3346
dc5c3759
MS
3347 if (code->src.type == X (OP_IMM, SL))
3348 fetch (sd, &code->src, &ea);
3349 else
3350 ea = 1;
c906108c 3351
dc5c3759
MS
3352 while (ea--)
3353 if (code->opcode == O (O_ROTL, SL))
3354 {
3355 c = rd & 0x80000000;
3356 rd <<= 1;
3357 if (c)
3358 rd |= 1;
3359 }
3360 else
3361 {
3362 c = rd & 1;
3363 rd = ((unsigned int) rd) >> 1;
3364 if (c)
3365 rd |= 0x80000000;
3366 }
c906108c 3367
dc5c3759
MS
3368 v = 0;
3369 goto shift32;
c906108c 3370
dc5c3759
MS
3371 case O (O_ROTXL, SB):
3372 case O (O_ROTXR, SB):
3373 if (fetch2 (sd, &code->dst, &rd))
3374 goto end;
d1360fb0 3375
dc5c3759
MS
3376 if (code->src.type == X (OP_IMM, SB))
3377 fetch (sd, &code->src, &ea);
3378 else
3379 ea = 1;
d1360fb0 3380
dc5c3759
MS
3381 while (ea--)
3382 if (code->opcode == O (O_ROTXL, SB))
3383 {
3384 res = rd & 0x80;
3385 rd <<= 1;
3386 if (C)
3387 rd |= 1;
3388 c = res;
3389 }
3390 else
3391 {
3392 res = rd & 1;
3393 rd = ((unsigned char) rd) >> 1;
3394 if (C)
3395 rd |= 0x80;
3396 c = res;
3397 }
d1360fb0 3398
dc5c3759
MS
3399 v = 0;
3400 goto shift8;
d1360fb0 3401
dc5c3759
MS
3402 case O (O_ROTXL, SW):
3403 case O (O_ROTXR, SW):
3404 if (fetch2 (sd, &code->dst, &rd))
3405 goto end;
d1360fb0 3406
dc5c3759
MS
3407 if (code->src.type == X (OP_IMM, SW))
3408 fetch (sd, &code->src, &ea);
3409 else
3410 ea = 1;
d1360fb0 3411
dc5c3759
MS
3412 while (ea--)
3413 if (code->opcode == O (O_ROTXL, SW))
d1360fb0 3414 {
dc5c3759
MS
3415 res = rd & 0x8000;
3416 rd <<= 1;
3417 if (C)
3418 rd |= 1;
3419 c = res;
d1360fb0
V
3420 }
3421 else
3422 {
dc5c3759
MS
3423 res = rd & 1;
3424 rd = ((unsigned short) rd) >> 1;
3425 if (C)
3426 rd |= 0x8000;
3427 c = res;
d1360fb0
V
3428 }
3429
dc5c3759
MS
3430 v = 0;
3431 goto shift16;
d1360fb0 3432
dc5c3759
MS
3433 case O (O_ROTXL, SL):
3434 case O (O_ROTXR, SL):
3435 if (fetch2 (sd, &code->dst, &rd))
3436 goto end;
d1360fb0 3437
dc5c3759
MS
3438 if (code->src.type == X (OP_IMM, SL))
3439 fetch (sd, &code->src, &ea);
3440 else
3441 ea = 1;
d1360fb0 3442
dc5c3759
MS
3443 while (ea--)
3444 if (code->opcode == O (O_ROTXL, SL))
3445 {
3446 res = rd & 0x80000000;
3447 rd <<= 1;
3448 if (C)
3449 rd |= 1;
3450 c = res;
3451 }
3452 else
3453 {
3454 res = rd & 1;
3455 rd = ((unsigned int) rd) >> 1;
3456 if (C)
3457 rd |= 0x80000000;
3458 c = res;
d1360fb0
V
3459 }
3460
dc5c3759
MS
3461 v = 0;
3462 goto shift32;
d1360fb0 3463
dc5c3759
MS
3464 case O (O_JMP, SN):
3465 case O (O_JMP, SL):
3466 case O (O_JMP, SB): /* jmp */
3467 case O (O_JMP, SW):
9f70f8ec
MS
3468 fetch (sd, &code->src, &pc);
3469 goto end;
d1360fb0 3470
dc5c3759
MS
3471 case O (O_JSR, SN):
3472 case O (O_JSR, SL):
3473 case O (O_JSR, SB): /* jsr, jump to subroutine */
3474 case O (O_JSR, SW):
9f70f8ec
MS
3475 if (fetch (sd, &code->src, &pc))
3476 goto end;
3477 call:
3478 tmp = h8_get_reg (sd, SP_REGNUM);
d1360fb0 3479
59768597 3480 if (h8300hmode && !h8300_normal_mode)
9f70f8ec
MS
3481 {
3482 tmp -= 4;
3483 SET_MEMORY_L (tmp, code->next_pc);
3484 }
3485 else
3486 {
3487 tmp -= 2;
3488 SET_MEMORY_W (tmp, code->next_pc);
3489 }
3490 h8_set_reg (sd, SP_REGNUM, tmp);
d1360fb0 3491
9f70f8ec 3492 goto end;
dc5c3759
MS
3493
3494 case O (O_BSR, SW):
3495 case O (O_BSR, SL):
3496 case O (O_BSR, SB): /* bsr, branch to subroutine */
3497 if (fetch (sd, &code->src, &res))
3498 goto end;
3499 pc = code->next_pc + res;
3500 goto call;
3501
9f70f8ec
MS
3502 case O (O_RTE, SN): /* rte, return from exception */
3503 rte:
3504 /* Pops exr and ccr before pc -- otherwise identical to rts. */
3505 tmp = h8_get_reg (sd, SP_REGNUM);
dc5c3759 3506
9f70f8ec
MS
3507 if (h8300smode) /* pop exr */
3508 {
3509 h8_set_exr (sd, GET_MEMORY_L (tmp));
3510 tmp += 4;
3511 }
59768597 3512 if (h8300hmode && !h8300_normal_mode)
9f70f8ec
MS
3513 {
3514 h8_set_ccr (sd, GET_MEMORY_L (tmp));
3515 tmp += 4;
3516 pc = GET_MEMORY_L (tmp);
3517 tmp += 4;
3518 }
3519 else
3520 {
3521 h8_set_ccr (sd, GET_MEMORY_W (tmp));
3522 tmp += 2;
3523 pc = GET_MEMORY_W (tmp);
3524 tmp += 2;
3525 }
dc5c3759 3526
9f70f8ec
MS
3527 GETSR (sd);
3528 h8_set_reg (sd, SP_REGNUM, tmp);
3529 goto end;
d1360fb0 3530
9f70f8ec
MS
3531 case O (O_RTS, SN): /* rts, return from subroutine */
3532 rts:
3533 tmp = h8_get_reg (sd, SP_REGNUM);
3534
59768597 3535 if (h8300hmode && !h8300_normal_mode)
9f70f8ec
MS
3536 {
3537 pc = GET_MEMORY_L (tmp);
3538 tmp += 4;
3539 }
3540 else
3541 {
3542 pc = GET_MEMORY_W (tmp);
3543 tmp += 2;
3544 }
3545
3546 h8_set_reg (sd, SP_REGNUM, tmp);
3547 goto end;
d1360fb0 3548
dc5c3759 3549 case O (O_ILL, SB): /* illegal */
4ca9d09e 3550 sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL);
dc5c3759
MS
3551 goto end;
3552
3553 case O (O_SLEEP, SN): /* sleep */
3554 /* Check for magic numbers in r1 and r2. */
3555 if ((h8_get_reg (sd, R1_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC1 &&
3556 (h8_get_reg (sd, R2_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC2 &&
3557 SIM_WIFEXITED (h8_get_reg (sd, 0)))
3558 {
3559 /* This trap comes from _exit, not from gdb. */
4ca9d09e
MF
3560 sim_engine_halt (sd, cpu, NULL, pc, sim_exited,
3561 SIM_WEXITSTATUS (h8_get_reg (sd, 0)));
dc5c3759 3562 }
e22fef83 3563#if 0
f408565c
MS
3564 /* Unfortunately this won't really work, because
3565 when we take a breakpoint trap, R0 has a "random",
3566 user-defined value. Don't see any immediate solution. */
f0861129
MS
3567 else if (SIM_WIFSTOPPED (h8_get_reg (sd, 0)))
3568 {
3569 /* Pass the stop signal up to gdb. */
4ca9d09e
MF
3570 sim_engine_halt (sd, cpu, NULL, pc, sim_stopped,
3571 SIM_WSTOPSIG (h8_get_reg (sd, 0)));
f0861129 3572 }
e22fef83 3573#endif
dc5c3759
MS
3574 else
3575 {
3576 /* Treat it as a sigtrap. */
4ca9d09e 3577 sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
dc5c3759
MS
3578 }
3579 goto end;
bf174226 3580
9f70f8ec
MS
3581 case O (O_TRAPA, SB): /* trapa */
3582 if (fetch (sd, &code->src, &res))
59768597
SA
3583 goto end; /* res is vector number. */
3584
3585 tmp = h8_get_reg (sd, SP_REGNUM);
3586 if(h8300_normal_mode)
3587 {
3588 tmp -= 2;
3589 SET_MEMORY_W (tmp, code->next_pc);
3590 tmp -= 2;
3591 SET_MEMORY_W (tmp, h8_get_ccr (sd));
3592 }
3593 else
3594 {
3595 tmp -= 4;
3596 SET_MEMORY_L (tmp, code->next_pc);
3597 tmp -= 4;
3598 SET_MEMORY_L (tmp, h8_get_ccr (sd));
3599 }
3600 intMaskBit = 1;
3601 BUILDSR (sd);
3602
9f70f8ec
MS
3603 if (h8300smode)
3604 {
3605 tmp -= 4;
3606 SET_MEMORY_L (tmp, h8_get_exr (sd));
3607 }
3608
3609 h8_set_reg (sd, SP_REGNUM, tmp);
3610
59768597
SA
3611 if(h8300_normal_mode)
3612 pc = GET_MEMORY_L (0x10 + res * 2); /* Vector addresses are 0x10,0x12,0x14 and 0x16 */
3613 else
3614 pc = GET_MEMORY_L (0x20 + res * 4);
9f70f8ec
MS
3615 goto end;
3616
dc5c3759 3617 case O (O_BPT, SN):
4ca9d09e 3618 sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
dc5c3759 3619 goto end;
bf174226 3620
dc5c3759
MS
3621 case O (O_BSETEQ, SB):
3622 if (Z)
3623 goto bset;
3624 goto next;
bf174226 3625
dc5c3759
MS
3626 case O (O_BSETNE, SB):
3627 if (!Z)
3628 goto bset;
3629 goto next;
bf174226 3630
dc5c3759
MS
3631 case O (O_BCLREQ, SB):
3632 if (Z)
3633 goto bclr;
3634 goto next;
bf174226 3635
dc5c3759
MS
3636 case O (O_BCLRNE, SB):
3637 if (!Z)
3638 goto bclr;
3639 goto next;
bf174226 3640
dc5c3759
MS
3641 OBITOP (O_BNOT, 1, 1, ea ^= m); /* bnot */
3642 OBITOP (O_BTST, 1, 0, nz = ea & m); /* btst */
3643 bset:
3644 OBITOP (O_BSET, 1, 1, ea |= m); /* bset */
3645 bclr:
3646 OBITOP (O_BCLR, 1, 1, ea &= ~m); /* bclr */
3647 OBITOP (O_BLD, 1, 0, c = ea & m); /* bld */
3648 OBITOP (O_BILD, 1, 0, c = !(ea & m)); /* bild */
3649 OBITOP (O_BST, 1, 1, ea &= ~m;
3650 if (C) ea |= m); /* bst */
3651 OBITOP (O_BIST, 1, 1, ea &= ~m;
3652 if (!C) ea |= m); /* bist */
3653 OBITOP (O_BSTZ, 1, 1, ea &= ~m;
3654 if (Z) ea |= m); /* bstz */
3655 OBITOP (O_BISTZ, 1, 1, ea &= ~m;
3656 if (!Z) ea |= m); /* bistz */
3657 OBITOP (O_BAND, 1, 0, c = (ea & m) && C); /* band */
3658 OBITOP (O_BIAND, 1, 0, c = !(ea & m) && C); /* biand */
3659 OBITOP (O_BOR, 1, 0, c = (ea & m) || C); /* bor */
3660 OBITOP (O_BIOR, 1, 0, c = !(ea & m) || C); /* bior */
3661 OBITOP (O_BXOR, 1, 0, c = ((ea & m) != 0)!= C); /* bxor */
3662 OBITOP (O_BIXOR, 1, 0, c = !(ea & m) != C); /* bixor */
3663
3664 case O (O_BFLD, SB): /* bfld */
3665 /* bitfield load */
3666 ea = 0;
3667 if (fetch (sd, &code->src, &bit))
3668 goto end;
bf174226 3669
dc5c3759
MS
3670 if (bit != 0)
3671 {
3672 if (fetch (sd, &code->dst, &ea))
3673 goto end;
bf174226 3674
dc5c3759
MS
3675 ea &= bit;
3676 while (!(bit & 1))
3677 {
3678 ea >>= 1;
3679 bit >>= 1;
3680 }
3681 }
3682 if (store (sd, &code->op3, ea))
3683 goto end;
bf174226 3684
c906108c
SS
3685 goto next;
3686
dc5c3759
MS
3687 case O(O_BFST, SB): /* bfst */
3688 /* bitfield store */
3689 /* NOTE: the imm8 value is in dst, and the ea value
3690 (which is actually the destination) is in op3.
3691 It has to be that way, to avoid breaking the assembler. */
bf174226 3692
dc5c3759
MS
3693 if (fetch (sd, &code->dst, &bit)) /* imm8 */
3694 goto end;
3695 if (bit == 0) /* noop -- nothing to do. */
3696 goto next;
bf174226 3697
dc5c3759
MS
3698 if (fetch (sd, &code->src, &rd)) /* reg8 src */
3699 goto end;
bf174226 3700
dc5c3759
MS
3701 if (fetch2 (sd, &code->op3, &ea)) /* ea dst */
3702 goto end;
bf174226 3703
dc5c3759
MS
3704 /* Left-shift the register data into position. */
3705 for (tmp = bit; !(tmp & 1); tmp >>= 1)
3706 rd <<= 1;
bf174226 3707
dc5c3759
MS
3708 /* Combine it with the neighboring bits. */
3709 ea = (ea & ~bit) | (rd & bit);
bf174226 3710
dc5c3759
MS
3711 /* Put it back. */
3712 if (store2 (sd, &code->op3, ea))
3713 goto end;
3714 goto next;
3715
3716 case O (O_CLRMAC, SN): /* clrmac */
3717 h8_set_mach (sd, 0);
3718 h8_set_macl (sd, 0);
3719 h8_set_macZ (sd, 1);
3720 h8_set_macV (sd, 0);
3721 h8_set_macN (sd, 0);
3722 goto next;
3723
3724 case O (O_STMAC, SL): /* stmac, 260 */
3725 switch (code->src.type) {
3726 case X (OP_MACH, SL):
3727 res = h8_get_mach (sd);
3728 if (res & 0x200) /* sign extend */
3729 res |= 0xfffffc00;
3730 break;
3731 case X (OP_MACL, SL):
3732 res = h8_get_macl (sd);
3733 break;
3734 default: goto illegal;
bf174226 3735 }
dc5c3759
MS
3736 nz = !h8_get_macZ (sd);
3737 n = h8_get_macN (sd);
3738 v = h8_get_macV (sd);
3739
3740 if (store (sd, &code->dst, res))
3741 goto end;
3742
bf174226
V
3743 goto next;
3744
dc5c3759
MS
3745 case O (O_LDMAC, SL): /* ldmac, 179 */
3746 if (fetch (sd, &code->src, &rd))
3747 goto end;
bf174226 3748
dc5c3759
MS
3749 switch (code->dst.type) {
3750 case X (OP_MACH, SL):
3751 rd &= 0x3ff; /* Truncate to 10 bits */
3752 h8_set_mach (sd, rd);
3753 break;
3754 case X (OP_MACL, SL):
3755 h8_set_macl (sd, rd);
3756 break;
3757 default: goto illegal;
3758 }
3759 h8_set_macV (sd, 0);
3760 goto next;
bf174226 3761
dc5c3759
MS
3762 case O (O_MAC, SW):
3763 if (fetch (sd, &code->src, &rd) ||
3764 fetch (sd, &code->dst, &res))
3765 goto end;
bf174226 3766
dc5c3759
MS
3767 /* Ye gods, this is non-portable!
3768 However, the existing mul/div code is similar. */
3769 res = SEXTSHORT (res) * SEXTSHORT (rd);
bf174226 3770
dc5c3759
MS
3771 if (h8_get_macS (sd)) /* Saturating mode */
3772 {
3773 long long mac = h8_get_macl (sd);
bf174226 3774
dc5c3759
MS
3775 if (mac & 0x80000000) /* sign extend */
3776 mac |= 0xffffffff00000000LL;
bf174226 3777
dc5c3759
MS
3778 mac += res;
3779 if (mac > 0x7fffffff || mac < 0xffffffff80000000LL)
3780 h8_set_macV (sd, 1);
3781 h8_set_macZ (sd, (mac == 0));
3782 h8_set_macN (sd, (mac < 0));
3783 h8_set_macl (sd, (int) mac);
3784 }
3785 else /* "Less Saturating" mode */
3786 {
3787 long long mac = h8_get_mach (sd);
3788 mac <<= 32;
3789 mac += h8_get_macl (sd);
3790
3791 if (mac & 0x20000000000LL) /* sign extend */
3792 mac |= 0xfffffc0000000000LL;
3793
3794 mac += res;
3795 if (mac > 0x1ffffffffffLL ||
3796 mac < (long long) 0xfffffe0000000000LL)
3797 h8_set_macV (sd, 1);
3798 h8_set_macZ (sd, (mac == 0));
3799 h8_set_macN (sd, (mac < 0));
3800 h8_set_macl (sd, (int) mac);
3801 mac >>= 32;
3802 h8_set_mach (sd, (int) (mac & 0x3ff));
3803 }
bf174226
V
3804 goto next;
3805
dc5c3759
MS
3806 case O (O_MULS, SW): /* muls.w */
3807 if (fetch (sd, &code->src, &ea) ||
3808 fetch (sd, &code->dst, &rd))
3809 goto end;
bf174226 3810
e073c474 3811 ea = SEXTSHORT (ea);
dc5c3759
MS
3812 res = SEXTSHORT (ea * SEXTSHORT (rd));
3813
3814 n = res & 0x8000;
3815 nz = res & 0xffff;
3816 if (store (sd, &code->dst, res))
3817 goto end;
bf174226 3818
bf174226
V
3819 goto next;
3820
dc5c3759
MS
3821 case O (O_MULS, SL): /* muls.l */
3822 if (fetch (sd, &code->src, &ea) ||
3823 fetch (sd, &code->dst, &rd))
3824 goto end;
bf174226 3825
dc5c3759 3826 res = ea * rd;
bf174226 3827
dc5c3759
MS
3828 n = res & 0x80000000;
3829 nz = res & 0xffffffff;
3830 if (store (sd, &code->dst, res))
3831 goto end;
bf174226
V
3832 goto next;
3833
dc5c3759
MS
3834 case O (O_MULSU, SL): /* muls/u.l */
3835 if (fetch (sd, &code->src, &ea) ||
3836 fetch (sd, &code->dst, &rd))
3837 goto end;
bf174226 3838
dc5c3759
MS
3839 /* Compute upper 32 bits of the 64-bit result. */
3840 res = (((long long) ea) * ((long long) rd)) >> 32;
bf174226 3841
dc5c3759
MS
3842 n = res & 0x80000000;
3843 nz = res & 0xffffffff;
3844 if (store (sd, &code->dst, res))
3845 goto end;
3846 goto next;
bf174226 3847
dc5c3759
MS
3848 case O (O_MULU, SW): /* mulu.w */
3849 if (fetch (sd, &code->src, &ea) ||
3850 fetch (sd, &code->dst, &rd))
3851 goto end;
bf174226 3852
dc5c3759
MS
3853 res = UEXTSHORT ((UEXTSHORT (ea) * UEXTSHORT (rd)));
3854
3855 /* Don't set Z or N. */
3856 if (store (sd, &code->dst, res))
3857 goto end;
bf174226 3858
bf174226
V
3859 goto next;
3860
dc5c3759
MS
3861 case O (O_MULU, SL): /* mulu.l */
3862 if (fetch (sd, &code->src, &ea) ||
3863 fetch (sd, &code->dst, &rd))
3864 goto end;
bf174226 3865
dc5c3759 3866 res = ea * rd;
bf174226 3867
dc5c3759
MS
3868 /* Don't set Z or N. */
3869 if (store (sd, &code->dst, res))
3870 goto end;
bf174226 3871
dc5c3759 3872 goto next;
bf174226 3873
dc5c3759
MS
3874 case O (O_MULUU, SL): /* mulu/u.l */
3875 if (fetch (sd, &code->src, &ea) ||
3876 fetch (sd, &code->dst, &rd))
3877 goto end;
bf174226 3878
dc5c3759
MS
3879 /* Compute upper 32 bits of the 64-bit result. */
3880 res = (((unsigned long long) (unsigned) ea) *
3881 ((unsigned long long) (unsigned) rd)) >> 32;
bf174226 3882
dc5c3759
MS
3883 /* Don't set Z or N. */
3884 if (store (sd, &code->dst, res))
3885 goto end;
bf174226 3886
dc5c3759 3887 goto next;
bf174226 3888
dc5c3759
MS
3889 case O (O_MULXS, SB): /* mulxs.b */
3890 if (fetch (sd, &code->src, &ea) ||
3891 fetch (sd, &code->dst, &rd))
3892 goto end;
bf174226 3893
e073c474 3894 ea = SEXTCHAR (ea);
dc5c3759
MS
3895 res = ea * SEXTCHAR (rd);
3896
3897 n = res & 0x8000;
3898 nz = res & 0xffff;
3899 if (store (sd, &code->dst, res))
3900 goto end;
bf174226 3901
bf174226 3902 goto next;
bf174226 3903
dc5c3759
MS
3904 case O (O_MULXS, SW): /* mulxs.w */
3905 if (fetch (sd, &code->src, &ea) ||
3906 fetch (sd, &code->dst, &rd))
c906108c
SS
3907 goto end;
3908
e073c474 3909 ea = SEXTSHORT (ea);
dc5c3759 3910 res = ea * SEXTSHORT (rd & 0xffff);
c906108c 3911
dc5c3759
MS
3912 n = res & 0x80000000;
3913 nz = res & 0xffffffff;
3914 if (store (sd, &code->dst, res))
3915 goto end;
3916
3917 goto next;
c906108c 3918
dc5c3759
MS
3919 case O (O_MULXU, SB): /* mulxu.b */
3920 if (fetch (sd, &code->src, &ea) ||
3921 fetch (sd, &code->dst, &rd))
c906108c 3922 goto end;
c906108c 3923
dc5c3759 3924 res = UEXTCHAR (ea) * UEXTCHAR (rd);
c906108c 3925
dc5c3759
MS
3926 if (store (sd, &code->dst, res))
3927 goto end;
c906108c 3928
dc5c3759 3929 goto next;
c906108c 3930
dc5c3759
MS
3931 case O (O_MULXU, SW): /* mulxu.w */
3932 if (fetch (sd, &code->src, &ea) ||
3933 fetch (sd, &code->dst, &rd))
c906108c 3934 goto end;
c906108c 3935
dc5c3759 3936 res = UEXTSHORT (ea) * UEXTSHORT (rd);
c906108c 3937
dc5c3759
MS
3938 if (store (sd, &code->dst, res))
3939 goto end;
3940
3941 goto next;
c906108c 3942
9f70f8ec
MS
3943 case O (O_TAS, SB): /* tas (test and set) */
3944 if (!h8300sxmode) /* h8sx can use any register. */
3945 switch (code->src.reg)
3946 {
3947 case R0_REGNUM:
3948 case R1_REGNUM:
3949 case R4_REGNUM:
3950 case R5_REGNUM:
3951 break;
3952 default:
3953 goto illegal;
3954 }
3955
dc5c3759
MS
3956 if (fetch (sd, &code->src, &res))
3957 goto end;
3958 if (store (sd, &code->src, res | 0x80))
3959 goto end;
3960
6147b1f6 3961 goto just_flags_log8;
c906108c 3962
dc5c3759
MS
3963 case O (O_DIVU, SW): /* divu.w */
3964 if (fetch (sd, &code->src, &ea) ||
3965 fetch (sd, &code->dst, &rd))
3966 goto end;
c906108c 3967
dc5c3759
MS
3968 n = ea & 0x8000;
3969 nz = ea & 0xffff;
3970 if (ea)
3971 res = (unsigned) (UEXTSHORT (rd) / UEXTSHORT (ea));
3972 else
3973 res = 0;
c906108c 3974
dc5c3759
MS
3975 if (store (sd, &code->dst, res))
3976 goto end;
3977 goto next;
c906108c 3978
dc5c3759
MS
3979 case O (O_DIVU, SL): /* divu.l */
3980 if (fetch (sd, &code->src, &ea) ||
3981 fetch (sd, &code->dst, &rd))
3982 goto end;
3983
3984 n = ea & 0x80000000;
3985 nz = ea & 0xffffffff;
3986 if (ea)
3987 res = (unsigned) rd / ea;
3988 else
3989 res = 0;
3990
3991 if (store (sd, &code->dst, res))
3992 goto end;
3993 goto next;
3994
3995 case O (O_DIVS, SW): /* divs.w */
3996 if (fetch (sd, &code->src, &ea) ||
3997 fetch (sd, &code->dst, &rd))
3998 goto end;
3999
dc5c3759
MS
4000 if (ea)
4001 {
4002 res = SEXTSHORT (rd) / SEXTSHORT (ea);
4003 nz = 1;
4004 }
4005 else
4006 {
4007 res = 0;
4008 nz = 0;
4009 }
4010
4011 n = res & 0x8000;
4012 if (store (sd, &code->dst, res))
4013 goto end;
4014 goto next;
4015
4016 case O (O_DIVS, SL): /* divs.l */
4017 if (fetch (sd, &code->src, &ea) ||
4018 fetch (sd, &code->dst, &rd))
4019 goto end;
4020
dc5c3759
MS
4021 if (ea)
4022 {
4023 res = rd / ea;
4024 nz = 1;
4025 }
4026 else
4027 {
4028 res = 0;
4029 nz = 0;
4030 }
4031
4032 n = res & 0x80000000;
4033 if (store (sd, &code->dst, res))
4034 goto end;
4035 goto next;
4036
4037 case O (O_DIVXU, SB): /* divxu.b */
4038 if (fetch (sd, &code->src, &ea) ||
4039 fetch (sd, &code->dst, &rd))
4040 goto end;
4041
4042 rd = UEXTSHORT (rd);
4043 ea = UEXTCHAR (ea);
4044
4045 n = ea & 0x80;
4046 nz = ea & 0xff;
4047 if (ea)
4048 {
4049 tmp = (unsigned) rd % ea;
4050 res = (unsigned) rd / ea;
4051 }
4052 else
4053 {
4054 tmp = 0;
4055 res = 0;
4056 }
4057
9f70f8ec 4058 if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
dc5c3759
MS
4059 goto end;
4060 goto next;
4061
4062 case O (O_DIVXU, SW): /* divxu.w */
4063 if (fetch (sd, &code->src, &ea) ||
4064 fetch (sd, &code->dst, &rd))
4065 goto end;
4066
4067 ea = UEXTSHORT (ea);
4068
4069 n = ea & 0x8000;
4070 nz = ea & 0xffff;
4071 if (ea)
4072 {
4073 tmp = (unsigned) rd % ea;
4074 res = (unsigned) rd / ea;
4075 }
4076 else
4077 {
4078 tmp = 0;
4079 res = 0;
4080 }
4081
4082 if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
4083 goto end;
4084 goto next;
4085
4086 case O (O_DIVXS, SB): /* divxs.b */
4087 if (fetch (sd, &code->src, &ea) ||
4088 fetch (sd, &code->dst, &rd))
4089 goto end;
4090
4091 rd = SEXTSHORT (rd);
e073c474 4092 ea = SEXTCHAR (ea);
dc5c3759
MS
4093
4094 if (ea)
4095 {
4096 tmp = (int) rd % (int) ea;
4097 res = (int) rd / (int) ea;
4098 nz = 1;
4099 }
4100 else
4101 {
4102 tmp = 0;
4103 res = 0;
4104 nz = 0;
4105 }
4106
4107 n = res & 0x8000;
4108 if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
4109 goto end;
4110 goto next;
4111
4112 case O (O_DIVXS, SW): /* divxs.w */
4113 if (fetch (sd, &code->src, &ea) ||
4114 fetch (sd, &code->dst, &rd))
4115 goto end;
4116
e073c474 4117 ea = SEXTSHORT (ea);
dc5c3759
MS
4118
4119 if (ea)
4120 {
4121 tmp = (int) rd % (int) ea;
4122 res = (int) rd / (int) ea;
4123 nz = 1;
4124 }
4125 else
4126 {
4127 tmp = 0;
4128 res = 0;
4129 nz = 0;
4130 }
4131
4132 n = res & 0x80000000;
4133 if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
4134 goto end;
4135 goto next;
4136
4137 case O (O_EXTS, SW): /* exts.w, signed extend */
4138 if (fetch2 (sd, &code->dst, &rd))
4139 goto end;
c906108c 4140 ea = rd & 0x80 ? -256 : 0;
dc5c3759 4141 res = (rd & 0xff) + ea;
c906108c 4142 goto log16;
dc5c3759
MS
4143
4144 case O (O_EXTS, SL): /* exts.l, signed extend */
4145 if (fetch2 (sd, &code->dst, &rd))
4146 goto end;
4147 if (code->src.type == X (OP_IMM, SL))
4148 {
4149 if (fetch (sd, &code->src, &ea))
4150 goto end;
4151
4152 if (ea == 2) /* exts.l #2, nn */
4153 {
4154 /* Sign-extend from 8-bit to 32-bit. */
4155 ea = rd & 0x80 ? -256 : 0;
4156 res = (rd & 0xff) + ea;
4157 goto log32;
4158 }
4159 }
4160 /* Sign-extend from 16-bit to 32-bit. */
c906108c 4161 ea = rd & 0x8000 ? -65536 : 0;
dc5c3759 4162 res = (rd & 0xffff) + ea;
c906108c 4163 goto log32;
dc5c3759
MS
4164
4165 case O (O_EXTU, SW): /* extu.w, unsigned extend */
4166 if (fetch2 (sd, &code->dst, &rd))
4167 goto end;
c906108c 4168 ea = 0;
dc5c3759 4169 res = (rd & 0xff) + ea;
c906108c 4170 goto log16;
dc5c3759
MS
4171
4172 case O (O_EXTU, SL): /* extu.l, unsigned extend */
4173 if (fetch2 (sd, &code->dst, &rd))
4174 goto end;
4175 if (code->src.type == X (OP_IMM, SL))
4176 {
4177 if (fetch (sd, &code->src, &ea))
4178 goto end;
4179
4180 if (ea == 2) /* extu.l #2, nn */
4181 {
4182 /* Zero-extend from 8-bit to 32-bit. */
4183 ea = 0;
4184 res = (rd & 0xff) + ea;
4185 goto log32;
4186 }
4187 }
4188 /* Zero-extend from 16-bit to 32-bit. */
c906108c 4189 ea = 0;
dc5c3759 4190 res = (rd & 0xffff) + ea;
c906108c
SS
4191 goto log32;
4192
dc5c3759 4193 case O (O_NOP, SN): /* nop */
c906108c
SS
4194 goto next;
4195
dc5c3759 4196 case O (O_STM, SL): /* stm, store to memory */
c906108c
SS
4197 {
4198 int nregs, firstreg, i;
4199
4200 nregs = GET_MEMORY_B (pc + 1);
4201 nregs >>= 4;
4202 nregs &= 0xf;
dc5c3759 4203 firstreg = code->src.reg;
c906108c
SS
4204 firstreg &= 0xf;
4205 for (i = firstreg; i <= firstreg + nregs; i++)
4206 {
dc5c3759
MS
4207 h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) - 4);
4208 SET_MEMORY_L (h8_get_reg (sd, SP_REGNUM), h8_get_reg (sd, i));
c906108c
SS
4209 }
4210 }
4211 goto next;
4212
dc5c3759 4213 case O (O_LDM, SL): /* ldm, load from memory */
9f70f8ec
MS
4214 case O (O_RTEL, SN): /* rte/l, ldm plus rte */
4215 case O (O_RTSL, SN): /* rts/l, ldm plus rts */
c906108c
SS
4216 {
4217 int nregs, firstreg, i;
4218
9f70f8ec
MS
4219 nregs = ((GET_MEMORY_B (pc + 1) >> 4) & 0xf);
4220 firstreg = code->dst.reg & 0xf;
c906108c
SS
4221 for (i = firstreg; i >= firstreg - nregs; i--)
4222 {
dc5c3759
MS
4223 h8_set_reg (sd, i, GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM)));
4224 h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) + 4);
c906108c
SS
4225 }
4226 }
9f70f8ec
MS
4227 switch (code->opcode) {
4228 case O (O_RTEL, SN):
4229 goto rte;
4230 case O (O_RTSL, SN):
4231 goto rts;
4232 case O (O_LDM, SL):
4233 goto next;
4234 default:
4235 goto illegal;
4236 }
c906108c 4237
b7f97e9c
MS
4238 case O (O_DAA, SB):
4239 /* Decimal Adjust Addition. This is for BCD arithmetic. */
9f70f8ec 4240 res = GET_B_REG (code->src.reg); /* FIXME fetch? */
dc5c3759
MS
4241 if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4242 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
b7f97e9c 4243 res = res; /* Value added == 0. */
dc5c3759
MS
4244 else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8) &&
4245 !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
b7f97e9c 4246 res = res + 0x6; /* Value added == 6. */
dc5c3759
MS
4247 else if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4248 h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
b7f97e9c 4249 res = res + 0x6; /* Value added == 6. */
dc5c3759
MS
4250 else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15) &&
4251 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
4252 res = res + 0x60; /* Value added == 60. */
4253 else if (!c && (9 <= (res >> 4) && (res >> 4) <= 15) &&
4254 !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
4255 res = res + 0x66; /* Value added == 66. */
4256 else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15) &&
4257 h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
4258 res = res + 0x66; /* Value added == 66. */
4259 else if ( c && (1 <= (res >> 4) && (res >> 4) <= 2) &&
4260 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
b7f97e9c 4261 res = res + 0x60; /* Value added == 60. */
dc5c3759
MS
4262 else if ( c && (1 <= (res >> 4) && (res >> 4) <= 2) &&
4263 !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
b7f97e9c 4264 res = res + 0x66; /* Value added == 66. */
dc5c3759
MS
4265 else if (c && (1 <= (res >> 4) && (res >> 4) <= 3) &&
4266 h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
b7f97e9c 4267 res = res + 0x66; /* Value added == 66. */
b7f97e9c
MS
4268
4269 goto alu8;
4270
4271 case O (O_DAS, SB):
4272 /* Decimal Adjust Subtraction. This is for BCD arithmetic. */
4273 res = GET_B_REG (code->src.reg); /* FIXME fetch, fetch2... */
dc5c3759
MS
4274 if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4275 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
b7f97e9c 4276 res = res; /* Value added == 0. */
dc5c3759
MS
4277 else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8) &&
4278 h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
b7f97e9c 4279 res = res + 0xfa; /* Value added == 0xfa. */
dc5c3759
MS
4280 else if ( c && (7 <= (res >> 4) && (res >> 4) <= 15) &&
4281 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
b7f97e9c 4282 res = res + 0xa0; /* Value added == 0xa0. */
dc5c3759
MS
4283 else if (c && (6 <= (res >> 4) && (res >> 4) <= 15) &&
4284 h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
b7f97e9c
MS
4285 res = res + 0x9a; /* Value added == 0x9a. */
4286
4287 goto alu8;
4288
c906108c 4289 default:
d0fe2f7e 4290 illegal:
4ca9d09e 4291 sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL);
c906108c
SS
4292 goto end;
4293
4294 }
dc5c3759 4295
c1fc4b4d 4296 sim_io_printf (sd, "sim_resume: internal error.\n");
4ca9d09e 4297 sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL);
dc5c3759 4298 goto end;
c906108c
SS
4299
4300 setc:
dc5c3759
MS
4301 if (code->dst.type == X (OP_CCR, SB) ||
4302 code->dst.type == X (OP_CCR, SW))
c3f4437e 4303 {
dc5c3759 4304 h8_set_ccr (sd, res);
9f70f8ec 4305 GETSR (sd);
c3f4437e 4306 }
dc5c3759
MS
4307 else if (h8300smode &&
4308 (code->dst.type == X (OP_EXR, SB) ||
4309 code->dst.type == X (OP_EXR, SW)))
c3f4437e 4310 {
dc5c3759
MS
4311 h8_set_exr (sd, res);
4312 if (h8300smode) /* Get exr. */
4313 {
4314 trace = (h8_get_exr (sd) >> 7) & 1;
4315 intMask = h8_get_exr (sd) & 7;
4316 }
c3f4437e 4317 }
fc974602 4318 else
c3f4437e 4319 goto illegal;
fc974602 4320
c906108c
SS
4321 goto next;
4322
4323 condtrue:
4324 /* When a branch works */
dc5c3759
MS
4325 if (fetch (sd, &code->src, &res))
4326 goto end;
4327 if (res & 1) /* bad address */
4328 goto illegal;
4329 pc = code->next_pc + res;
c906108c
SS
4330 goto end;
4331
4332 /* Set the cond codes from res */
4333 bitop:
4334
4335 /* Set the flags after an 8 bit inc/dec operation */
4336 just_flags_inc8:
4337 n = res & 0x80;
4338 nz = res & 0xff;
4339 v = (rd & 0x7f) == 0x7f;
4340 goto next;
4341
c906108c
SS
4342 /* Set the flags after an 16 bit inc/dec operation */
4343 just_flags_inc16:
4344 n = res & 0x8000;
4345 nz = res & 0xffff;
4346 v = (rd & 0x7fff) == 0x7fff;
4347 goto next;
4348
c906108c
SS
4349 /* Set the flags after an 32 bit inc/dec operation */
4350 just_flags_inc32:
4351 n = res & 0x80000000;
4352 nz = res & 0xffffffff;
4353 v = (rd & 0x7fffffff) == 0x7fffffff;
4354 goto next;
4355
c906108c
SS
4356 shift8:
4357 /* Set flags after an 8 bit shift op, carry,overflow set in insn */
4358 n = (rd & 0x80);
4359 nz = rd & 0xff;
dc5c3759
MS
4360 if (store2 (sd, &code->dst, rd))
4361 goto end;
c906108c
SS
4362 goto next;
4363
4364 shift16:
4365 /* Set flags after an 16 bit shift op, carry,overflow set in insn */
4366 n = (rd & 0x8000);
4367 nz = rd & 0xffff;
dc5c3759
MS
4368 if (store2 (sd, &code->dst, rd))
4369 goto end;
c906108c
SS
4370 goto next;
4371
4372 shift32:
4373 /* Set flags after an 32 bit shift op, carry,overflow set in insn */
4374 n = (rd & 0x80000000);
4375 nz = rd & 0xffffffff;
dc5c3759
MS
4376 if (store2 (sd, &code->dst, rd))
4377 goto end;
c906108c
SS
4378 goto next;
4379
4380 log32:
dc5c3759
MS
4381 if (store2 (sd, &code->dst, res))
4382 goto end;
4383
c906108c
SS
4384 just_flags_log32:
4385 /* flags after a 32bit logical operation */
4386 n = res & 0x80000000;
4387 nz = res & 0xffffffff;
4388 v = 0;
4389 goto next;
4390
4391 log16:
dc5c3759
MS
4392 if (store2 (sd, &code->dst, res))
4393 goto end;
4394
c906108c
SS
4395 just_flags_log16:
4396 /* flags after a 16bit logical operation */
4397 n = res & 0x8000;
4398 nz = res & 0xffff;
4399 v = 0;
4400 goto next;
4401
c906108c 4402 log8:
dc5c3759
MS
4403 if (store2 (sd, &code->dst, res))
4404 goto end;
4405
c906108c
SS
4406 just_flags_log8:
4407 n = res & 0x80;
4408 nz = res & 0xff;
4409 v = 0;
4410 goto next;
4411
4412 alu8:
dc5c3759
MS
4413 if (store2 (sd, &code->dst, res))
4414 goto end;
4415
c906108c
SS
4416 just_flags_alu8:
4417 n = res & 0x80;
4418 nz = res & 0xff;
4419 c = (res & 0x100);
4420 switch (code->opcode / 4)
4421 {
4422 case O_ADD:
dc5c3759 4423 case O_ADDX:
c906108c
SS
4424 v = ((rd & 0x80) == (ea & 0x80)
4425 && (rd & 0x80) != (res & 0x80));
4426 break;
4427 case O_SUB:
dc5c3759 4428 case O_SUBX:
c906108c
SS
4429 case O_CMP:
4430 v = ((rd & 0x80) != (-ea & 0x80)
4431 && (rd & 0x80) != (res & 0x80));
4432 break;
4433 case O_NEG:
4434 v = (rd == 0x80);
4435 break;
dc5c3759
MS
4436 case O_DAA:
4437 case O_DAS:
4438 break; /* No effect on v flag. */
c906108c
SS
4439 }
4440 goto next;
4441
4442 alu16:
dc5c3759
MS
4443 if (store2 (sd, &code->dst, res))
4444 goto end;
4445
c906108c
SS
4446 just_flags_alu16:
4447 n = res & 0x8000;
4448 nz = res & 0xffff;
4449 c = (res & 0x10000);
4450 switch (code->opcode / 4)
4451 {
4452 case O_ADD:
dc5c3759 4453 case O_ADDX:
c906108c
SS
4454 v = ((rd & 0x8000) == (ea & 0x8000)
4455 && (rd & 0x8000) != (res & 0x8000));
4456 break;
4457 case O_SUB:
dc5c3759 4458 case O_SUBX:
c906108c
SS
4459 case O_CMP:
4460 v = ((rd & 0x8000) != (-ea & 0x8000)
4461 && (rd & 0x8000) != (res & 0x8000));
4462 break;
4463 case O_NEG:
4464 v = (rd == 0x8000);
4465 break;
4466 }
4467 goto next;
4468
4469 alu32:
dc5c3759
MS
4470 if (store2 (sd, &code->dst, res))
4471 goto end;
4472
c906108c
SS
4473 just_flags_alu32:
4474 n = res & 0x80000000;
4475 nz = res & 0xffffffff;
4476 switch (code->opcode / 4)
4477 {
4478 case O_ADD:
dc5c3759 4479 case O_ADDX:
c906108c
SS
4480 v = ((rd & 0x80000000) == (ea & 0x80000000)
4481 && (rd & 0x80000000) != (res & 0x80000000));
dc5c3759
MS
4482 c = ((unsigned) res < (unsigned) rd) ||
4483 ((unsigned) res < (unsigned) ea);
c906108c
SS
4484 break;
4485 case O_SUB:
dc5c3759 4486 case O_SUBX:
c906108c
SS
4487 case O_CMP:
4488 v = ((rd & 0x80000000) != (-ea & 0x80000000)
4489 && (rd & 0x80000000) != (res & 0x80000000));
4490 c = (unsigned) rd < (unsigned) -ea;
4491 break;
4492 case O_NEG:
4493 v = (rd == 0x80000000);
4494 c = res != 0;
4495 break;
4496 }
4497 goto next;
4498
dc5c3759
MS
4499 next:
4500 if ((res = h8_get_delayed_branch (sd)) != 0)
4501 {
4502 pc = res;
4503 h8_set_delayed_branch (sd, 0);
4504 }
4505 else
4506 pc = code->next_pc;
c906108c 4507
4ca9d09e 4508 } while (0);
c906108c 4509
4ca9d09e 4510 end:
dc5c3759
MS
4511 h8_set_ticks (sd, h8_get_ticks (sd) + get_now () - tick_start);
4512 h8_set_cycles (sd, h8_get_cycles (sd) + cycles);
4513 h8_set_insts (sd, h8_get_insts (sd) + insts);
4514 h8_set_pc (sd, pc);
4515 BUILDSR (sd);
4516
4517 if (h8300smode)
4518 h8_set_exr (sd, (trace<<7) | intMask);
4519
4520 h8_set_mask (sd, oldmask);
c906108c
SS
4521}
4522
4ca9d09e
MF
4523void
4524sim_engine_run (SIM_DESC sd,
4525 int next_cpu_nr, /* ignore */
4526 int nr_cpus, /* ignore */
4527 int siggnal)
4528{
4529 sim_cpu *cpu;
4530
4531 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
4532
4533 cpu = STATE_CPU (sd, 0);
4534
4535 while (1)
4536 {
4537 step_once (sd, cpu);
4538 if (sim_events_tick (sd))
4539 sim_events_process (sd);
4540 }
4541}
4542
c906108c 4543int
5558e7e6 4544sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
c906108c
SS
4545{
4546 int i;
4547
dc5c3759 4548 init_pointers (sd);
c906108c
SS
4549 if (addr < 0)
4550 return 0;
4551 for (i = 0; i < size; i++)
4552 {
4553 if (addr < memory_size)
4554 {
dc5c3759
MS
4555 h8_set_memory (sd, addr + i, buffer[i]);
4556 h8_set_cache_idx (sd, addr + i, 0);
c906108c
SS
4557 }
4558 else
dc5c3759
MS
4559 {
4560 h8_set_eightbit (sd, (addr + i) & 0xff, buffer[i]);
4561 }
c906108c
SS
4562 }
4563 return size;
4564}
4565
4566int
a4f27e3e 4567sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
c906108c 4568{
dc5c3759 4569 init_pointers (sd);
c906108c
SS
4570 if (addr < 0)
4571 return 0;
4572 if (addr < memory_size)
dc5c3759 4573 memcpy (buffer, h8_get_memory_buf (sd) + addr, size);
c906108c 4574 else
dc5c3759 4575 memcpy (buffer, h8_get_eightbit_buf (sd) + (addr & 0xff), size);
c906108c
SS
4576 return size;
4577}
4578
e1211e55
MF
4579static int
4580h8300_reg_store (SIM_CPU *cpu, int rn, unsigned char *value, int length)
c906108c
SS
4581{
4582 int longval;
4583 int shortval;
4584 int intval;
4585 longval = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
4586 shortval = (value[0] << 8) | (value[1]);
4587 intval = h8300hmode ? longval : shortval;
4588
2a2757ac 4589 init_pointers (CPU_STATE (cpu));
c906108c
SS
4590 switch (rn)
4591 {
9f70f8ec 4592 case PC_REGNUM:
59768597 4593 if(h8300_normal_mode)
2a2757ac 4594 cpu->pc = shortval; /* PC for Normal mode is 2 bytes */
59768597 4595 else
2a2757ac 4596 cpu->pc = intval;
9f70f8ec 4597 break;
c906108c 4598 default:
2a2757ac 4599 return -1;
c906108c
SS
4600 case R0_REGNUM:
4601 case R1_REGNUM:
4602 case R2_REGNUM:
4603 case R3_REGNUM:
4604 case R4_REGNUM:
4605 case R5_REGNUM:
4606 case R6_REGNUM:
4607 case R7_REGNUM:
c906108c 4608 case CCR_REGNUM:
fc974602 4609 case EXR_REGNUM:
173b1c98 4610 case SBR_REGNUM:
173b1c98 4611 case VBR_REGNUM:
173b1c98 4612 case MACH_REGNUM:
173b1c98 4613 case MACL_REGNUM:
2a2757ac 4614 cpu->regs[rn] = intval;
173b1c98 4615 break;
c906108c 4616 case CYCLE_REGNUM:
c906108c 4617 case INST_REGNUM:
c906108c 4618 case TICK_REGNUM:
2a2757ac 4619 cpu->regs[rn] = longval;
c906108c
SS
4620 break;
4621 }
dae477fe 4622 return length;
c906108c
SS
4623}
4624
e1211e55
MF
4625static int
4626h8300_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *buf, int length)
c906108c
SS
4627{
4628 int v;
4629 int longreg = 0;
4630
2a2757ac 4631 init_pointers (CPU_STATE (cpu));
c906108c 4632
d0fe2f7e 4633 if (!h8300smode && rn >= EXR_REGNUM)
c3f4437e 4634 rn++;
c906108c
SS
4635 switch (rn)
4636 {
4637 default:
2a2757ac
MF
4638 return -1;
4639 case PC_REGNUM:
4640 v = cpu->pc;
dc5c3759 4641 break;
3b02cf92 4642 case CCR_REGNUM:
fc974602 4643 case EXR_REGNUM:
173b1c98 4644 case SBR_REGNUM:
173b1c98 4645 case VBR_REGNUM:
173b1c98 4646 case MACH_REGNUM:
173b1c98 4647 case MACL_REGNUM:
c906108c
SS
4648 case R0_REGNUM:
4649 case R1_REGNUM:
4650 case R2_REGNUM:
4651 case R3_REGNUM:
4652 case R4_REGNUM:
4653 case R5_REGNUM:
4654 case R6_REGNUM:
4655 case R7_REGNUM:
2a2757ac 4656 v = cpu->regs[rn];
c906108c 4657 break;
3b02cf92 4658 case CYCLE_REGNUM:
3b02cf92 4659 case TICK_REGNUM:
3b02cf92 4660 case INST_REGNUM:
2a2757ac 4661 v = cpu->regs[rn];
c906108c
SS
4662 longreg = 1;
4663 break;
2a2757ac
MF
4664 case ZERO_REGNUM:
4665 v = 0;
4666 break;
c906108c 4667 }
59768597
SA
4668 /* In Normal mode PC is 2 byte, but other registers are 4 byte */
4669 if ((h8300hmode || longreg) && !(rn == PC_REGNUM && h8300_normal_mode))
c906108c
SS
4670 {
4671 buf[0] = v >> 24;
4672 buf[1] = v >> 16;
4673 buf[2] = v >> 8;
4674 buf[3] = v >> 0;
2a2757ac 4675 return 4;
c906108c
SS
4676 }
4677 else
4678 {
4679 buf[0] = v >> 8;
4680 buf[1] = v;
2a2757ac 4681 return 2;
c906108c 4682 }
c906108c
SS
4683}
4684
dc5c3759
MS
4685static void
4686set_simcache_size (SIM_DESC sd, int n)
c906108c 4687{
dc5c3759
MS
4688 if (sd->sim_cache)
4689 free (sd->sim_cache);
c906108c
SS
4690 if (n < 2)
4691 n = 2;
dc5c3759
MS
4692 sd->sim_cache = (decoded_inst *) malloc (sizeof (decoded_inst) * n);
4693 memset (sd->sim_cache, 0, sizeof (decoded_inst) * n);
4694 sd->sim_cache_size = n;
c906108c
SS
4695}
4696
4697
4698void
a4f27e3e 4699sim_info (SIM_DESC sd, int verbose)
c906108c 4700{
dc5c3759
MS
4701 double timetaken = (double) h8_get_ticks (sd) / (double) now_persec ();
4702 double virttime = h8_get_cycles (sd) / 10.0e6;
c906108c 4703
c1fc4b4d
MF
4704 sim_io_printf (sd, "\n\n#instructions executed %10d\n", h8_get_insts (sd));
4705 sim_io_printf (sd, "#cycles (v approximate) %10d\n", h8_get_cycles (sd));
4706 sim_io_printf (sd, "#real time taken %10.4f\n", timetaken);
4707 sim_io_printf (sd, "#virtual time taken %10.4f\n", virttime);
c906108c 4708 if (timetaken != 0.0)
c1fc4b4d
MF
4709 sim_io_printf (sd, "#simulation ratio %10.4f\n", virttime / timetaken);
4710 sim_io_printf (sd, "#compiles %10d\n", h8_get_compiles (sd));
4711 sim_io_printf (sd, "#cache size %10d\n", sd->sim_cache_size);
c906108c
SS
4712
4713#ifdef ADEBUG
4714 /* This to be conditional on `what' (aka `verbose'),
4715 however it was never passed as non-zero. */
4716 if (1)
4717 {
4718 int i;
4719 for (i = 0; i < O_LAST; i++)
4720 {
dc5c3759 4721 if (h8_get_stats (sd, i))
c1fc4b4d 4722 sim_io_printf (sd, "%d: %d\n", i, h8_get_stats (sd, i));
c906108c
SS
4723 }
4724 }
4725#endif
4726}
4727
2ea716f6
KH
4728/* Indicate whether the cpu is an H8/300 or H8/300H.
4729 FLAG is non-zero for the H8/300H. */
c906108c
SS
4730
4731void
27ebfdf4 4732set_h8300h (unsigned long machine)
c906108c
SS
4733{
4734 /* FIXME: Much of the code in sim_load can be moved to sim_open.
4735 This function being replaced by a sim_open:ARGV configuration
2ea716f6 4736 option. */
dc5c3759 4737
454d0511
DD
4738 h8300hmode = h8300smode = h8300sxmode = h8300_normal_mode = 0;
4739
9f70f8ec 4740 if (machine == bfd_mach_h8300sx || machine == bfd_mach_h8300sxn)
27ebfdf4
MS
4741 h8300sxmode = 1;
4742
4743 if (machine == bfd_mach_h8300s || machine == bfd_mach_h8300sn || h8300sxmode)
4744 h8300smode = 1;
4745
4746 if (machine == bfd_mach_h8300h || machine == bfd_mach_h8300hn || h8300smode)
4747 h8300hmode = 1;
59768597
SA
4748
4749 if(machine == bfd_mach_h8300hn || machine == bfd_mach_h8300sn || machine == bfd_mach_h8300sxn)
4750 h8300_normal_mode = 1;
dc5c3759
MS
4751}
4752
bd3fb5b8
MF
4753/* H8300-specific options.
4754 TODO: These really should be merged into the common model modules. */
4755typedef enum {
4756 OPTION_H8300H,
4757 OPTION_H8300S,
4758 OPTION_H8300SX
4759} H8300_OPTIONS;
4760
4761static SIM_RC
4762h8300_option_handler (SIM_DESC sd, sim_cpu *cpu ATTRIBUTE_UNUSED, int opt,
4763 char *arg, int is_command ATTRIBUTE_UNUSED)
4764{
4765 switch ((H8300_OPTIONS) opt)
4766 {
4767 case OPTION_H8300H:
4768 set_h8300h (bfd_mach_h8300h);
4769 break;
4770 case OPTION_H8300S:
4771 set_h8300h (bfd_mach_h8300s);
4772 break;
4773 case OPTION_H8300SX:
4774 set_h8300h (bfd_mach_h8300sx);
4775 break;
4776
4777 default:
4778 /* We'll actually never get here; the caller handles the error
4779 case. */
4780 sim_io_eprintf (sd, "Unknown option `%s'\n", arg);
4781 return SIM_RC_FAIL;
4782 }
4783
4784 return SIM_RC_OK;
4785}
4786
4787static const OPTION h8300_options[] =
4788{
4789 { {"h8300h", no_argument, NULL, OPTION_H8300H},
4790 'h', NULL, "Indicate the CPU is H8/300H",
4791 h8300_option_handler },
4792 { {"h8300s", no_argument, NULL, OPTION_H8300S},
4793 'S', NULL, "Indicate the CPU is H8S",
4794 h8300_option_handler },
4795 { {"h8300sx", no_argument, NULL, OPTION_H8300SX},
4796 'x', NULL, "Indicate the CPU is H8SX",
4797 h8300_option_handler },
4798 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
4799};
4800
27b97b40
MF
4801static sim_cia
4802h8300_pc_get (sim_cpu *cpu)
4803{
4804 return cpu->pc;
4805}
4806
4807static void
4808h8300_pc_set (sim_cpu *cpu, sim_cia pc)
4809{
4810 cpu->pc = pc;
4811}
4812
dc5c3759
MS
4813/* Cover function of sim_state_free to free the cpu buffers as well. */
4814
4815static void
4816free_state (SIM_DESC sd)
4817{
4818 if (STATE_MODULES (sd) != NULL)
4819 sim_module_uninstall (sd);
4820
4821 /* Fixme: free buffers in _sim_cpu. */
4822 sim_state_free (sd);
c906108c
SS
4823}
4824
4825SIM_DESC
a4f27e3e 4826sim_open (SIM_OPEN_KIND kind,
dc5c3759 4827 struct host_callback_struct *callback,
6b4a8935 4828 struct bfd *abfd,
2e3d4f4d 4829 char * const *argv)
c906108c 4830{
27b97b40 4831 int i;
dc5c3759
MS
4832 SIM_DESC sd;
4833 sim_cpu *cpu;
4834
4835 sd = sim_state_alloc (kind, callback);
f95f4ed2
MF
4836
4837 /* The cpu data is kept in a separately allocated chunk of memory. */
4838 if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
4839 {
4840 free_state (sd);
4841 return 0;
4842 }
4843
dc5c3759
MS
4844 cpu = STATE_CPU (sd, 0);
4845 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
cec99e6b 4846 cpu->regs[SBR_REGNUM] = 0xFFFFFF00;
dc5c3759
MS
4847 /* sim_cpu object is new, so some initialization is needed. */
4848 init_pointers_needed = 1;
4849
dc5c3759
MS
4850 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
4851 {
4852 free_state (sd);
4853 return 0;
4854 }
4855
bd3fb5b8
MF
4856 if (sim_add_option_table (sd, NULL, h8300_options) != SIM_RC_OK)
4857 {
4858 free_state (sd);
4859 return 0;
4860 }
4861
77cf2ef5 4862 /* The parser will print an error message for us, so we silently return. */
dc5c3759
MS
4863 if (sim_parse_args (sd, argv) != SIM_RC_OK)
4864 {
4865 /* Uninstall the modules to avoid memory leaks,
4866 file descriptor leaks, etc. */
4867 free_state (sd);
4868 return 0;
4869 }
4870
4871 /* Check for/establish the a reference program image. */
4872 if (sim_analyze_program (sd,
4873 (STATE_PROG_ARGV (sd) != NULL
4874 ? *STATE_PROG_ARGV (sd)
4875 : NULL), abfd) != SIM_RC_OK)
4876 {
4877 free_state (sd);
4878 return 0;
4879 }
4880
4881 /* Establish any remaining configuration options. */
4882 if (sim_config (sd) != SIM_RC_OK)
4883 {
4884 free_state (sd);
4885 return 0;
4886 }
4887
4888 if (sim_post_argv_init (sd) != SIM_RC_OK)
4889 {
4890 /* Uninstall the modules to avoid memory leaks,
4891 file descriptor leaks, etc. */
4892 free_state (sd);
4893 return 0;
4894 }
4895
27b97b40
MF
4896 /* CPU specific initialization. */
4897 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
4898 {
4899 SIM_CPU *cpu = STATE_CPU (sd, i);
4900
e1211e55
MF
4901 CPU_REG_FETCH (cpu) = h8300_reg_fetch;
4902 CPU_REG_STORE (cpu) = h8300_reg_store;
27b97b40
MF
4903 CPU_PC_FETCH (cpu) = h8300_pc_get;
4904 CPU_PC_STORE (cpu) = h8300_pc_set;
4905 }
4906
dc5c3759
MS
4907 /* sim_hw_configure (sd); */
4908
2ea716f6 4909 /* FIXME: Much of the code in sim_load can be moved here. */
c906108c 4910
dc5c3759 4911 return sd;
c906108c
SS
4912}
4913
c906108c
SS
4914/* Called by gdb to load a program into memory. */
4915
4916SIM_RC
b2b255bd 4917sim_load (SIM_DESC sd, const char *prog, bfd *abfd, int from_tty)
c906108c
SS
4918{
4919 bfd *prog_bfd;
4920
2ea716f6
KH
4921 /* FIXME: The code below that sets a specific variant of the H8/300
4922 being simulated should be moved to sim_open(). */
c906108c 4923
2ea716f6 4924 /* See if the file is for the H8/300 or H8/300H. */
c906108c
SS
4925 /* ??? This may not be the most efficient way. The z8k simulator
4926 does this via a different mechanism (INIT_EXTRA_SYMTAB_INFO). */
4927 if (abfd != NULL)
4928 prog_bfd = abfd;
4929 else
3d29fdb4 4930 prog_bfd = bfd_openr (prog, NULL);
c906108c
SS
4931 if (prog_bfd != NULL)
4932 {
4933 /* Set the cpu type. We ignore failure from bfd_check_format
4934 and bfd_openr as sim_load_file checks too. */
de9b1892 4935 if (bfd_check_format (prog_bfd, bfd_object))
c906108c 4936 {
27ebfdf4 4937 set_h8300h (bfd_get_mach (prog_bfd));
c906108c
SS
4938 }
4939 }
4940
4941 /* If we're using gdb attached to the simulator, then we have to
4942 reallocate memory for the simulator.
4943
4944 When gdb first starts, it calls fetch_registers (among other
4945 functions), which in turn calls init_pointers, which allocates
4946 simulator memory.
4947
4948 The problem is when we do that, we don't know whether we're
2ea716f6 4949 debugging an H8/300 or H8/300H program.
c906108c
SS
4950
4951 This is the first point at which we can make that determination,
4952 so we just reallocate memory now; this will also allow us to handle
2ea716f6 4953 switching between H8/300 and H8/300H programs without exiting
c906108c 4954 gdb. */
a8cdafbd 4955
59768597 4956 if (h8300smode && !h8300_normal_mode)
a8cdafbd 4957 memory_size = H8300S_MSIZE;
59768597 4958 else if (h8300hmode && !h8300_normal_mode)
c906108c
SS
4959 memory_size = H8300H_MSIZE;
4960 else
4961 memory_size = H8300_MSIZE;
4962
dc5c3759
MS
4963 if (h8_get_memory_buf (sd))
4964 free (h8_get_memory_buf (sd));
4965 if (h8_get_cache_idx_buf (sd))
4966 free (h8_get_cache_idx_buf (sd));
4967 if (h8_get_eightbit_buf (sd))
4968 free (h8_get_eightbit_buf (sd));
c906108c 4969
dc5c3759
MS
4970 h8_set_memory_buf (sd, (unsigned char *)
4971 calloc (sizeof (char), memory_size));
4972 h8_set_cache_idx_buf (sd, (unsigned short *)
4973 calloc (sizeof (short), memory_size));
e4d3c499 4974 sd->memory_size = memory_size;
dc5c3759 4975 h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256));
c906108c 4976
2ea716f6 4977 /* `msize' must be a power of two. */
c906108c 4978 if ((memory_size & (memory_size - 1)) != 0)
dc5c3759 4979 {
c1fc4b4d 4980 sim_io_printf (sd, "sim_load: bad memory size.\n");
dc5c3759
MS
4981 return SIM_RC_FAIL;
4982 }
4983 h8_set_mask (sd, memory_size - 1);
c906108c 4984
c1fc4b4d
MF
4985 if (sim_load_file (sd, STATE_MY_NAME (sd), STATE_CALLBACK (sd), prog,
4986 prog_bfd, STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG,
c906108c
SS
4987 0, sim_write)
4988 == NULL)
4989 {
4990 /* Close the bfd if we opened it. */
4991 if (abfd == NULL && prog_bfd != NULL)
4992 bfd_close (prog_bfd);
4993 return SIM_RC_FAIL;
4994 }
4995
4996 /* Close the bfd if we opened it. */
4997 if (abfd == NULL && prog_bfd != NULL)
4998 bfd_close (prog_bfd);
4999 return SIM_RC_OK;
5000}
5001
5002SIM_RC
2e3d4f4d
MF
5003sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
5004 char * const *argv, char * const *env)
c906108c 5005{
d1360fb0
V
5006 int i = 0;
5007 int len_arg = 0;
5008 int no_of_args = 0;
dc5c3759 5009
c906108c 5010 if (abfd != NULL)
dc5c3759 5011 h8_set_pc (sd, bfd_get_start_address (abfd));
c906108c 5012 else
dc5c3759 5013 h8_set_pc (sd, 0);
d1360fb0
V
5014
5015 /* Command Line support. */
5016 if (argv != NULL)
5017 {
5018 /* Counting the no. of commandline arguments. */
5019 for (no_of_args = 0; argv[no_of_args] != NULL; no_of_args++)
5020 continue;
5021
5022 /* Allocating memory for the argv pointers. */
dc5c3759
MS
5023 h8_set_command_line (sd, (char **) malloc ((sizeof (char *))
5024 * (no_of_args + 1)));
d1360fb0
V
5025
5026 for (i = 0; i < no_of_args; i++)
5027 {
d1360fb0 5028 /* Copying the argument string. */
dc5c3759 5029 h8_set_cmdline_arg (sd, i, (char *) strdup (argv[i]));
d1360fb0 5030 }
dc5c3759 5031 h8_set_cmdline_arg (sd, i, NULL);
d1360fb0
V
5032 }
5033
c906108c
SS
5034 return SIM_RC_OK;
5035}