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