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