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