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