]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/h8300/compile.c
sim: mn10300: drop global callback handle
[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
dc5c3759
MS
1753/* Flag to be set whenever a new SIM_DESC object is created. */
1754static int init_pointers_needed = 1;
1755
1756static void
1757init_pointers (SIM_DESC sd)
1758{
1759 if (init_pointers_needed)
1760 {
1761 int i;
1762
59768597 1763 if (h8300smode && !h8300_normal_mode)
dc5c3759 1764 memory_size = H8300S_MSIZE;
59768597 1765 else if (h8300hmode && !h8300_normal_mode)
dc5c3759
MS
1766 memory_size = H8300H_MSIZE;
1767 else
1768 memory_size = H8300_MSIZE;
1769 /* `msize' must be a power of two. */
1770 if ((memory_size & (memory_size - 1)) != 0)
1771 {
1772 (*sim_callback->printf_filtered)
1773 (sim_callback,
1774 "init_pointers: bad memory size %d, defaulting to %d.\n",
1775 memory_size, memory_size = H8300S_MSIZE);
1776 }
1777
1778 if (h8_get_memory_buf (sd))
1779 free (h8_get_memory_buf (sd));
1780 if (h8_get_cache_idx_buf (sd))
1781 free (h8_get_cache_idx_buf (sd));
1782 if (h8_get_eightbit_buf (sd))
1783 free (h8_get_eightbit_buf (sd));
1784
1785 h8_set_memory_buf (sd, (unsigned char *)
1786 calloc (sizeof (char), memory_size));
1787 h8_set_cache_idx_buf (sd, (unsigned short *)
1788 calloc (sizeof (short), memory_size));
1789 sd->memory_size = memory_size;
1790 h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256));
1791
1792 h8_set_mask (sd, memory_size - 1);
1793
1794 memset (h8_get_reg_buf (sd), 0, sizeof (((STATE_CPU (sd, 0))->regs)));
1795
1796 for (i = 0; i < 8; i++)
1797 {
1798 /* FIXME: rewrite using local buffer. */
1799 unsigned char *p = (unsigned char *) (h8_get_reg_buf (sd) + i);
1800 unsigned char *e = (unsigned char *) (h8_get_reg_buf (sd) + i + 1);
1801 unsigned short *q = (unsigned short *) (h8_get_reg_buf (sd) + i);
1802 unsigned short *u = (unsigned short *) (h8_get_reg_buf (sd) + i + 1);
1803 h8_set_reg (sd, i, 0x00112233);
1804
1805 while (p < e)
1806 {
1807 if (*p == 0x22)
1808 breg[i] = p;
1809 if (*p == 0x33)
1810 breg[i + 8] = p;
1811 if (*p == 0x11)
1812 breg[i + 16] = p;
1813 if (*p == 0x00)
1814 breg[i + 24] = p;
1815 p++;
1816 }
1817
1818 wreg[i] = wreg[i + 8] = 0;
1819 while (q < u)
1820 {
1821 if (*q == 0x2233)
1822 {
1823 wreg[i] = q;
1824 }
1825 if (*q == 0x0011)
1826 {
1827 wreg[i + 8] = q;
1828 }
1829 q++;
1830 }
1831
1832 if (wreg[i] == 0 || wreg[i + 8] == 0)
1833 (*sim_callback->printf_filtered) (sim_callback,
1834 "init_pointers: internal error.\n");
1835
1836 h8_set_reg (sd, i, 0);
1837 lreg[i] = h8_get_reg_buf (sd) + i;
1838 }
1839
1840 /* Note: sim uses pseudo-register ZERO as a zero register. */
1841 lreg[ZERO_REGNUM] = h8_get_reg_buf (sd) + ZERO_REGNUM;
1842 init_pointers_needed = 0;
1843
1844 /* Initialize the seg registers. */
1845 if (!sd->sim_cache)
1846 set_simcache_size (sd, CSIZE);
1847 }
1848}
1849
dc5c3759
MS
1850#define OBITOP(name, f, s, op) \
1851case O (name, SB): \
1852{ \
1853 int m, tmp; \
1854 \
1855 if (f) \
1856 if (fetch (sd, &code->dst, &ea)) \
1857 goto end; \
1858 if (fetch (sd, &code->src, &tmp)) \
1859 goto end; \
b86015ea 1860 m = 1 << (tmp & 7); \
dc5c3759
MS
1861 op; \
1862 if (s) \
1863 if (store (sd, &code->dst,ea)) \
1864 goto end; \
1865 goto next; \
1866}
1867
1868void
1869sim_resume (SIM_DESC sd, int step, int siggnal)
1870{
1871 static int init1;
1872 int cycles = 0;
1873 int insts = 0;
1874 int tick_start = get_now ();
dc5c3759
MS
1875 int poll_count = 0;
1876 int res;
1877 int tmp;
1878 int rd;
1879 int ea;
1880 int bit;
1881 int pc;
1882 int c, nz, v, n, u, h, ui, intMaskBit;
1883 int trace, intMask;
1884 int oldmask;
1885 enum sim_stop reason;
1886 int sigrc;
1887
1888 init_pointers (sd);
1889
dc5c3759
MS
1890 if (step)
1891 {
1892 sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
1893 }
1894 else
1895 {
1896 sim_engine_set_run_state (sd, sim_running, 0);
1897 }
1898
1899 pc = h8_get_pc (sd);
1900
1901 /* The PC should never be odd. */
1902 if (pc & 0x1)
1903 {
1904 sim_engine_set_run_state (sd, sim_stopped, SIGBUS);
1905 return;
1906 }
1907
1908 /* Get Status Register (flags). */
9f70f8ec 1909 GETSR (sd);
dc5c3759
MS
1910
1911 if (h8300smode) /* Get exr. */
1912 {
1913 trace = (h8_get_exr (sd) >> 7) & 1;
1914 intMask = h8_get_exr (sd) & 7;
1915 }
1916
1917 oldmask = h8_get_mask (sd);
59768597 1918 if (!h8300hmode || h8300_normal_mode)
dc5c3759
MS
1919 h8_set_mask (sd, 0xffff);
1920 do
1921 {
1922 unsigned short cidx;
1923 decoded_inst *code;
1924
1925 top:
1926 cidx = h8_get_cache_idx (sd, pc);
1927 if (cidx == (unsigned short) -1 ||
1928 cidx >= sd->sim_cache_size)
1929 goto illegal;
1930
1931 code = sd->sim_cache + cidx;
1932
1933#if ADEBUG
1934 if (debug)
1935 {
1936 printf ("%x %d %s\n", pc, code->opcode,
1937 code->op ? code->op->name : "**");
1938 }
1939 h8_increment_stats (sd, code->opcode);
1940#endif
1941
1942 if (code->opcode)
1943 {
1944 cycles += code->cycles;
1945 insts++;
1946 }
1947
1948 switch (code->opcode)
1949 {
1950 case 0:
1951 /*
1952 * This opcode is a fake for when we get to an
1953 * instruction which hasnt been compiled
1954 */
1955 compile (sd, pc);
1956 goto top;
1957 break;
1958
1959 case O (O_MOVAB, SL):
1960 case O (O_MOVAW, SL):
1961 case O (O_MOVAL, SL):
1962 /* 1) Evaluate 2nd argument (dst).
1963 2) Mask / zero extend according to whether 1st argument (src)
1964 is INDEXB, INDEXW, or INDEXL.
1965 3) Left-shift the result by 0, 1 or 2, according to size of mova
1966 (mova/b, mova/w, mova/l).
1967 4) Add literal value of 1st argument (src).
1968 5) Store result in 3rd argument (op3).
f408565c
MS
1969 */
1970
1971 /* Alas, since this is the only instruction with 3 arguments,
1972 decode doesn't handle them very well. Some fix-up is required.
1973
1974 a) The size of dst is determined by whether src is
1975 INDEXB or INDEXW. */
dc5c3759 1976
f408565c
MS
1977 if (OP_KIND (code->src.type) == OP_INDEXB)
1978 code->dst.type = X (OP_KIND (code->dst.type), SB);
1979 else if (OP_KIND (code->src.type) == OP_INDEXW)
1980 code->dst.type = X (OP_KIND (code->dst.type), SW);
1981
1982 /* b) If op3 == null, then this is the short form of the insn.
1983 Dst is the dispreg of src, and op3 is the 32-bit form
1984 of the same register.
dc5c3759 1985 */
f408565c
MS
1986
1987 if (code->op3.type == 0)
1988 {
1989 /* Short form: src == INDEXB/INDEXW, dst == op3 == 0.
1990 We get to compose dst and op3 as follows:
1991
1992 op3 is a 32-bit register, ID == src.reg.
1993 dst is the same register, but 8 or 16 bits
1994 depending on whether src is INDEXB or INDEXW.
1995 */
1996
1997 code->op3.type = X (OP_REG, SL);
1998 code->op3.reg = code->src.reg;
1999 code->op3.literal = 0;
2000
2001 if (OP_KIND (code->src.type) == OP_INDEXB)
e073c474
AO
2002 {
2003 code->dst.type = X (OP_REG, SB);
2004 code->dst.reg = code->op3.reg + 8;
2005 }
f408565c
MS
2006 else
2007 code->dst.type = X (OP_REG, SW);
2008 }
2009
dc5c3759
MS
2010 if (fetch (sd, &code->dst, &ea))
2011 goto end;
2012
2013 switch (OP_KIND (code->src.type)) {
2014 case OP_INDEXB: ea = ea & 0xff; break;
2015 case OP_INDEXW: ea = ea & 0xffff; break;
2016 case OP_INDEXL: break;
2017 default: goto illegal;
2018 }
2019
2020 switch (code->opcode) {
2021 case O (O_MOVAB, SL): break;
2022 case O (O_MOVAW, SL): ea = ea << 1; break;
2023 case O (O_MOVAL, SL): ea = ea << 2; break;
2024 default: goto illegal;
2025 }
2026
2027 ea = ea + code->src.literal;
2028
2029 if (store (sd, &code->op3, ea))
2030 goto end;
2031
2032 goto next;
2033
2034 case O (O_SUBX, SB): /* subx, extended sub */
2035 if (fetch2 (sd, &code->dst, &rd))
2036 goto end;
2037 if (fetch (sd, &code->src, &ea))
2038 goto end;
2039 ea = -(ea + C);
2040 res = rd + ea;
2041 goto alu8;
2042
2043 case O (O_SUBX, SW): /* subx, extended sub */
2044 if (fetch2 (sd, &code->dst, &rd))
2045 goto end;
2046 if (fetch (sd, &code->src, &ea))
2047 goto end;
2048 ea = -(ea + C);
2049 res = rd + ea;
2050 goto alu16;
2051
2052 case O (O_SUBX, SL): /* subx, extended sub */
2053 if (fetch2 (sd, &code->dst, &rd))
2054 goto end;
2055 if (fetch (sd, &code->src, &ea))
2056 goto end;
2057 ea = -(ea + C);
2058 res = rd + ea;
2059 goto alu32;
2060
2061 case O (O_ADDX, SB): /* addx, extended add */
2062 if (fetch2 (sd, &code->dst, &rd))
2063 goto end;
2064 if (fetch (sd, &code->src, &ea))
2065 goto end;
2066 ea = ea + C;
2067 res = rd + ea;
2068 goto alu8;
2069
2070 case O (O_ADDX, SW): /* addx, extended add */
2071 if (fetch2 (sd, &code->dst, &rd))
2072 goto end;
2073 if (fetch (sd, &code->src, &ea))
2074 goto end;
2075 ea = ea + C;
2076 res = rd + ea;
2077 goto alu16;
2078
2079 case O (O_ADDX, SL): /* addx, extended add */
2080 if (fetch2 (sd, &code->dst, &rd))
2081 goto end;
2082 if (fetch (sd, &code->src, &ea))
2083 goto end;
2084 ea = ea + C;
2085 res = rd + ea;
2086 goto alu32;
2087
2088 case O (O_SUB, SB): /* sub.b */
2089 /* Fetch rd and ea. */
2090 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2091 goto end;
2092 ea = -ea;
2093 res = rd + ea;
2094 goto alu8;
2095
2096 case O (O_SUB, SW): /* sub.w */
2097 /* Fetch rd and ea. */
2098 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2099 goto end;
2100 ea = -ea;
2101 res = rd + ea;
2102 goto alu16;
2103
2104 case O (O_SUB, SL): /* sub.l */
2105 /* Fetch rd and ea. */
2106 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2107 goto end;
2108 ea = -ea;
2109 res = rd + ea;
2110 goto alu32;
2111
2112 case O (O_NEG, SB): /* neg.b */
2113 /* Fetch ea. */
2114 if (fetch2 (sd, &code->src, &ea))
2115 goto end;
2116 ea = -ea;
2117 rd = 0;
2118 res = rd + ea;
2119 goto alu8;
2120
2121 case O (O_NEG, SW): /* neg.w */
2122 /* Fetch ea. */
2123 if (fetch2 (sd, &code->src, &ea))
2124 goto end;
2125 ea = -ea;
2126 rd = 0;
2127 res = rd + ea;
2128 goto alu16;
2129
2130 case O (O_NEG, SL): /* neg.l */
2131 /* Fetch ea. */
2132 if (fetch2 (sd, &code->src, &ea))
2133 goto end;
2134 ea = -ea;
2135 rd = 0;
2136 res = rd + ea;
2137 goto alu32;
2138
2139 case O (O_ADD, SB): /* add.b */
2140 if (fetch2 (sd, &code->dst, &rd))
2141 goto end;
2142 if (fetch (sd, &code->src, &ea))
2143 goto end;
2144 res = rd + ea;
2145 goto alu8;
2146
2147 case O (O_ADD, SW): /* add.w */
2148 if (fetch2 (sd, &code->dst, &rd))
2149 goto end;
2150 if (fetch (sd, &code->src, &ea))
2151 goto end;
2152 res = rd + ea;
2153 goto alu16;
2154
2155 case O (O_ADD, SL): /* add.l */
2156 if (fetch2 (sd, &code->dst, &rd))
2157 goto end;
2158 if (fetch (sd, &code->src, &ea))
2159 goto end;
2160 res = rd + ea;
2161 goto alu32;
2162
2163 case O (O_AND, SB): /* and.b */
2164 /* Fetch rd and ea. */
2165 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2166 goto end;
2167 res = rd & ea;
2168 goto log8;
2169
2170 case O (O_AND, SW): /* and.w */
2171 /* Fetch rd and ea. */
2172 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2173 goto end;
2174 res = rd & ea;
2175 goto log16;
2176
2177 case O (O_AND, SL): /* and.l */
2178 /* Fetch rd and ea. */
2179 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2180 goto end;
2181 res = rd & ea;
2182 goto log32;
2183
2184 case O (O_OR, SB): /* or.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_OR, SW): /* or.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_OR, SL): /* or.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_XOR, SB): /* xor.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_XOR, SW): /* xor.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_XOR, SL): /* xor.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_MOV, SB):
2227 if (fetch (sd, &code->src, &res))
2228 goto end;
2229 if (store (sd, &code->dst, res))
2230 goto end;
2231 goto just_flags_log8;
2232 case O (O_MOV, SW):
2233 if (fetch (sd, &code->src, &res))
2234 goto end;
2235 if (store (sd, &code->dst, res))
2236 goto end;
2237 goto just_flags_log16;
2238 case O (O_MOV, SL):
2239 if (fetch (sd, &code->src, &res))
2240 goto end;
2241 if (store (sd, &code->dst, res))
2242 goto end;
2243 goto just_flags_log32;
2244
9f70f8ec 2245 case O (O_MOVMD, SB): /* movmd.b */
dc5c3759
MS
2246 ea = GET_W_REG (4);
2247 if (ea == 0)
2248 ea = 0x10000;
2249
2250 while (ea--)
2251 {
2252 rd = GET_MEMORY_B (GET_L_REG (5));
2253 SET_MEMORY_B (GET_L_REG (6), rd);
2254 SET_L_REG (5, GET_L_REG (5) + 1);
2255 SET_L_REG (6, GET_L_REG (6) + 1);
2256 SET_W_REG (4, ea);
2257 }
2258 goto next;
2259
9f70f8ec 2260 case O (O_MOVMD, SW): /* movmd.w */
dc5c3759
MS
2261 ea = GET_W_REG (4);
2262 if (ea == 0)
2263 ea = 0x10000;
2264
2265 while (ea--)
2266 {
2267 rd = GET_MEMORY_W (GET_L_REG (5));
2268 SET_MEMORY_W (GET_L_REG (6), rd);
2269 SET_L_REG (5, GET_L_REG (5) + 2);
2270 SET_L_REG (6, GET_L_REG (6) + 2);
2271 SET_W_REG (4, ea);
2272 }
2273 goto next;
2274
9f70f8ec 2275 case O (O_MOVMD, SL): /* movmd.l */
dc5c3759
MS
2276 ea = GET_W_REG (4);
2277 if (ea == 0)
2278 ea = 0x10000;
2279
2280 while (ea--)
2281 {
2282 rd = GET_MEMORY_L (GET_L_REG (5));
2283 SET_MEMORY_L (GET_L_REG (6), rd);
2284 SET_L_REG (5, GET_L_REG (5) + 4);
2285 SET_L_REG (6, GET_L_REG (6) + 4);
2286 SET_W_REG (4, ea);
2287 }
2288 goto next;
2289
2290 case O (O_MOVSD, SB): /* movsd.b */
2291 /* This instruction implements strncpy, with a conditional branch.
2292 r4 contains n, r5 contains src, and r6 contains dst.
2293 The 16-bit displacement operand is added to the pc
2294 if and only if the end of string is reached before
2295 n bytes are transferred. */
2296
2297 ea = GET_L_REG (4) & 0xffff;
2298 if (ea == 0)
2299 ea = 0x10000;
2300
2301 while (ea--)
2302 {
2303 rd = GET_MEMORY_B (GET_L_REG (5));
2304 SET_MEMORY_B (GET_L_REG (6), rd);
2305 SET_L_REG (5, GET_L_REG (5) + 1);
2306 SET_L_REG (6, GET_L_REG (6) + 1);
2307 SET_W_REG (4, ea);
2308 if (rd == 0)
2309 goto condtrue;
2310 }
2311 goto next;
2312
2313 case O (O_EEPMOV, SB): /* eepmov.b */
2314 case O (O_EEPMOV, SW): /* eepmov.w */
2315 if (h8300hmode || h8300smode)
2316 {
2317 register unsigned char *_src, *_dst;
2318 unsigned int count = ((code->opcode == O (O_EEPMOV, SW))
2319 ? h8_get_reg (sd, R4_REGNUM) & 0xffff
2320 : h8_get_reg (sd, R4_REGNUM) & 0xff);
2321
2322 _src = (h8_get_reg (sd, R5_REGNUM) < memory_size
2323 ? h8_get_memory_buf (sd) + h8_get_reg (sd, R5_REGNUM)
2324 : h8_get_eightbit_buf (sd) +
2325 (h8_get_reg (sd, R5_REGNUM) & 0xff));
2326 if ((_src + count) >= (h8_get_memory_buf (sd) + memory_size))
2327 {
2328 if ((_src + count) >= (h8_get_eightbit_buf (sd) + 0x100))
2329 goto illegal;
2330 }
2331 _dst = (h8_get_reg (sd, R6_REGNUM) < memory_size
2332 ? h8_get_memory_buf (sd) + h8_get_reg (sd, R6_REGNUM)
2333 : h8_get_eightbit_buf (sd) +
2334 (h8_get_reg (sd, R6_REGNUM) & 0xff));
2335
2336 if ((_dst + count) >= (h8_get_memory_buf (sd) + memory_size))
2337 {
2338 if ((_dst + count) >= (h8_get_eightbit_buf (sd) + 0x100))
2339 goto illegal;
2340 }
2341 memcpy (_dst, _src, count);
2342
2343 h8_set_reg (sd, R5_REGNUM, h8_get_reg (sd, R5_REGNUM) + count);
2344 h8_set_reg (sd, R6_REGNUM, h8_get_reg (sd, R6_REGNUM) + count);
2345 h8_set_reg (sd, R4_REGNUM, h8_get_reg (sd, R4_REGNUM) &
2346 ((code->opcode == O (O_EEPMOV, SW))
2347 ? (~0xffff) : (~0xff)));
2348 cycles += 2 * count;
2349 goto next;
2350 }
2351 goto illegal;
2352
2353 case O (O_ADDS, SL): /* adds (.l) */
2354 /* FIXME fetch.
2355 * This insn only uses register operands, but still
2356 * it would be cleaner to use fetch and store... */
2357 SET_L_REG (code->dst.reg,
2358 GET_L_REG (code->dst.reg)
2359 + code->src.literal);
2360
2361 goto next;
2362
2363 case O (O_SUBS, SL): /* subs (.l) */
2364 /* FIXME fetch.
2365 * This insn only uses register operands, but still
2366 * it would be cleaner to use fetch and store... */
2367 SET_L_REG (code->dst.reg,
2368 GET_L_REG (code->dst.reg)
2369 - code->src.literal);
2370 goto next;
2371
2372 case O (O_CMP, SB): /* cmp.b */
2373 if (fetch (sd, &code->dst, &rd))
2374 goto end;
2375 if (fetch (sd, &code->src, &ea))
2376 goto end;
2377 ea = -ea;
2378 res = rd + ea;
2379 goto just_flags_alu8;
2380
2381 case O (O_CMP, SW): /* cmp.w */
2382 if (fetch (sd, &code->dst, &rd))
2383 goto end;
2384 if (fetch (sd, &code->src, &ea))
2385 goto end;
2386 ea = -ea;
2387 res = rd + ea;
2388 goto just_flags_alu16;
2389
2390 case O (O_CMP, SL): /* cmp.l */
2391 if (fetch (sd, &code->dst, &rd))
2392 goto end;
2393 if (fetch (sd, &code->src, &ea))
2394 goto end;
2395 ea = -ea;
2396 res = rd + ea;
2397 goto just_flags_alu32;
2398
2399 case O (O_DEC, SB): /* dec.b */
2400 /* FIXME fetch.
2401 * This insn only uses register operands, but still
2402 * it would be cleaner to use fetch and store... */
2403 rd = GET_B_REG (code->src.reg);
2404 ea = -1;
2405 res = rd + ea;
2406 SET_B_REG (code->src.reg, res);
2407 goto just_flags_inc8;
2408
2409 case O (O_DEC, SW): /* dec.w */
2410 /* FIXME fetch.
2411 * This insn only uses register operands, but still
2412 * it would be cleaner to use fetch and store... */
2413 rd = GET_W_REG (code->dst.reg);
2414 ea = -code->src.literal;
2415 res = rd + ea;
2416 SET_W_REG (code->dst.reg, res);
2417 goto just_flags_inc16;
2418
2419 case O (O_DEC, SL): /* dec.l */
2420 /* FIXME fetch.
2421 * This insn only uses register operands, but still
2422 * it would be cleaner to use fetch and store... */
2423 rd = GET_L_REG (code->dst.reg);
2424 ea = -code->src.literal;
2425 res = rd + ea;
2426 SET_L_REG (code->dst.reg, res);
2427 goto just_flags_inc32;
2428
2429 case O (O_INC, SB): /* inc.b */
2430 /* FIXME fetch.
2431 * This insn only uses register operands, but still
2432 * it would be cleaner to use fetch and store... */
2433 rd = GET_B_REG (code->src.reg);
2434 ea = 1;
2435 res = rd + ea;
2436 SET_B_REG (code->src.reg, res);
2437 goto just_flags_inc8;
2438
2439 case O (O_INC, SW): /* inc.w */
2440 /* FIXME fetch.
2441 * This insn only uses register operands, but still
2442 * it would be cleaner to use fetch and store... */
2443 rd = GET_W_REG (code->dst.reg);
2444 ea = code->src.literal;
2445 res = rd + ea;
2446 SET_W_REG (code->dst.reg, res);
2447 goto just_flags_inc16;
2448
2449 case O (O_INC, SL): /* inc.l */
2450 /* FIXME fetch.
2451 * This insn only uses register operands, but still
2452 * it would be cleaner to use fetch and store... */
2453 rd = GET_L_REG (code->dst.reg);
2454 ea = code->src.literal;
2455 res = rd + ea;
2456 SET_L_REG (code->dst.reg, res);
2457 goto just_flags_inc32;
2458
2459 case O (O_LDC, SB): /* ldc.b */
2460 if (fetch (sd, &code->src, &res))
2461 goto end;
2462 goto setc;
2463
2464 case O (O_LDC, SW): /* ldc.w */
2465 if (fetch (sd, &code->src, &res))
2466 goto end;
2467
2468 /* Word operand, value from MSB, must be shifted. */
2469 res >>= 8;
2470 goto setc;
2471
2472 case O (O_LDC, SL): /* ldc.l */
2473 if (fetch (sd, &code->src, &res))
2474 goto end;
2475 switch (code->dst.type) {
2476 case X (OP_SBR, SL):
2477 h8_set_sbr (sd, res);
2478 break;
2479 case X (OP_VBR, SL):
2480 h8_set_vbr (sd, res);
2481 break;
2482 default:
2483 goto illegal;
2484 }
2485 goto next;
2486
2487 case O (O_STC, SW): /* stc.w */
2488 case O (O_STC, SB): /* stc.b */
2489 if (code->src.type == X (OP_CCR, SB))
2490 {
2491 BUILDSR (sd);
2492 res = h8_get_ccr (sd);
2493 }
2494 else if (code->src.type == X (OP_EXR, SB) && h8300smode)
2495 {
2496 if (h8300smode)
2497 h8_set_exr (sd, (trace << 7) | intMask);
2498 res = h8_get_exr (sd);
2499 }
2500 else
2501 goto illegal;
2502
2503 /* Word operand, value to MSB, must be shifted. */
2504 if (code->opcode == X (O_STC, SW))
2505 res <<= 8;
2506 if (store (sd, &code->dst, res))
2507 goto end;
2508 goto next;
2509 case O (O_STC, SL): /* stc.l */
2510 switch (code->src.type) {
2511 case X (OP_SBR, SL):
2512 res = h8_get_sbr (sd);
2513 break;
2514 case X (OP_VBR, SL):
2515 res = h8_get_vbr (sd);
2516 break;
2517 default:
2518 goto illegal;
2519 }
2520 if (store (sd, &code->dst, res))
2521 goto end;
2522 goto next;
2523
2524 case O (O_ANDC, SB): /* andc.b */
2525 if (code->dst.type == X (OP_CCR, SB))
2526 {
2527 BUILDSR (sd);
2528 rd = h8_get_ccr (sd);
2529 }
2530 else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
2531 {
2532 if (h8300smode)
2533 h8_set_exr (sd, (trace << 7) | intMask);
d6fd015d 2534 rd = h8_get_exr (sd);
dc5c3759
MS
2535 }
2536 else
2537 goto illegal;
2538 ea = code->src.literal;
2539 res = rd & ea;
2540 goto setc;
2541
2542 case O (O_ORC, SB): /* orc.b */
2543 if (code->dst.type == X (OP_CCR, SB))
2544 {
2545 BUILDSR (sd);
2546 rd = h8_get_ccr (sd);
2547 }
2548 else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
2549 {
2550 if (h8300smode)
2551 h8_set_exr (sd, (trace << 7) | intMask);
2552 rd = h8_get_exr (sd);
2553 }
2554 else
2555 goto illegal;
2556 ea = code->src.literal;
2557 res = rd | ea;
2558 goto setc;
2559
2560 case O (O_XORC, SB): /* xorc.b */
2561 if (code->dst.type == X (OP_CCR, SB))
2562 {
2563 BUILDSR (sd);
2564 rd = h8_get_ccr (sd);
2565 }
2566 else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
2567 {
2568 if (h8300smode)
2569 h8_set_exr (sd, (trace << 7) | intMask);
2570 rd = h8_get_exr (sd);
2571 }
2572 else
2573 goto illegal;
2574 ea = code->src.literal;
2575 res = rd ^ ea;
2576 goto setc;
2577
2578 case O (O_BRAS, SB): /* bra/s */
2579 /* This is basically an ordinary branch, with a delay slot. */
2580 if (fetch (sd, &code->src, &res))
2581 goto end;
2582
2583 if ((res & 1) == 0)
2584 goto illegal;
2585
2586 res -= 1;
2587
2588 /* Execution continues at next instruction, but
2589 delayed_branch is set up for next cycle. */
2590 h8_set_delayed_branch (sd, code->next_pc + res);
2591 pc = code->next_pc;
2592 goto end;
2593
2594 case O (O_BRAB, SB): /* bra rd.b */
2595 case O (O_BRAW, SW): /* bra rd.w */
2596 case O (O_BRAL, SL): /* bra erd.l */
2597 if (fetch (sd, &code->src, &rd))
2598 goto end;
2599 switch (OP_SIZE (code->opcode)) {
2600 case SB: rd &= 0xff; break;
2601 case SW: rd &= 0xffff; break;
2602 case SL: rd &= 0xffffffff; break;
2603 }
2604 pc = code->next_pc + rd;
2605 goto end;
2606
2607 case O (O_BRABC, SB): /* bra/bc, branch if bit clear */
2608 case O (O_BRABS, SB): /* bra/bs, branch if bit set */
2609 case O (O_BSRBC, SB): /* bsr/bc, call if bit clear */
2610 case O (O_BSRBS, SB): /* bsr/bs, call if bit set */
2611 if (fetch (sd, &code->dst, &rd) ||
2612 fetch (sd, &code->src, &bit))
2613 goto end;
2614
2615 if (code->opcode == O (O_BRABC, SB) || /* branch if clear */
2616 code->opcode == O (O_BSRBC, SB)) /* call if clear */
2617 {
2618 if ((rd & (1 << bit))) /* no branch */
2619 goto next;
2620 }
2621 else /* branch/call if set */
2622 {
2623 if (!(rd & (1 << bit))) /* no branch */
2624 goto next;
2625 }
2626
2627 if (fetch (sd, &code->op3, &res)) /* branch */
2628 goto end;
2629 pc = code->next_pc + res;
2630
2631 if (code->opcode == O (O_BRABC, SB) ||
2632 code->opcode == O (O_BRABS, SB)) /* branch */
2633 goto end;
2634 else /* call */
2635 goto call;
2636
2637 case O (O_BRA, SN):
2638 case O (O_BRA, SL):
2639 case O (O_BRA, SW):
2640 case O (O_BRA, SB): /* bra, branch always */
2641 if (1)
2642 goto condtrue;
2643 goto next;
2644
2645 case O (O_BRN, SB): /* brn, ;-/ branch never? */
2646 if (0)
2647 goto condtrue;
2648 goto next;
2649
2650 case O (O_BHI, SB): /* bhi */
2651 if ((C || Z) == 0)
2652 goto condtrue;
2653 goto next;
2654
2655
2656 case O (O_BLS, SB): /* bls */
2657 if ((C || Z))
2658 goto condtrue;
2659 goto next;
2660
2661 case O (O_BCS, SB): /* bcs, branch if carry set */
2662 if ((C == 1))
2663 goto condtrue;
2664 goto next;
2665
2666 case O (O_BCC, SB): /* bcc, branch if carry clear */
2667 if ((C == 0))
2668 goto condtrue;
2669 goto next;
2670
2671 case O (O_BEQ, SB): /* beq, branch if zero set */
2672 if (Z)
2673 goto condtrue;
2674 goto next;
2675 case O (O_BGT, SB): /* bgt */
2676 if (((Z || (N ^ V)) == 0))
2677 goto condtrue;
2678 goto next;
2679
2680 case O (O_BLE, SB): /* ble */
2681 if (((Z || (N ^ V)) == 1))
2682 goto condtrue;
2683 goto next;
2684
2685 case O (O_BGE, SB): /* bge */
2686 if ((N ^ V) == 0)
2687 goto condtrue;
2688 goto next;
2689 case O (O_BLT, SB): /* blt */
2690 if ((N ^ V))
2691 goto condtrue;
2692 goto next;
2693 case O (O_BMI, SB): /* bmi */
2694 if ((N))
2695 goto condtrue;
2696 goto next;
2697 case O (O_BNE, SB): /* bne, branch if zero clear */
2698 if ((Z == 0))
2699 goto condtrue;
2700 goto next;
2701
2702 case O (O_BPL, SB): /* bpl */
2703 if (N == 0)
2704 goto condtrue;
2705 goto next;
2706 case O (O_BVC, SB): /* bvc */
2707 if ((V == 0))
2708 goto condtrue;
2709 goto next;
2710 case O (O_BVS, SB): /* bvs */
2711 if ((V == 1))
2712 goto condtrue;
2713 goto next;
2714
2715 /* Trap for Command Line setup. */
2716 case O (O_SYS_CMDLINE, SB):
2717 {
2718 int i = 0; /* Loop counter. */
2719 int j = 0; /* Loop counter. */
2720 int ind_arg_len = 0; /* Length of each argument. */
2721 int no_of_args = 0; /* The no. or cmdline args. */
2722 int current_location = 0; /* Location of string. */
2723 int old_sp = 0; /* The Initial Stack Pointer. */
2724 int no_of_slots = 0; /* No. of slots required on the stack
2725 for storing cmdline args. */
2726 int sp_move = 0; /* No. of locations by which the stack needs
2727 to grow. */
2728 int new_sp = 0; /* The final stack pointer location passed
2729 back. */
2730 int *argv_ptrs; /* Pointers of argv strings to be stored. */
2731 int argv_ptrs_location = 0; /* Location of pointers to cmdline
2732 args on the stack. */
2733 int char_ptr_size = 0; /* Size of a character pointer on
2734 target machine. */
2735 int addr_cmdline = 0; /* Memory location where cmdline has
2736 to be stored. */
2737 int size_cmdline = 0; /* Size of cmdline. */
2738
2739 /* Set the address of 256 free locations where command line is
2740 stored. */
2741 addr_cmdline = cmdline_location();
2742 h8_set_reg (sd, 0, addr_cmdline);
2743
2744 /* Counting the no. of commandline arguments. */
2745 for (i = 0; h8_get_cmdline_arg (sd, i) != NULL; i++)
2746 continue;
2747
2748 /* No. of arguments in the command line. */
2749 no_of_args = i;
2750
2751 /* Current location is just a temporary variable,which we are
2752 setting to the point to the start of our commandline string. */
2753 current_location = addr_cmdline;
2754
2755 /* Allocating space for storing pointers of the command line
2756 arguments. */
2757 argv_ptrs = (int *) malloc (sizeof (int) * no_of_args);
2758
2759 /* Setting char_ptr_size to the sizeof (char *) on the different
2760 architectures. */
59768597 2761 if ((h8300hmode || h8300smode) && !h8300_normal_mode)
dc5c3759
MS
2762 {
2763 char_ptr_size = 4;
2764 }
2765 else
2766 {
2767 char_ptr_size = 2;
2768 }
2769
2770 for (i = 0; i < no_of_args; i++)
2771 {
2772 ind_arg_len = 0;
2773
2774 /* The size of the commandline argument. */
917c78f9 2775 ind_arg_len = strlen (h8_get_cmdline_arg (sd, i)) + 1;
dc5c3759
MS
2776
2777 /* The total size of the command line string. */
2778 size_cmdline += ind_arg_len;
2779
2780 /* As we have only 256 bytes, we need to provide a graceful
2781 exit. Anyways, a program using command line arguments
2782 where we cannot store all the command line arguments
2783 given may behave unpredictably. */
2784 if (size_cmdline >= 256)
2785 {
2786 h8_set_reg (sd, 0, 0);
2787 goto next;
2788 }
2789 else
2790 {
2791 /* current_location points to the memory where the next
2792 commandline argument is stored. */
2793 argv_ptrs[i] = current_location;
2794 for (j = 0; j < ind_arg_len; j++)
2795 {
2796 SET_MEMORY_B ((current_location +
2797 (sizeof (char) * j)),
2798 *(h8_get_cmdline_arg (sd, i) +
2799 sizeof (char) * j));
2800 }
2801
2802 /* Setting current_location to the starting of next
2803 argument. */
2804 current_location += ind_arg_len;
2805 }
2806 }
2807
2808 /* This is the original position of the stack pointer. */
2809 old_sp = h8_get_reg (sd, SP_REGNUM);
2810
2811 /* We need space from the stack to store the pointers to argvs. */
2812 /* As we will infringe on the stack, we need to shift the stack
2813 pointer so that the data is not overwritten. We calculate how
2814 much space is required. */
2815 sp_move = (no_of_args) * (char_ptr_size);
2816
2817 /* The final position of stack pointer, we have thus taken some
2818 space from the stack. */
2819 new_sp = old_sp - sp_move;
2820
2821 /* Temporary variable holding value where the argv pointers need
2822 to be stored. */
2823 argv_ptrs_location = new_sp;
2824
2825 /* The argv pointers are stored at sequential locations. As per
2826 the H8300 ABI. */
2827 for (i = 0; i < no_of_args; i++)
2828 {
2829 /* Saving the argv pointer. */
59768597 2830 if ((h8300hmode || h8300smode) && !h8300_normal_mode)
dc5c3759
MS
2831 {
2832 SET_MEMORY_L (argv_ptrs_location, argv_ptrs[i]);
2833 }
2834 else
2835 {
2836 SET_MEMORY_W (argv_ptrs_location, argv_ptrs[i]);
2837 }
2838
2839 /* The next location where the pointer to the next argv
2840 string has to be stored. */
2841 argv_ptrs_location += char_ptr_size;
2842 }
2843
2844 /* Required by POSIX, Setting 0x0 at the end of the list of argv
2845 pointers. */
59768597 2846 if ((h8300hmode || h8300smode) && !h8300_normal_mode)
dc5c3759
MS
2847 {
2848 SET_MEMORY_L (old_sp, 0x0);
2849 }
2850 else
2851 {
2852 SET_MEMORY_W (old_sp, 0x0);
2853 }
2854
2855 /* Freeing allocated memory. */
2856 free (argv_ptrs);
2857 for (i = 0; i <= no_of_args; i++)
2858 {
2859 free (h8_get_cmdline_arg (sd, i));
2860 }
2861 free (h8_get_command_line (sd));
2862
2863 /* The no. of argv arguments are returned in Reg 0. */
2864 h8_set_reg (sd, 0, no_of_args);
2865 /* The Pointer to argv in Register 1. */
2866 h8_set_reg (sd, 1, new_sp);
2867 /* Setting the stack pointer to the new value. */
2868 h8_set_reg (sd, SP_REGNUM, new_sp);
2869 }
2870 goto next;
2871
2872 /* System call processing starts. */
2873 case O (O_SYS_OPEN, SB):
2874 {
2875 int len = 0; /* Length of filename. */
2876 char *filename; /* Filename would go here. */
2877 char temp_char; /* Temporary character */
2878 int mode = 0; /* Mode bits for the file. */
2879 int open_return; /* Return value of open, file descriptor. */
2880 int i; /* Loop counter */
2881 int filename_ptr; /* Pointer to filename in cpu memory. */
2882
2883 /* Setting filename_ptr to first argument of open, */
2884 /* and trying to get mode. */
59768597 2885 if ((h8300sxmode || h8300hmode || h8300smode) && !h8300_normal_mode)
dc5c3759
MS
2886 {
2887 filename_ptr = GET_L_REG (0);
2888 mode = GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM) + 4);
2889 }
2890 else
2891 {
2892 filename_ptr = GET_W_REG (0);
2893 mode = GET_MEMORY_W (h8_get_reg (sd, SP_REGNUM) + 2);
2894 }
2895
2896 /* Trying to find the length of the filename. */
2897 temp_char = GET_MEMORY_B (h8_get_reg (sd, 0));
2898
2899 len = 1;
2900 while (temp_char != '\0')
2901 {
2902 temp_char = GET_MEMORY_B (filename_ptr + len);
2903 len++;
2904 }
2905
2906 /* Allocating space for the filename. */
2907 filename = (char *) malloc (sizeof (char) * len);
2908
2909 /* String copying the filename from memory. */
2910 for (i = 0; i < len; i++)
2911 {
2912 temp_char = GET_MEMORY_B (filename_ptr + i);
2913 filename[i] = temp_char;
2914 }
2915
2916 /* Callback to open and return the file descriptor. */
2917 open_return = sim_callback->open (sim_callback, filename, mode);
2918
2919 /* Return value in register 0. */
2920 h8_set_reg (sd, 0, open_return);
2921
2922 /* Freeing memory used for filename. */
2923 free (filename);
2924 }
2925 goto next;
2926
2927 case O (O_SYS_READ, SB):
2928 {
2929 char *char_ptr; /* Where characters read would be stored. */
2930 int fd; /* File descriptor */
2931 int buf_size; /* BUF_SIZE parameter in read. */
2932 int i = 0; /* Temporary Loop counter */
2933 int read_return = 0; /* Return value from callback to
2934 read. */
2935
59768597
SA
2936 fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
2937 buf_size = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
dc5c3759
MS
2938
2939 char_ptr = (char *) malloc (sizeof (char) * buf_size);
2940
2941 /* Callback to read and return the no. of characters read. */
2942 read_return =
2943 sim_callback->read (sim_callback, fd, char_ptr, buf_size);
2944
2945 /* The characters read are stored in cpu memory. */
2946 for (i = 0; i < buf_size; i++)
2947 {
2948 SET_MEMORY_B ((h8_get_reg (sd, 1) + (sizeof (char) * i)),
2949 *(char_ptr + (sizeof (char) * i)));
2950 }
2951
2952 /* Return value in Register 0. */
2953 h8_set_reg (sd, 0, read_return);
2954
2955 /* Freeing memory used as buffer. */
2956 free (char_ptr);
2957 }
2958 goto next;
2959
2960 case O (O_SYS_WRITE, SB):
2961 {
2962 int fd; /* File descriptor */
2963 char temp_char; /* Temporary character */
2964 int len; /* Length of write, Parameter II to write. */
2965 int char_ptr; /* Character Pointer, Parameter I of write. */
2966 char *ptr; /* Where characters to be written are stored.
2967 */
2968 int write_return; /* Return value from callback to write. */
2969 int i = 0; /* Loop counter */
2970
59768597
SA
2971 fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
2972 char_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
2973 len = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
dc5c3759
MS
2974
2975 /* Allocating space for the characters to be written. */
2976 ptr = (char *) malloc (sizeof (char) * len);
2977
2978 /* Fetching the characters from cpu memory. */
2979 for (i = 0; i < len; i++)
2980 {
2981 temp_char = GET_MEMORY_B (char_ptr + i);
2982 ptr[i] = temp_char;
2983 }
2984
2985 /* Callback write and return the no. of characters written. */
2986 write_return = sim_callback->write (sim_callback, fd, ptr, len);
2987
2988 /* Return value in Register 0. */
2989 h8_set_reg (sd, 0, write_return);
2990
2991 /* Freeing memory used as buffer. */
2992 free (ptr);
2993 }
2994 goto next;
2995
2996 case O (O_SYS_LSEEK, SB):
2997 {
2998 int fd; /* File descriptor */
2999 int offset; /* Offset */
3000 int origin; /* Origin */
3001 int lseek_return; /* Return value from callback to lseek. */
3002
59768597
SA
3003 fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
3004 offset = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
3005 origin = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
c906108c 3006
dc5c3759
MS
3007 /* Callback lseek and return offset. */
3008 lseek_return =
3009 sim_callback->lseek (sim_callback, fd, offset, origin);
3b02cf92 3010
dc5c3759
MS
3011 /* Return value in register 0. */
3012 h8_set_reg (sd, 0, lseek_return);
3013 }
3014 goto next;
c906108c 3015
dc5c3759
MS
3016 case O (O_SYS_CLOSE, SB):
3017 {
3018 int fd; /* File descriptor */
3019 int close_return; /* Return value from callback to close. */
c906108c 3020
59768597 3021 fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
c906108c 3022
dc5c3759
MS
3023 /* Callback close and return. */
3024 close_return = sim_callback->close (sim_callback, fd);
c906108c 3025
dc5c3759
MS
3026 /* Return value in register 0. */
3027 h8_set_reg (sd, 0, close_return);
3028 }
3029 goto next;
c906108c 3030
dc5c3759
MS
3031 case O (O_SYS_FSTAT, SB):
3032 {
3033 int fd; /* File descriptor */
3034 struct stat stat_rec; /* Stat record */
3035 int fstat_return; /* Return value from callback to stat. */
3036 int stat_ptr; /* Pointer to stat record. */
3037 char *temp_stat_ptr; /* Temporary stat_rec pointer. */
c906108c 3038
59768597 3039 fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
c906108c 3040
dc5c3759 3041 /* Setting stat_ptr to second argument of stat. */
59768597 3042 stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
c906108c 3043
dc5c3759 3044 /* Callback stat and return. */
2d7bb758
JB
3045 fstat_return = sim_callback->to_fstat (sim_callback, fd,
3046 &stat_rec);
c906108c 3047
dc5c3759
MS
3048 /* Have stat_ptr point to starting of stat_rec. */
3049 temp_stat_ptr = (char *) (&stat_rec);
c906108c 3050
dc5c3759
MS
3051 /* Setting up the stat structure returned. */
3052 SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
3053 stat_ptr += 2;
3054 SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
3055 stat_ptr += 2;
3056 SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
3057 stat_ptr += 4;
3058 SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
3059 stat_ptr += 2;
3060 SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
3061 stat_ptr += 2;
3062 SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
3063 stat_ptr += 2;
3064 SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
3065 stat_ptr += 2;
3066 SET_MEMORY_L (stat_ptr, stat_rec.st_size);
3067 stat_ptr += 4;
3068 SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
3069 stat_ptr += 8;
3070 SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
3071 stat_ptr += 8;
3072 SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
c906108c 3073
dc5c3759
MS
3074 /* Return value in register 0. */
3075 h8_set_reg (sd, 0, fstat_return);
3076 }
3077 goto next;
c906108c 3078
dc5c3759
MS
3079 case O (O_SYS_STAT, SB):
3080 {
3081 int len = 0; /* Length of filename. */
3082 char *filename; /* Filename would go here. */
3083 char temp_char; /* Temporary character */
3084 int filename_ptr; /* Pointer to filename in cpu memory. */
3085 struct stat stat_rec; /* Stat record */
3086 int stat_return; /* Return value from callback to stat */
3087 int stat_ptr; /* Pointer to stat record. */
3088 char *temp_stat_ptr; /* Temporary stat_rec pointer. */
3089 int i = 0; /* Loop Counter */
c906108c 3090
dc5c3759 3091 /* Setting filename_ptr to first argument of open. */
59768597 3092 filename_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
c906108c 3093
dc5c3759
MS
3094 /* Trying to find the length of the filename. */
3095 temp_char = GET_MEMORY_B (h8_get_reg (sd, 0));
c906108c 3096
dc5c3759
MS
3097 len = 1;
3098 while (temp_char != '\0')
3099 {
3100 temp_char = GET_MEMORY_B (filename_ptr + len);
3101 len++;
3102 }
d0fe2f7e 3103
dc5c3759
MS
3104 /* Allocating space for the filename. */
3105 filename = (char *) malloc (sizeof (char) * len);
c3f4437e 3106
dc5c3759
MS
3107 /* String copying the filename from memory. */
3108 for (i = 0; i < len; i++)
3109 {
3110 temp_char = GET_MEMORY_B (filename_ptr + i);
3111 filename[i] = temp_char;
3112 }
c906108c 3113
dc5c3759
MS
3114 /* Setting stat_ptr to second argument of stat. */
3115 /* stat_ptr = h8_get_reg (sd, 1); */
59768597 3116 stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
c906108c 3117
dc5c3759
MS
3118 /* Callback stat and return. */
3119 stat_return =
2d7bb758 3120 sim_callback->to_stat (sim_callback, filename, &stat_rec);
c906108c 3121
dc5c3759
MS
3122 /* Have stat_ptr point to starting of stat_rec. */
3123 temp_stat_ptr = (char *) (&stat_rec);
3124
3125 /* Freeing memory used for filename. */
3126 free (filename);
3127
3128 /* Setting up the stat structure returned. */
3129 SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
3130 stat_ptr += 2;
3131 SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
3132 stat_ptr += 2;
3133 SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
3134 stat_ptr += 4;
3135 SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
3136 stat_ptr += 2;
3137 SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
3138 stat_ptr += 2;
3139 SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
3140 stat_ptr += 2;
3141 SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
3142 stat_ptr += 2;
3143 SET_MEMORY_L (stat_ptr, stat_rec.st_size);
3144 stat_ptr += 4;
3145 SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
3146 stat_ptr += 8;
3147 SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
3148 stat_ptr += 8;
3149 SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
3150
3151 /* Return value in register 0. */
3152 h8_set_reg (sd, 0, stat_return);
3153 }
c906108c 3154 goto next;
dc5c3759 3155 /* End of system call processing. */
c906108c 3156
dc5c3759
MS
3157 case O (O_NOT, SB): /* not.b */
3158 if (fetch2 (sd, &code->src, &rd))
3159 goto end;
3160 rd = ~rd;
3161 v = 0;
3162 goto shift8;
c906108c 3163
dc5c3759
MS
3164 case O (O_NOT, SW): /* not.w */
3165 if (fetch2 (sd, &code->src, &rd))
3166 goto end;
3167 rd = ~rd;
3168 v = 0;
3169 goto shift16;
c906108c 3170
dc5c3759
MS
3171 case O (O_NOT, SL): /* not.l */
3172 if (fetch2 (sd, &code->src, &rd))
3173 goto end;
3174 rd = ~rd;
3175 v = 0;
3176 goto shift32;
c906108c 3177
dc5c3759
MS
3178 case O (O_SHLL, SB): /* shll.b */
3179 case O (O_SHLR, SB): /* shlr.b */
3180 if (fetch2 (sd, &code->dst, &rd))
3181 goto end;
c906108c 3182
55acb21b
MS
3183 if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
3184 ea = 1; /* unary op */
3185 else /* binary op */
dc5c3759 3186 fetch (sd, &code->src, &ea);
c906108c 3187
dc5c3759
MS
3188 if (code->opcode == O (O_SHLL, SB))
3189 {
3190 v = (ea > 8);
3191 c = rd & (0x80 >> (ea - 1));
3192 rd <<= ea;
3193 }
3194 else
3195 {
3196 v = 0;
3197 c = rd & (1 << (ea - 1));
3198 rd = (unsigned char) rd >> ea;
3199 }
3200 goto shift8;
c906108c 3201
dc5c3759
MS
3202 case O (O_SHLL, SW): /* shll.w */
3203 case O (O_SHLR, SW): /* shlr.w */
3204 if (fetch2 (sd, &code->dst, &rd))
3205 goto end;
c906108c 3206
55acb21b
MS
3207 if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
3208 ea = 1; /* unary op */
dc5c3759 3209 else
55acb21b 3210 fetch (sd, &code->src, &ea);
c906108c 3211
dc5c3759
MS
3212 if (code->opcode == O (O_SHLL, SW))
3213 {
3214 v = (ea > 16);
3215 c = rd & (0x8000 >> (ea - 1));
3216 rd <<= ea;
3217 }
3218 else
3219 {
3220 v = 0;
3221 c = rd & (1 << (ea - 1));
3222 rd = (unsigned short) rd >> ea;
3223 }
3224 goto shift16;
c906108c 3225
dc5c3759
MS
3226 case O (O_SHLL, SL): /* shll.l */
3227 case O (O_SHLR, SL): /* shlr.l */
3228 if (fetch2 (sd, &code->dst, &rd))
3229 goto end;
c906108c 3230
55acb21b
MS
3231 if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
3232 ea = 1; /* unary op */
dc5c3759 3233 else
55acb21b 3234 fetch (sd, &code->src, &ea);
c906108c 3235
dc5c3759 3236 if (code->opcode == O (O_SHLL, SL))
c3f4437e 3237 {
dc5c3759
MS
3238 v = (ea > 32);
3239 c = rd & (0x80000000 >> (ea - 1));
3240 rd <<= ea;
c3f4437e 3241 }
dc5c3759 3242 else
c3f4437e 3243 {
dc5c3759
MS
3244 v = 0;
3245 c = rd & (1 << (ea - 1));
3246 rd = (unsigned int) rd >> ea;
c3f4437e 3247 }
dc5c3759
MS
3248 goto shift32;
3249
3250 case O (O_SHAL, SB):
3251 case O (O_SHAR, SB):
3252 if (fetch2 (sd, &code->dst, &rd))
3253 goto end;
3254
3255 if (code->src.type == X (OP_IMM, SB))
3256 fetch (sd, &code->src, &ea);
c3f4437e 3257 else
dc5c3759 3258 ea = 1;
6147b1f6 3259
dc5c3759 3260 if (code->opcode == O (O_SHAL, SB))
c3f4437e 3261 {
dc5c3759
MS
3262 c = rd & (0x80 >> (ea - 1));
3263 res = rd >> (7 - ea);
3264 v = ((res & 1) && !(res & 2))
3265 || (!(res & 1) && (res & 2));
3266 rd <<= ea;
c3f4437e 3267 }
dc5c3759 3268 else
c3f4437e 3269 {
dc5c3759
MS
3270 c = rd & (1 << (ea - 1));
3271 v = 0;
3272 rd = ((signed char) rd) >> ea;
c3f4437e 3273 }
dc5c3759
MS
3274 goto shift8;
3275
3276 case O (O_SHAL, SW):
3277 case O (O_SHAR, SW):
3278 if (fetch2 (sd, &code->dst, &rd))
3279 goto end;
3280
3281 if (code->src.type == X (OP_IMM, SW))
3282 fetch (sd, &code->src, &ea);
c3f4437e 3283 else
dc5c3759 3284 ea = 1;
c906108c 3285
dc5c3759 3286 if (code->opcode == O (O_SHAL, SW))
c3f4437e 3287 {
dc5c3759
MS
3288 c = rd & (0x8000 >> (ea - 1));
3289 res = rd >> (15 - ea);
3290 v = ((res & 1) && !(res & 2))
3291 || (!(res & 1) && (res & 2));
3292 rd <<= ea;
c3f4437e 3293 }
dc5c3759 3294 else
c3f4437e 3295 {
dc5c3759
MS
3296 c = rd & (1 << (ea - 1));
3297 v = 0;
3298 rd = ((signed short) rd) >> ea;
c3f4437e 3299 }
dc5c3759
MS
3300 goto shift16;
3301
3302 case O (O_SHAL, SL):
3303 case O (O_SHAR, SL):
3304 if (fetch2 (sd, &code->dst, &rd))
3305 goto end;
3306
3307 if (code->src.type == X (OP_IMM, SL))
3308 fetch (sd, &code->src, &ea);
3309 else
3310 ea = 1;
c906108c 3311
dc5c3759 3312 if (code->opcode == O (O_SHAL, SL))
c3f4437e 3313 {
dc5c3759
MS
3314 c = rd & (0x80000000 >> (ea - 1));
3315 res = rd >> (31 - ea);
3316 v = ((res & 1) && !(res & 2))
3317 || (!(res & 1) && (res & 2));
3318 rd <<= ea;
c3f4437e 3319 }
dc5c3759 3320 else
c3f4437e 3321 {
dc5c3759
MS
3322 c = rd & (1 << (ea - 1));
3323 v = 0;
3324 rd = ((signed int) rd) >> ea;
c3f4437e 3325 }
dc5c3759 3326 goto shift32;
c906108c 3327
dc5c3759
MS
3328 case O (O_ROTL, SB):
3329 case O (O_ROTR, SB):
3330 if (fetch2 (sd, &code->dst, &rd))
3331 goto end;
c906108c 3332
dc5c3759
MS
3333 if (code->src.type == X (OP_IMM, SB))
3334 fetch (sd, &code->src, &ea);
3335 else
3336 ea = 1;
c906108c 3337
dc5c3759
MS
3338 while (ea--)
3339 if (code->opcode == O (O_ROTL, SB))
3340 {
3341 c = rd & 0x80;
3342 rd <<= 1;
3343 if (c)
3344 rd |= 1;
3345 }
3346 else
3347 {
3348 c = rd & 1;
3349 rd = ((unsigned char) rd) >> 1;
3350 if (c)
3351 rd |= 0x80;
3352 }
c906108c 3353
dc5c3759
MS
3354 v = 0;
3355 goto shift8;
c906108c 3356
dc5c3759
MS
3357 case O (O_ROTL, SW):
3358 case O (O_ROTR, SW):
3359 if (fetch2 (sd, &code->dst, &rd))
3360 goto end;
c906108c 3361
dc5c3759
MS
3362 if (code->src.type == X (OP_IMM, SW))
3363 fetch (sd, &code->src, &ea);
3364 else
3365 ea = 1;
c906108c 3366
dc5c3759
MS
3367 while (ea--)
3368 if (code->opcode == O (O_ROTL, SW))
3369 {
3370 c = rd & 0x8000;
3371 rd <<= 1;
3372 if (c)
3373 rd |= 1;
3374 }
3375 else
3376 {
3377 c = rd & 1;
3378 rd = ((unsigned short) rd) >> 1;
3379 if (c)
3380 rd |= 0x8000;
3381 }
c906108c 3382
dc5c3759
MS
3383 v = 0;
3384 goto shift16;
c906108c 3385
dc5c3759
MS
3386 case O (O_ROTL, SL):
3387 case O (O_ROTR, SL):
3388 if (fetch2 (sd, &code->dst, &rd))
3389 goto end;
c906108c 3390
dc5c3759
MS
3391 if (code->src.type == X (OP_IMM, SL))
3392 fetch (sd, &code->src, &ea);
3393 else
3394 ea = 1;
c906108c 3395
dc5c3759
MS
3396 while (ea--)
3397 if (code->opcode == O (O_ROTL, SL))
3398 {
3399 c = rd & 0x80000000;
3400 rd <<= 1;
3401 if (c)
3402 rd |= 1;
3403 }
3404 else
3405 {
3406 c = rd & 1;
3407 rd = ((unsigned int) rd) >> 1;
3408 if (c)
3409 rd |= 0x80000000;
3410 }
c906108c 3411
dc5c3759
MS
3412 v = 0;
3413 goto shift32;
c906108c 3414
dc5c3759
MS
3415 case O (O_ROTXL, SB):
3416 case O (O_ROTXR, SB):
3417 if (fetch2 (sd, &code->dst, &rd))
3418 goto end;
d1360fb0 3419
dc5c3759
MS
3420 if (code->src.type == X (OP_IMM, SB))
3421 fetch (sd, &code->src, &ea);
3422 else
3423 ea = 1;
d1360fb0 3424
dc5c3759
MS
3425 while (ea--)
3426 if (code->opcode == O (O_ROTXL, SB))
3427 {
3428 res = rd & 0x80;
3429 rd <<= 1;
3430 if (C)
3431 rd |= 1;
3432 c = res;
3433 }
3434 else
3435 {
3436 res = rd & 1;
3437 rd = ((unsigned char) rd) >> 1;
3438 if (C)
3439 rd |= 0x80;
3440 c = res;
3441 }
d1360fb0 3442
dc5c3759
MS
3443 v = 0;
3444 goto shift8;
d1360fb0 3445
dc5c3759
MS
3446 case O (O_ROTXL, SW):
3447 case O (O_ROTXR, SW):
3448 if (fetch2 (sd, &code->dst, &rd))
3449 goto end;
d1360fb0 3450
dc5c3759
MS
3451 if (code->src.type == X (OP_IMM, SW))
3452 fetch (sd, &code->src, &ea);
3453 else
3454 ea = 1;
d1360fb0 3455
dc5c3759
MS
3456 while (ea--)
3457 if (code->opcode == O (O_ROTXL, SW))
d1360fb0 3458 {
dc5c3759
MS
3459 res = rd & 0x8000;
3460 rd <<= 1;
3461 if (C)
3462 rd |= 1;
3463 c = res;
d1360fb0
V
3464 }
3465 else
3466 {
dc5c3759
MS
3467 res = rd & 1;
3468 rd = ((unsigned short) rd) >> 1;
3469 if (C)
3470 rd |= 0x8000;
3471 c = res;
d1360fb0
V
3472 }
3473
dc5c3759
MS
3474 v = 0;
3475 goto shift16;
d1360fb0 3476
dc5c3759
MS
3477 case O (O_ROTXL, SL):
3478 case O (O_ROTXR, SL):
3479 if (fetch2 (sd, &code->dst, &rd))
3480 goto end;
d1360fb0 3481
dc5c3759
MS
3482 if (code->src.type == X (OP_IMM, SL))
3483 fetch (sd, &code->src, &ea);
3484 else
3485 ea = 1;
d1360fb0 3486
dc5c3759
MS
3487 while (ea--)
3488 if (code->opcode == O (O_ROTXL, SL))
3489 {
3490 res = rd & 0x80000000;
3491 rd <<= 1;
3492 if (C)
3493 rd |= 1;
3494 c = res;
3495 }
3496 else
3497 {
3498 res = rd & 1;
3499 rd = ((unsigned int) rd) >> 1;
3500 if (C)
3501 rd |= 0x80000000;
3502 c = res;
d1360fb0
V
3503 }
3504
dc5c3759
MS
3505 v = 0;
3506 goto shift32;
d1360fb0 3507
dc5c3759
MS
3508 case O (O_JMP, SN):
3509 case O (O_JMP, SL):
3510 case O (O_JMP, SB): /* jmp */
3511 case O (O_JMP, SW):
9f70f8ec
MS
3512 fetch (sd, &code->src, &pc);
3513 goto end;
d1360fb0 3514
dc5c3759
MS
3515 case O (O_JSR, SN):
3516 case O (O_JSR, SL):
3517 case O (O_JSR, SB): /* jsr, jump to subroutine */
3518 case O (O_JSR, SW):
9f70f8ec
MS
3519 if (fetch (sd, &code->src, &pc))
3520 goto end;
3521 call:
3522 tmp = h8_get_reg (sd, SP_REGNUM);
d1360fb0 3523
59768597 3524 if (h8300hmode && !h8300_normal_mode)
9f70f8ec
MS
3525 {
3526 tmp -= 4;
3527 SET_MEMORY_L (tmp, code->next_pc);
3528 }
3529 else
3530 {
3531 tmp -= 2;
3532 SET_MEMORY_W (tmp, code->next_pc);
3533 }
3534 h8_set_reg (sd, SP_REGNUM, tmp);
d1360fb0 3535
9f70f8ec 3536 goto end;
dc5c3759
MS
3537
3538 case O (O_BSR, SW):
3539 case O (O_BSR, SL):
3540 case O (O_BSR, SB): /* bsr, branch to subroutine */
3541 if (fetch (sd, &code->src, &res))
3542 goto end;
3543 pc = code->next_pc + res;
3544 goto call;
3545
9f70f8ec
MS
3546 case O (O_RTE, SN): /* rte, return from exception */
3547 rte:
3548 /* Pops exr and ccr before pc -- otherwise identical to rts. */
3549 tmp = h8_get_reg (sd, SP_REGNUM);
dc5c3759 3550
9f70f8ec
MS
3551 if (h8300smode) /* pop exr */
3552 {
3553 h8_set_exr (sd, GET_MEMORY_L (tmp));
3554 tmp += 4;
3555 }
59768597 3556 if (h8300hmode && !h8300_normal_mode)
9f70f8ec
MS
3557 {
3558 h8_set_ccr (sd, GET_MEMORY_L (tmp));
3559 tmp += 4;
3560 pc = GET_MEMORY_L (tmp);
3561 tmp += 4;
3562 }
3563 else
3564 {
3565 h8_set_ccr (sd, GET_MEMORY_W (tmp));
3566 tmp += 2;
3567 pc = GET_MEMORY_W (tmp);
3568 tmp += 2;
3569 }
dc5c3759 3570
9f70f8ec
MS
3571 GETSR (sd);
3572 h8_set_reg (sd, SP_REGNUM, tmp);
3573 goto end;
d1360fb0 3574
9f70f8ec
MS
3575 case O (O_RTS, SN): /* rts, return from subroutine */
3576 rts:
3577 tmp = h8_get_reg (sd, SP_REGNUM);
3578
59768597 3579 if (h8300hmode && !h8300_normal_mode)
9f70f8ec
MS
3580 {
3581 pc = GET_MEMORY_L (tmp);
3582 tmp += 4;
3583 }
3584 else
3585 {
3586 pc = GET_MEMORY_W (tmp);
3587 tmp += 2;
3588 }
3589
3590 h8_set_reg (sd, SP_REGNUM, tmp);
3591 goto end;
d1360fb0 3592
dc5c3759
MS
3593 case O (O_ILL, SB): /* illegal */
3594 sim_engine_set_run_state (sd, sim_stopped, SIGILL);
3595 goto end;
3596
3597 case O (O_SLEEP, SN): /* sleep */
3598 /* Check for magic numbers in r1 and r2. */
3599 if ((h8_get_reg (sd, R1_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC1 &&
3600 (h8_get_reg (sd, R2_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC2 &&
3601 SIM_WIFEXITED (h8_get_reg (sd, 0)))
3602 {
3603 /* This trap comes from _exit, not from gdb. */
3604 sim_engine_set_run_state (sd, sim_exited,
3605 SIM_WEXITSTATUS (h8_get_reg (sd, 0)));
3606 }
e22fef83 3607#if 0
f408565c
MS
3608 /* Unfortunately this won't really work, because
3609 when we take a breakpoint trap, R0 has a "random",
3610 user-defined value. Don't see any immediate solution. */
f0861129
MS
3611 else if (SIM_WIFSTOPPED (h8_get_reg (sd, 0)))
3612 {
3613 /* Pass the stop signal up to gdb. */
3614 sim_engine_set_run_state (sd, sim_stopped,
3615 SIM_WSTOPSIG (h8_get_reg (sd, 0)));
3616 }
e22fef83 3617#endif
dc5c3759
MS
3618 else
3619 {
3620 /* Treat it as a sigtrap. */
3621 sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
3622 }
3623 goto end;
bf174226 3624
9f70f8ec
MS
3625 case O (O_TRAPA, SB): /* trapa */
3626 if (fetch (sd, &code->src, &res))
59768597
SA
3627 goto end; /* res is vector number. */
3628
3629 tmp = h8_get_reg (sd, SP_REGNUM);
3630 if(h8300_normal_mode)
3631 {
3632 tmp -= 2;
3633 SET_MEMORY_W (tmp, code->next_pc);
3634 tmp -= 2;
3635 SET_MEMORY_W (tmp, h8_get_ccr (sd));
3636 }
3637 else
3638 {
3639 tmp -= 4;
3640 SET_MEMORY_L (tmp, code->next_pc);
3641 tmp -= 4;
3642 SET_MEMORY_L (tmp, h8_get_ccr (sd));
3643 }
3644 intMaskBit = 1;
3645 BUILDSR (sd);
3646
9f70f8ec
MS
3647 if (h8300smode)
3648 {
3649 tmp -= 4;
3650 SET_MEMORY_L (tmp, h8_get_exr (sd));
3651 }
3652
3653 h8_set_reg (sd, SP_REGNUM, tmp);
3654
59768597
SA
3655 if(h8300_normal_mode)
3656 pc = GET_MEMORY_L (0x10 + res * 2); /* Vector addresses are 0x10,0x12,0x14 and 0x16 */
3657 else
3658 pc = GET_MEMORY_L (0x20 + res * 4);
9f70f8ec
MS
3659 goto end;
3660
dc5c3759
MS
3661 case O (O_BPT, SN):
3662 sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
3663 goto end;
bf174226 3664
dc5c3759
MS
3665 case O (O_BSETEQ, SB):
3666 if (Z)
3667 goto bset;
3668 goto next;
bf174226 3669
dc5c3759
MS
3670 case O (O_BSETNE, SB):
3671 if (!Z)
3672 goto bset;
3673 goto next;
bf174226 3674
dc5c3759
MS
3675 case O (O_BCLREQ, SB):
3676 if (Z)
3677 goto bclr;
3678 goto next;
bf174226 3679
dc5c3759
MS
3680 case O (O_BCLRNE, SB):
3681 if (!Z)
3682 goto bclr;
3683 goto next;
bf174226 3684
dc5c3759
MS
3685 OBITOP (O_BNOT, 1, 1, ea ^= m); /* bnot */
3686 OBITOP (O_BTST, 1, 0, nz = ea & m); /* btst */
3687 bset:
3688 OBITOP (O_BSET, 1, 1, ea |= m); /* bset */
3689 bclr:
3690 OBITOP (O_BCLR, 1, 1, ea &= ~m); /* bclr */
3691 OBITOP (O_BLD, 1, 0, c = ea & m); /* bld */
3692 OBITOP (O_BILD, 1, 0, c = !(ea & m)); /* bild */
3693 OBITOP (O_BST, 1, 1, ea &= ~m;
3694 if (C) ea |= m); /* bst */
3695 OBITOP (O_BIST, 1, 1, ea &= ~m;
3696 if (!C) ea |= m); /* bist */
3697 OBITOP (O_BSTZ, 1, 1, ea &= ~m;
3698 if (Z) ea |= m); /* bstz */
3699 OBITOP (O_BISTZ, 1, 1, ea &= ~m;
3700 if (!Z) ea |= m); /* bistz */
3701 OBITOP (O_BAND, 1, 0, c = (ea & m) && C); /* band */
3702 OBITOP (O_BIAND, 1, 0, c = !(ea & m) && C); /* biand */
3703 OBITOP (O_BOR, 1, 0, c = (ea & m) || C); /* bor */
3704 OBITOP (O_BIOR, 1, 0, c = !(ea & m) || C); /* bior */
3705 OBITOP (O_BXOR, 1, 0, c = ((ea & m) != 0)!= C); /* bxor */
3706 OBITOP (O_BIXOR, 1, 0, c = !(ea & m) != C); /* bixor */
3707
3708 case O (O_BFLD, SB): /* bfld */
3709 /* bitfield load */
3710 ea = 0;
3711 if (fetch (sd, &code->src, &bit))
3712 goto end;
bf174226 3713
dc5c3759
MS
3714 if (bit != 0)
3715 {
3716 if (fetch (sd, &code->dst, &ea))
3717 goto end;
bf174226 3718
dc5c3759
MS
3719 ea &= bit;
3720 while (!(bit & 1))
3721 {
3722 ea >>= 1;
3723 bit >>= 1;
3724 }
3725 }
3726 if (store (sd, &code->op3, ea))
3727 goto end;
bf174226 3728
c906108c
SS
3729 goto next;
3730
dc5c3759
MS
3731 case O(O_BFST, SB): /* bfst */
3732 /* bitfield store */
3733 /* NOTE: the imm8 value is in dst, and the ea value
3734 (which is actually the destination) is in op3.
3735 It has to be that way, to avoid breaking the assembler. */
bf174226 3736
dc5c3759
MS
3737 if (fetch (sd, &code->dst, &bit)) /* imm8 */
3738 goto end;
3739 if (bit == 0) /* noop -- nothing to do. */
3740 goto next;
bf174226 3741
dc5c3759
MS
3742 if (fetch (sd, &code->src, &rd)) /* reg8 src */
3743 goto end;
bf174226 3744
dc5c3759
MS
3745 if (fetch2 (sd, &code->op3, &ea)) /* ea dst */
3746 goto end;
bf174226 3747
dc5c3759
MS
3748 /* Left-shift the register data into position. */
3749 for (tmp = bit; !(tmp & 1); tmp >>= 1)
3750 rd <<= 1;
bf174226 3751
dc5c3759
MS
3752 /* Combine it with the neighboring bits. */
3753 ea = (ea & ~bit) | (rd & bit);
bf174226 3754
dc5c3759
MS
3755 /* Put it back. */
3756 if (store2 (sd, &code->op3, ea))
3757 goto end;
3758 goto next;
3759
3760 case O (O_CLRMAC, SN): /* clrmac */
3761 h8_set_mach (sd, 0);
3762 h8_set_macl (sd, 0);
3763 h8_set_macZ (sd, 1);
3764 h8_set_macV (sd, 0);
3765 h8_set_macN (sd, 0);
3766 goto next;
3767
3768 case O (O_STMAC, SL): /* stmac, 260 */
3769 switch (code->src.type) {
3770 case X (OP_MACH, SL):
3771 res = h8_get_mach (sd);
3772 if (res & 0x200) /* sign extend */
3773 res |= 0xfffffc00;
3774 break;
3775 case X (OP_MACL, SL):
3776 res = h8_get_macl (sd);
3777 break;
3778 default: goto illegal;
bf174226 3779 }
dc5c3759
MS
3780 nz = !h8_get_macZ (sd);
3781 n = h8_get_macN (sd);
3782 v = h8_get_macV (sd);
3783
3784 if (store (sd, &code->dst, res))
3785 goto end;
3786
bf174226
V
3787 goto next;
3788
dc5c3759
MS
3789 case O (O_LDMAC, SL): /* ldmac, 179 */
3790 if (fetch (sd, &code->src, &rd))
3791 goto end;
bf174226 3792
dc5c3759
MS
3793 switch (code->dst.type) {
3794 case X (OP_MACH, SL):
3795 rd &= 0x3ff; /* Truncate to 10 bits */
3796 h8_set_mach (sd, rd);
3797 break;
3798 case X (OP_MACL, SL):
3799 h8_set_macl (sd, rd);
3800 break;
3801 default: goto illegal;
3802 }
3803 h8_set_macV (sd, 0);
3804 goto next;
bf174226 3805
dc5c3759
MS
3806 case O (O_MAC, SW):
3807 if (fetch (sd, &code->src, &rd) ||
3808 fetch (sd, &code->dst, &res))
3809 goto end;
bf174226 3810
dc5c3759
MS
3811 /* Ye gods, this is non-portable!
3812 However, the existing mul/div code is similar. */
3813 res = SEXTSHORT (res) * SEXTSHORT (rd);
bf174226 3814
dc5c3759
MS
3815 if (h8_get_macS (sd)) /* Saturating mode */
3816 {
3817 long long mac = h8_get_macl (sd);
bf174226 3818
dc5c3759
MS
3819 if (mac & 0x80000000) /* sign extend */
3820 mac |= 0xffffffff00000000LL;
bf174226 3821
dc5c3759
MS
3822 mac += res;
3823 if (mac > 0x7fffffff || mac < 0xffffffff80000000LL)
3824 h8_set_macV (sd, 1);
3825 h8_set_macZ (sd, (mac == 0));
3826 h8_set_macN (sd, (mac < 0));
3827 h8_set_macl (sd, (int) mac);
3828 }
3829 else /* "Less Saturating" mode */
3830 {
3831 long long mac = h8_get_mach (sd);
3832 mac <<= 32;
3833 mac += h8_get_macl (sd);
3834
3835 if (mac & 0x20000000000LL) /* sign extend */
3836 mac |= 0xfffffc0000000000LL;
3837
3838 mac += res;
3839 if (mac > 0x1ffffffffffLL ||
3840 mac < (long long) 0xfffffe0000000000LL)
3841 h8_set_macV (sd, 1);
3842 h8_set_macZ (sd, (mac == 0));
3843 h8_set_macN (sd, (mac < 0));
3844 h8_set_macl (sd, (int) mac);
3845 mac >>= 32;
3846 h8_set_mach (sd, (int) (mac & 0x3ff));
3847 }
bf174226
V
3848 goto next;
3849
dc5c3759
MS
3850 case O (O_MULS, SW): /* muls.w */
3851 if (fetch (sd, &code->src, &ea) ||
3852 fetch (sd, &code->dst, &rd))
3853 goto end;
bf174226 3854
e073c474 3855 ea = SEXTSHORT (ea);
dc5c3759
MS
3856 res = SEXTSHORT (ea * SEXTSHORT (rd));
3857
3858 n = res & 0x8000;
3859 nz = res & 0xffff;
3860 if (store (sd, &code->dst, res))
3861 goto end;
bf174226 3862
bf174226
V
3863 goto next;
3864
dc5c3759
MS
3865 case O (O_MULS, SL): /* muls.l */
3866 if (fetch (sd, &code->src, &ea) ||
3867 fetch (sd, &code->dst, &rd))
3868 goto end;
bf174226 3869
dc5c3759 3870 res = ea * rd;
bf174226 3871
dc5c3759
MS
3872 n = res & 0x80000000;
3873 nz = res & 0xffffffff;
3874 if (store (sd, &code->dst, res))
3875 goto end;
bf174226
V
3876 goto next;
3877
dc5c3759
MS
3878 case O (O_MULSU, SL): /* muls/u.l */
3879 if (fetch (sd, &code->src, &ea) ||
3880 fetch (sd, &code->dst, &rd))
3881 goto end;
bf174226 3882
dc5c3759
MS
3883 /* Compute upper 32 bits of the 64-bit result. */
3884 res = (((long long) ea) * ((long long) rd)) >> 32;
bf174226 3885
dc5c3759
MS
3886 n = res & 0x80000000;
3887 nz = res & 0xffffffff;
3888 if (store (sd, &code->dst, res))
3889 goto end;
3890 goto next;
bf174226 3891
dc5c3759
MS
3892 case O (O_MULU, SW): /* mulu.w */
3893 if (fetch (sd, &code->src, &ea) ||
3894 fetch (sd, &code->dst, &rd))
3895 goto end;
bf174226 3896
dc5c3759
MS
3897 res = UEXTSHORT ((UEXTSHORT (ea) * UEXTSHORT (rd)));
3898
3899 /* Don't set Z or N. */
3900 if (store (sd, &code->dst, res))
3901 goto end;
bf174226 3902
bf174226
V
3903 goto next;
3904
dc5c3759
MS
3905 case O (O_MULU, SL): /* mulu.l */
3906 if (fetch (sd, &code->src, &ea) ||
3907 fetch (sd, &code->dst, &rd))
3908 goto end;
bf174226 3909
dc5c3759 3910 res = ea * rd;
bf174226 3911
dc5c3759
MS
3912 /* Don't set Z or N. */
3913 if (store (sd, &code->dst, res))
3914 goto end;
bf174226 3915
dc5c3759 3916 goto next;
bf174226 3917
dc5c3759
MS
3918 case O (O_MULUU, SL): /* mulu/u.l */
3919 if (fetch (sd, &code->src, &ea) ||
3920 fetch (sd, &code->dst, &rd))
3921 goto end;
bf174226 3922
dc5c3759
MS
3923 /* Compute upper 32 bits of the 64-bit result. */
3924 res = (((unsigned long long) (unsigned) ea) *
3925 ((unsigned long long) (unsigned) rd)) >> 32;
bf174226 3926
dc5c3759
MS
3927 /* Don't set Z or N. */
3928 if (store (sd, &code->dst, res))
3929 goto end;
bf174226 3930
dc5c3759 3931 goto next;
bf174226 3932
dc5c3759
MS
3933 case O (O_MULXS, SB): /* mulxs.b */
3934 if (fetch (sd, &code->src, &ea) ||
3935 fetch (sd, &code->dst, &rd))
3936 goto end;
bf174226 3937
e073c474 3938 ea = SEXTCHAR (ea);
dc5c3759
MS
3939 res = ea * SEXTCHAR (rd);
3940
3941 n = res & 0x8000;
3942 nz = res & 0xffff;
3943 if (store (sd, &code->dst, res))
3944 goto end;
bf174226 3945
bf174226 3946 goto next;
bf174226 3947
dc5c3759
MS
3948 case O (O_MULXS, SW): /* mulxs.w */
3949 if (fetch (sd, &code->src, &ea) ||
3950 fetch (sd, &code->dst, &rd))
c906108c
SS
3951 goto end;
3952
e073c474 3953 ea = SEXTSHORT (ea);
dc5c3759 3954 res = ea * SEXTSHORT (rd & 0xffff);
c906108c 3955
dc5c3759
MS
3956 n = res & 0x80000000;
3957 nz = res & 0xffffffff;
3958 if (store (sd, &code->dst, res))
3959 goto end;
3960
3961 goto next;
c906108c 3962
dc5c3759
MS
3963 case O (O_MULXU, SB): /* mulxu.b */
3964 if (fetch (sd, &code->src, &ea) ||
3965 fetch (sd, &code->dst, &rd))
c906108c 3966 goto end;
c906108c 3967
dc5c3759 3968 res = UEXTCHAR (ea) * UEXTCHAR (rd);
c906108c 3969
dc5c3759
MS
3970 if (store (sd, &code->dst, res))
3971 goto end;
c906108c 3972
dc5c3759 3973 goto next;
c906108c 3974
dc5c3759
MS
3975 case O (O_MULXU, SW): /* mulxu.w */
3976 if (fetch (sd, &code->src, &ea) ||
3977 fetch (sd, &code->dst, &rd))
c906108c 3978 goto end;
c906108c 3979
dc5c3759 3980 res = UEXTSHORT (ea) * UEXTSHORT (rd);
c906108c 3981
dc5c3759
MS
3982 if (store (sd, &code->dst, res))
3983 goto end;
3984
3985 goto next;
c906108c 3986
9f70f8ec
MS
3987 case O (O_TAS, SB): /* tas (test and set) */
3988 if (!h8300sxmode) /* h8sx can use any register. */
3989 switch (code->src.reg)
3990 {
3991 case R0_REGNUM:
3992 case R1_REGNUM:
3993 case R4_REGNUM:
3994 case R5_REGNUM:
3995 break;
3996 default:
3997 goto illegal;
3998 }
3999
dc5c3759
MS
4000 if (fetch (sd, &code->src, &res))
4001 goto end;
4002 if (store (sd, &code->src, res | 0x80))
4003 goto end;
4004
6147b1f6 4005 goto just_flags_log8;
c906108c 4006
dc5c3759
MS
4007 case O (O_DIVU, SW): /* divu.w */
4008 if (fetch (sd, &code->src, &ea) ||
4009 fetch (sd, &code->dst, &rd))
4010 goto end;
c906108c 4011
dc5c3759
MS
4012 n = ea & 0x8000;
4013 nz = ea & 0xffff;
4014 if (ea)
4015 res = (unsigned) (UEXTSHORT (rd) / UEXTSHORT (ea));
4016 else
4017 res = 0;
c906108c 4018
dc5c3759
MS
4019 if (store (sd, &code->dst, res))
4020 goto end;
4021 goto next;
c906108c 4022
dc5c3759
MS
4023 case O (O_DIVU, SL): /* divu.l */
4024 if (fetch (sd, &code->src, &ea) ||
4025 fetch (sd, &code->dst, &rd))
4026 goto end;
4027
4028 n = ea & 0x80000000;
4029 nz = ea & 0xffffffff;
4030 if (ea)
4031 res = (unsigned) rd / ea;
4032 else
4033 res = 0;
4034
4035 if (store (sd, &code->dst, res))
4036 goto end;
4037 goto next;
4038
4039 case O (O_DIVS, SW): /* divs.w */
4040 if (fetch (sd, &code->src, &ea) ||
4041 fetch (sd, &code->dst, &rd))
4042 goto end;
4043
dc5c3759
MS
4044 if (ea)
4045 {
4046 res = SEXTSHORT (rd) / SEXTSHORT (ea);
4047 nz = 1;
4048 }
4049 else
4050 {
4051 res = 0;
4052 nz = 0;
4053 }
4054
4055 n = res & 0x8000;
4056 if (store (sd, &code->dst, res))
4057 goto end;
4058 goto next;
4059
4060 case O (O_DIVS, SL): /* divs.l */
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 = rd / ea;
4068 nz = 1;
4069 }
4070 else
4071 {
4072 res = 0;
4073 nz = 0;
4074 }
4075
4076 n = res & 0x80000000;
4077 if (store (sd, &code->dst, res))
4078 goto end;
4079 goto next;
4080
4081 case O (O_DIVXU, SB): /* divxu.b */
4082 if (fetch (sd, &code->src, &ea) ||
4083 fetch (sd, &code->dst, &rd))
4084 goto end;
4085
4086 rd = UEXTSHORT (rd);
4087 ea = UEXTCHAR (ea);
4088
4089 n = ea & 0x80;
4090 nz = ea & 0xff;
4091 if (ea)
4092 {
4093 tmp = (unsigned) rd % ea;
4094 res = (unsigned) rd / ea;
4095 }
4096 else
4097 {
4098 tmp = 0;
4099 res = 0;
4100 }
4101
9f70f8ec 4102 if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
dc5c3759
MS
4103 goto end;
4104 goto next;
4105
4106 case O (O_DIVXU, SW): /* divxu.w */
4107 if (fetch (sd, &code->src, &ea) ||
4108 fetch (sd, &code->dst, &rd))
4109 goto end;
4110
4111 ea = UEXTSHORT (ea);
4112
4113 n = ea & 0x8000;
4114 nz = ea & 0xffff;
4115 if (ea)
4116 {
4117 tmp = (unsigned) rd % ea;
4118 res = (unsigned) rd / ea;
4119 }
4120 else
4121 {
4122 tmp = 0;
4123 res = 0;
4124 }
4125
4126 if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
4127 goto end;
4128 goto next;
4129
4130 case O (O_DIVXS, SB): /* divxs.b */
4131 if (fetch (sd, &code->src, &ea) ||
4132 fetch (sd, &code->dst, &rd))
4133 goto end;
4134
4135 rd = SEXTSHORT (rd);
e073c474 4136 ea = SEXTCHAR (ea);
dc5c3759
MS
4137
4138 if (ea)
4139 {
4140 tmp = (int) rd % (int) ea;
4141 res = (int) rd / (int) ea;
4142 nz = 1;
4143 }
4144 else
4145 {
4146 tmp = 0;
4147 res = 0;
4148 nz = 0;
4149 }
4150
4151 n = res & 0x8000;
4152 if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
4153 goto end;
4154 goto next;
4155
4156 case O (O_DIVXS, SW): /* divxs.w */
4157 if (fetch (sd, &code->src, &ea) ||
4158 fetch (sd, &code->dst, &rd))
4159 goto end;
4160
e073c474 4161 ea = SEXTSHORT (ea);
dc5c3759
MS
4162
4163 if (ea)
4164 {
4165 tmp = (int) rd % (int) ea;
4166 res = (int) rd / (int) ea;
4167 nz = 1;
4168 }
4169 else
4170 {
4171 tmp = 0;
4172 res = 0;
4173 nz = 0;
4174 }
4175
4176 n = res & 0x80000000;
4177 if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
4178 goto end;
4179 goto next;
4180
4181 case O (O_EXTS, SW): /* exts.w, signed extend */
4182 if (fetch2 (sd, &code->dst, &rd))
4183 goto end;
c906108c 4184 ea = rd & 0x80 ? -256 : 0;
dc5c3759 4185 res = (rd & 0xff) + ea;
c906108c 4186 goto log16;
dc5c3759
MS
4187
4188 case O (O_EXTS, SL): /* exts.l, signed extend */
4189 if (fetch2 (sd, &code->dst, &rd))
4190 goto end;
4191 if (code->src.type == X (OP_IMM, SL))
4192 {
4193 if (fetch (sd, &code->src, &ea))
4194 goto end;
4195
4196 if (ea == 2) /* exts.l #2, nn */
4197 {
4198 /* Sign-extend from 8-bit to 32-bit. */
4199 ea = rd & 0x80 ? -256 : 0;
4200 res = (rd & 0xff) + ea;
4201 goto log32;
4202 }
4203 }
4204 /* Sign-extend from 16-bit to 32-bit. */
c906108c 4205 ea = rd & 0x8000 ? -65536 : 0;
dc5c3759 4206 res = (rd & 0xffff) + ea;
c906108c 4207 goto log32;
dc5c3759
MS
4208
4209 case O (O_EXTU, SW): /* extu.w, unsigned extend */
4210 if (fetch2 (sd, &code->dst, &rd))
4211 goto end;
c906108c 4212 ea = 0;
dc5c3759 4213 res = (rd & 0xff) + ea;
c906108c 4214 goto log16;
dc5c3759
MS
4215
4216 case O (O_EXTU, SL): /* extu.l, unsigned extend */
4217 if (fetch2 (sd, &code->dst, &rd))
4218 goto end;
4219 if (code->src.type == X (OP_IMM, SL))
4220 {
4221 if (fetch (sd, &code->src, &ea))
4222 goto end;
4223
4224 if (ea == 2) /* extu.l #2, nn */
4225 {
4226 /* Zero-extend from 8-bit to 32-bit. */
4227 ea = 0;
4228 res = (rd & 0xff) + ea;
4229 goto log32;
4230 }
4231 }
4232 /* Zero-extend from 16-bit to 32-bit. */
c906108c 4233 ea = 0;
dc5c3759 4234 res = (rd & 0xffff) + ea;
c906108c
SS
4235 goto log32;
4236
dc5c3759 4237 case O (O_NOP, SN): /* nop */
c906108c
SS
4238 goto next;
4239
dc5c3759 4240 case O (O_STM, SL): /* stm, store to memory */
c906108c
SS
4241 {
4242 int nregs, firstreg, i;
4243
4244 nregs = GET_MEMORY_B (pc + 1);
4245 nregs >>= 4;
4246 nregs &= 0xf;
dc5c3759 4247 firstreg = code->src.reg;
c906108c
SS
4248 firstreg &= 0xf;
4249 for (i = firstreg; i <= firstreg + nregs; i++)
4250 {
dc5c3759
MS
4251 h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) - 4);
4252 SET_MEMORY_L (h8_get_reg (sd, SP_REGNUM), h8_get_reg (sd, i));
c906108c
SS
4253 }
4254 }
4255 goto next;
4256
dc5c3759 4257 case O (O_LDM, SL): /* ldm, load from memory */
9f70f8ec
MS
4258 case O (O_RTEL, SN): /* rte/l, ldm plus rte */
4259 case O (O_RTSL, SN): /* rts/l, ldm plus rts */
c906108c
SS
4260 {
4261 int nregs, firstreg, i;
4262
9f70f8ec
MS
4263 nregs = ((GET_MEMORY_B (pc + 1) >> 4) & 0xf);
4264 firstreg = code->dst.reg & 0xf;
c906108c
SS
4265 for (i = firstreg; i >= firstreg - nregs; i--)
4266 {
dc5c3759
MS
4267 h8_set_reg (sd, i, GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM)));
4268 h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) + 4);
c906108c
SS
4269 }
4270 }
9f70f8ec
MS
4271 switch (code->opcode) {
4272 case O (O_RTEL, SN):
4273 goto rte;
4274 case O (O_RTSL, SN):
4275 goto rts;
4276 case O (O_LDM, SL):
4277 goto next;
4278 default:
4279 goto illegal;
4280 }
c906108c 4281
b7f97e9c
MS
4282 case O (O_DAA, SB):
4283 /* Decimal Adjust Addition. This is for BCD arithmetic. */
9f70f8ec 4284 res = GET_B_REG (code->src.reg); /* FIXME fetch? */
dc5c3759
MS
4285 if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4286 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
b7f97e9c 4287 res = res; /* Value added == 0. */
dc5c3759
MS
4288 else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8) &&
4289 !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
b7f97e9c 4290 res = res + 0x6; /* Value added == 6. */
dc5c3759
MS
4291 else if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4292 h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
b7f97e9c 4293 res = res + 0x6; /* Value added == 6. */
dc5c3759
MS
4294 else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15) &&
4295 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
4296 res = res + 0x60; /* Value added == 60. */
4297 else if (!c && (9 <= (res >> 4) && (res >> 4) <= 15) &&
4298 !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
4299 res = res + 0x66; /* Value added == 66. */
4300 else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15) &&
4301 h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
4302 res = res + 0x66; /* Value added == 66. */
4303 else if ( c && (1 <= (res >> 4) && (res >> 4) <= 2) &&
4304 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
b7f97e9c 4305 res = res + 0x60; /* Value added == 60. */
dc5c3759
MS
4306 else if ( c && (1 <= (res >> 4) && (res >> 4) <= 2) &&
4307 !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
b7f97e9c 4308 res = res + 0x66; /* Value added == 66. */
dc5c3759
MS
4309 else if (c && (1 <= (res >> 4) && (res >> 4) <= 3) &&
4310 h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
b7f97e9c 4311 res = res + 0x66; /* Value added == 66. */
b7f97e9c
MS
4312
4313 goto alu8;
4314
4315 case O (O_DAS, SB):
4316 /* Decimal Adjust Subtraction. This is for BCD arithmetic. */
4317 res = GET_B_REG (code->src.reg); /* FIXME fetch, fetch2... */
dc5c3759
MS
4318 if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4319 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
b7f97e9c 4320 res = res; /* Value added == 0. */
dc5c3759
MS
4321 else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8) &&
4322 h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
b7f97e9c 4323 res = res + 0xfa; /* Value added == 0xfa. */
dc5c3759
MS
4324 else if ( c && (7 <= (res >> 4) && (res >> 4) <= 15) &&
4325 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
b7f97e9c 4326 res = res + 0xa0; /* Value added == 0xa0. */
dc5c3759
MS
4327 else if (c && (6 <= (res >> 4) && (res >> 4) <= 15) &&
4328 h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
b7f97e9c
MS
4329 res = res + 0x9a; /* Value added == 0x9a. */
4330
4331 goto alu8;
4332
c906108c 4333 default:
d0fe2f7e 4334 illegal:
dc5c3759 4335 sim_engine_set_run_state (sd, sim_stopped, SIGILL);
c906108c
SS
4336 goto end;
4337
4338 }
dc5c3759
MS
4339
4340 (*sim_callback->printf_filtered) (sim_callback,
4341 "sim_resume: internal error.\n");
4342 sim_engine_set_run_state (sd, sim_stopped, SIGILL);
4343 goto end;
c906108c
SS
4344
4345 setc:
dc5c3759
MS
4346 if (code->dst.type == X (OP_CCR, SB) ||
4347 code->dst.type == X (OP_CCR, SW))
c3f4437e 4348 {
dc5c3759 4349 h8_set_ccr (sd, res);
9f70f8ec 4350 GETSR (sd);
c3f4437e 4351 }
dc5c3759
MS
4352 else if (h8300smode &&
4353 (code->dst.type == X (OP_EXR, SB) ||
4354 code->dst.type == X (OP_EXR, SW)))
c3f4437e 4355 {
dc5c3759
MS
4356 h8_set_exr (sd, res);
4357 if (h8300smode) /* Get exr. */
4358 {
4359 trace = (h8_get_exr (sd) >> 7) & 1;
4360 intMask = h8_get_exr (sd) & 7;
4361 }
c3f4437e 4362 }
fc974602 4363 else
c3f4437e 4364 goto illegal;
fc974602 4365
c906108c
SS
4366 goto next;
4367
4368 condtrue:
4369 /* When a branch works */
dc5c3759
MS
4370 if (fetch (sd, &code->src, &res))
4371 goto end;
4372 if (res & 1) /* bad address */
4373 goto illegal;
4374 pc = code->next_pc + res;
c906108c
SS
4375 goto end;
4376
4377 /* Set the cond codes from res */
4378 bitop:
4379
4380 /* Set the flags after an 8 bit inc/dec operation */
4381 just_flags_inc8:
4382 n = res & 0x80;
4383 nz = res & 0xff;
4384 v = (rd & 0x7f) == 0x7f;
4385 goto next;
4386
c906108c
SS
4387 /* Set the flags after an 16 bit inc/dec operation */
4388 just_flags_inc16:
4389 n = res & 0x8000;
4390 nz = res & 0xffff;
4391 v = (rd & 0x7fff) == 0x7fff;
4392 goto next;
4393
c906108c
SS
4394 /* Set the flags after an 32 bit inc/dec operation */
4395 just_flags_inc32:
4396 n = res & 0x80000000;
4397 nz = res & 0xffffffff;
4398 v = (rd & 0x7fffffff) == 0x7fffffff;
4399 goto next;
4400
c906108c
SS
4401 shift8:
4402 /* Set flags after an 8 bit shift op, carry,overflow set in insn */
4403 n = (rd & 0x80);
4404 nz = rd & 0xff;
dc5c3759
MS
4405 if (store2 (sd, &code->dst, rd))
4406 goto end;
c906108c
SS
4407 goto next;
4408
4409 shift16:
4410 /* Set flags after an 16 bit shift op, carry,overflow set in insn */
4411 n = (rd & 0x8000);
4412 nz = rd & 0xffff;
dc5c3759
MS
4413 if (store2 (sd, &code->dst, rd))
4414 goto end;
c906108c
SS
4415 goto next;
4416
4417 shift32:
4418 /* Set flags after an 32 bit shift op, carry,overflow set in insn */
4419 n = (rd & 0x80000000);
4420 nz = rd & 0xffffffff;
dc5c3759
MS
4421 if (store2 (sd, &code->dst, rd))
4422 goto end;
c906108c
SS
4423 goto next;
4424
4425 log32:
dc5c3759
MS
4426 if (store2 (sd, &code->dst, res))
4427 goto end;
4428
c906108c
SS
4429 just_flags_log32:
4430 /* flags after a 32bit logical operation */
4431 n = res & 0x80000000;
4432 nz = res & 0xffffffff;
4433 v = 0;
4434 goto next;
4435
4436 log16:
dc5c3759
MS
4437 if (store2 (sd, &code->dst, res))
4438 goto end;
4439
c906108c
SS
4440 just_flags_log16:
4441 /* flags after a 16bit logical operation */
4442 n = res & 0x8000;
4443 nz = res & 0xffff;
4444 v = 0;
4445 goto next;
4446
c906108c 4447 log8:
dc5c3759
MS
4448 if (store2 (sd, &code->dst, res))
4449 goto end;
4450
c906108c
SS
4451 just_flags_log8:
4452 n = res & 0x80;
4453 nz = res & 0xff;
4454 v = 0;
4455 goto next;
4456
4457 alu8:
dc5c3759
MS
4458 if (store2 (sd, &code->dst, res))
4459 goto end;
4460
c906108c
SS
4461 just_flags_alu8:
4462 n = res & 0x80;
4463 nz = res & 0xff;
4464 c = (res & 0x100);
4465 switch (code->opcode / 4)
4466 {
4467 case O_ADD:
dc5c3759 4468 case O_ADDX:
c906108c
SS
4469 v = ((rd & 0x80) == (ea & 0x80)
4470 && (rd & 0x80) != (res & 0x80));
4471 break;
4472 case O_SUB:
dc5c3759 4473 case O_SUBX:
c906108c
SS
4474 case O_CMP:
4475 v = ((rd & 0x80) != (-ea & 0x80)
4476 && (rd & 0x80) != (res & 0x80));
4477 break;
4478 case O_NEG:
4479 v = (rd == 0x80);
4480 break;
dc5c3759
MS
4481 case O_DAA:
4482 case O_DAS:
4483 break; /* No effect on v flag. */
c906108c
SS
4484 }
4485 goto next;
4486
4487 alu16:
dc5c3759
MS
4488 if (store2 (sd, &code->dst, res))
4489 goto end;
4490
c906108c
SS
4491 just_flags_alu16:
4492 n = res & 0x8000;
4493 nz = res & 0xffff;
4494 c = (res & 0x10000);
4495 switch (code->opcode / 4)
4496 {
4497 case O_ADD:
dc5c3759 4498 case O_ADDX:
c906108c
SS
4499 v = ((rd & 0x8000) == (ea & 0x8000)
4500 && (rd & 0x8000) != (res & 0x8000));
4501 break;
4502 case O_SUB:
dc5c3759 4503 case O_SUBX:
c906108c
SS
4504 case O_CMP:
4505 v = ((rd & 0x8000) != (-ea & 0x8000)
4506 && (rd & 0x8000) != (res & 0x8000));
4507 break;
4508 case O_NEG:
4509 v = (rd == 0x8000);
4510 break;
4511 }
4512 goto next;
4513
4514 alu32:
dc5c3759
MS
4515 if (store2 (sd, &code->dst, res))
4516 goto end;
4517
c906108c
SS
4518 just_flags_alu32:
4519 n = res & 0x80000000;
4520 nz = res & 0xffffffff;
4521 switch (code->opcode / 4)
4522 {
4523 case O_ADD:
dc5c3759 4524 case O_ADDX:
c906108c
SS
4525 v = ((rd & 0x80000000) == (ea & 0x80000000)
4526 && (rd & 0x80000000) != (res & 0x80000000));
dc5c3759
MS
4527 c = ((unsigned) res < (unsigned) rd) ||
4528 ((unsigned) res < (unsigned) ea);
c906108c
SS
4529 break;
4530 case O_SUB:
dc5c3759 4531 case O_SUBX:
c906108c
SS
4532 case O_CMP:
4533 v = ((rd & 0x80000000) != (-ea & 0x80000000)
4534 && (rd & 0x80000000) != (res & 0x80000000));
4535 c = (unsigned) rd < (unsigned) -ea;
4536 break;
4537 case O_NEG:
4538 v = (rd == 0x80000000);
4539 c = res != 0;
4540 break;
4541 }
4542 goto next;
4543
dc5c3759
MS
4544 next:
4545 if ((res = h8_get_delayed_branch (sd)) != 0)
4546 {
4547 pc = res;
4548 h8_set_delayed_branch (sd, 0);
4549 }
4550 else
4551 pc = code->next_pc;
c906108c
SS
4552
4553 end:
dc5c3759 4554
c906108c
SS
4555 if (--poll_count < 0)
4556 {
7a292a7a 4557 poll_count = POLL_QUIT_INTERVAL;
c906108c
SS
4558 if ((*sim_callback->poll_quit) != NULL
4559 && (*sim_callback->poll_quit) (sim_callback))
dc5c3759 4560 sim_engine_set_run_state (sd, sim_stopped, SIGINT);
c906108c 4561 }
dc5c3759
MS
4562 sim_engine_get_run_state (sd, &reason, &sigrc);
4563 } while (reason == sim_running);
c906108c 4564
dc5c3759
MS
4565 h8_set_ticks (sd, h8_get_ticks (sd) + get_now () - tick_start);
4566 h8_set_cycles (sd, h8_get_cycles (sd) + cycles);
4567 h8_set_insts (sd, h8_get_insts (sd) + insts);
4568 h8_set_pc (sd, pc);
4569 BUILDSR (sd);
4570
4571 if (h8300smode)
4572 h8_set_exr (sd, (trace<<7) | intMask);
4573
4574 h8_set_mask (sd, oldmask);
c906108c
SS
4575}
4576
c906108c 4577int
5558e7e6 4578sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
c906108c
SS
4579{
4580 int i;
4581
dc5c3759 4582 init_pointers (sd);
c906108c
SS
4583 if (addr < 0)
4584 return 0;
4585 for (i = 0; i < size; i++)
4586 {
4587 if (addr < memory_size)
4588 {
dc5c3759
MS
4589 h8_set_memory (sd, addr + i, buffer[i]);
4590 h8_set_cache_idx (sd, addr + i, 0);
c906108c
SS
4591 }
4592 else
dc5c3759
MS
4593 {
4594 h8_set_eightbit (sd, (addr + i) & 0xff, buffer[i]);
4595 }
c906108c
SS
4596 }
4597 return size;
4598}
4599
4600int
a4f27e3e 4601sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
c906108c 4602{
dc5c3759 4603 init_pointers (sd);
c906108c
SS
4604 if (addr < 0)
4605 return 0;
4606 if (addr < memory_size)
dc5c3759 4607 memcpy (buffer, h8_get_memory_buf (sd) + addr, size);
c906108c 4608 else
dc5c3759 4609 memcpy (buffer, h8_get_eightbit_buf (sd) + (addr & 0xff), size);
c906108c
SS
4610 return size;
4611}
4612
4613
c906108c 4614int
a4f27e3e 4615sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length)
c906108c
SS
4616{
4617 int longval;
4618 int shortval;
4619 int intval;
4620 longval = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
4621 shortval = (value[0] << 8) | (value[1]);
4622 intval = h8300hmode ? longval : shortval;
4623
dc5c3759 4624 init_pointers (sd);
c906108c
SS
4625 switch (rn)
4626 {
9f70f8ec 4627 case PC_REGNUM:
59768597
SA
4628 if(h8300_normal_mode)
4629 h8_set_pc (sd, shortval); /* PC for Normal mode is 2 bytes */
4630 else
4631 h8_set_pc (sd, intval);
9f70f8ec 4632 break;
c906108c 4633 default:
dc5c3759
MS
4634 (*sim_callback->printf_filtered) (sim_callback,
4635 "sim_store_register: bad regnum %d.\n",
4636 rn);
c906108c
SS
4637 case R0_REGNUM:
4638 case R1_REGNUM:
4639 case R2_REGNUM:
4640 case R3_REGNUM:
4641 case R4_REGNUM:
4642 case R5_REGNUM:
4643 case R6_REGNUM:
4644 case R7_REGNUM:
dc5c3759 4645 h8_set_reg (sd, rn, intval);
c906108c
SS
4646 break;
4647 case CCR_REGNUM:
dc5c3759 4648 h8_set_ccr (sd, intval);
c906108c 4649 break;
fc974602 4650 case EXR_REGNUM:
dc5c3759 4651 h8_set_exr (sd, intval);
fc974602 4652 break;
173b1c98
MS
4653 case SBR_REGNUM:
4654 h8_set_sbr (sd, intval);
4655 break;
4656 case VBR_REGNUM:
4657 h8_set_vbr (sd, intval);
4658 break;
4659 case MACH_REGNUM:
4660 h8_set_mach (sd, intval);
4661 break;
4662 case MACL_REGNUM:
4663 h8_set_macl (sd, intval);
4664 break;
c906108c 4665 case CYCLE_REGNUM:
dc5c3759 4666 h8_set_cycles (sd, longval);
c906108c 4667 break;
9f70f8ec 4668
c906108c 4669 case INST_REGNUM:
dc5c3759 4670 h8_set_insts (sd, longval);
c906108c 4671 break;
9f70f8ec 4672
c906108c 4673 case TICK_REGNUM:
dc5c3759 4674 h8_set_ticks (sd, longval);
c906108c
SS
4675 break;
4676 }
dae477fe 4677 return length;
c906108c
SS
4678}
4679
4680int
a4f27e3e 4681sim_fetch_register (SIM_DESC sd, int rn, unsigned char *buf, int length)
c906108c
SS
4682{
4683 int v;
4684 int longreg = 0;
4685
dc5c3759 4686 init_pointers (sd);
c906108c 4687
d0fe2f7e 4688 if (!h8300smode && rn >= EXR_REGNUM)
c3f4437e 4689 rn++;
c906108c
SS
4690 switch (rn)
4691 {
4692 default:
dc5c3759
MS
4693 (*sim_callback->printf_filtered) (sim_callback,
4694 "sim_fetch_register: bad regnum %d.\n",
4695 rn);
4696 v = 0;
4697 break;
3b02cf92 4698 case CCR_REGNUM:
dc5c3759 4699 v = h8_get_ccr (sd);
c906108c 4700 break;
fc974602 4701 case EXR_REGNUM:
dc5c3759 4702 v = h8_get_exr (sd);
fc974602 4703 break;
3b02cf92 4704 case PC_REGNUM:
dc5c3759 4705 v = h8_get_pc (sd);
c906108c 4706 break;
173b1c98
MS
4707 case SBR_REGNUM:
4708 v = h8_get_sbr (sd);
4709 break;
4710 case VBR_REGNUM:
4711 v = h8_get_vbr (sd);
4712 break;
4713 case MACH_REGNUM:
4714 v = h8_get_mach (sd);
4715 break;
4716 case MACL_REGNUM:
4717 v = h8_get_macl (sd);
4718 break;
c906108c
SS
4719 case R0_REGNUM:
4720 case R1_REGNUM:
4721 case R2_REGNUM:
4722 case R3_REGNUM:
4723 case R4_REGNUM:
4724 case R5_REGNUM:
4725 case R6_REGNUM:
4726 case R7_REGNUM:
dc5c3759 4727 v = h8_get_reg (sd, rn);
c906108c 4728 break;
3b02cf92 4729 case CYCLE_REGNUM:
dc5c3759 4730 v = h8_get_cycles (sd);
c906108c
SS
4731 longreg = 1;
4732 break;
3b02cf92 4733 case TICK_REGNUM:
dc5c3759 4734 v = h8_get_ticks (sd);
c906108c
SS
4735 longreg = 1;
4736 break;
3b02cf92 4737 case INST_REGNUM:
dc5c3759 4738 v = h8_get_insts (sd);
c906108c
SS
4739 longreg = 1;
4740 break;
4741 }
59768597
SA
4742 /* In Normal mode PC is 2 byte, but other registers are 4 byte */
4743 if ((h8300hmode || longreg) && !(rn == PC_REGNUM && h8300_normal_mode))
c906108c
SS
4744 {
4745 buf[0] = v >> 24;
4746 buf[1] = v >> 16;
4747 buf[2] = v >> 8;
4748 buf[3] = v >> 0;
4749 }
4750 else
4751 {
4752 buf[0] = v >> 8;
4753 buf[1] = v;
4754 }
4755 return -1;
4756}
4757
dc5c3759
MS
4758static void
4759set_simcache_size (SIM_DESC sd, int n)
c906108c 4760{
dc5c3759
MS
4761 if (sd->sim_cache)
4762 free (sd->sim_cache);
c906108c
SS
4763 if (n < 2)
4764 n = 2;
dc5c3759
MS
4765 sd->sim_cache = (decoded_inst *) malloc (sizeof (decoded_inst) * n);
4766 memset (sd->sim_cache, 0, sizeof (decoded_inst) * n);
4767 sd->sim_cache_size = n;
c906108c
SS
4768}
4769
4770
4771void
a4f27e3e 4772sim_info (SIM_DESC sd, int verbose)
c906108c 4773{
dc5c3759
MS
4774 double timetaken = (double) h8_get_ticks (sd) / (double) now_persec ();
4775 double virttime = h8_get_cycles (sd) / 10.0e6;
c906108c
SS
4776
4777 (*sim_callback->printf_filtered) (sim_callback,
4778 "\n\n#instructions executed %10d\n",
dc5c3759 4779 h8_get_insts (sd));
c906108c
SS
4780 (*sim_callback->printf_filtered) (sim_callback,
4781 "#cycles (v approximate) %10d\n",
dc5c3759 4782 h8_get_cycles (sd));
c906108c
SS
4783 (*sim_callback->printf_filtered) (sim_callback,
4784 "#real time taken %10.4f\n",
4785 timetaken);
4786 (*sim_callback->printf_filtered) (sim_callback,
e8c1a4e7 4787 "#virtual time taken %10.4f\n",
c906108c
SS
4788 virttime);
4789 if (timetaken != 0.0)
4790 (*sim_callback->printf_filtered) (sim_callback,
4791 "#simulation ratio %10.4f\n",
4792 virttime / timetaken);
4793 (*sim_callback->printf_filtered) (sim_callback,
4794 "#compiles %10d\n",
dc5c3759 4795 h8_get_compiles (sd));
c906108c
SS
4796 (*sim_callback->printf_filtered) (sim_callback,
4797 "#cache size %10d\n",
dc5c3759 4798 sd->sim_cache_size);
c906108c
SS
4799
4800#ifdef ADEBUG
4801 /* This to be conditional on `what' (aka `verbose'),
4802 however it was never passed as non-zero. */
4803 if (1)
4804 {
4805 int i;
4806 for (i = 0; i < O_LAST; i++)
4807 {
dc5c3759
MS
4808 if (h8_get_stats (sd, i))
4809 (*sim_callback->printf_filtered) (sim_callback, "%d: %d\n",
4810 i, h8_get_stats (sd, i));
c906108c
SS
4811 }
4812 }
4813#endif
4814}
4815
2ea716f6
KH
4816/* Indicate whether the cpu is an H8/300 or H8/300H.
4817 FLAG is non-zero for the H8/300H. */
c906108c
SS
4818
4819void
27ebfdf4 4820set_h8300h (unsigned long machine)
c906108c
SS
4821{
4822 /* FIXME: Much of the code in sim_load can be moved to sim_open.
4823 This function being replaced by a sim_open:ARGV configuration
2ea716f6 4824 option. */
dc5c3759 4825
454d0511
DD
4826 h8300hmode = h8300smode = h8300sxmode = h8300_normal_mode = 0;
4827
9f70f8ec 4828 if (machine == bfd_mach_h8300sx || machine == bfd_mach_h8300sxn)
27ebfdf4
MS
4829 h8300sxmode = 1;
4830
4831 if (machine == bfd_mach_h8300s || machine == bfd_mach_h8300sn || h8300sxmode)
4832 h8300smode = 1;
4833
4834 if (machine == bfd_mach_h8300h || machine == bfd_mach_h8300hn || h8300smode)
4835 h8300hmode = 1;
59768597
SA
4836
4837 if(machine == bfd_mach_h8300hn || machine == bfd_mach_h8300sn || machine == bfd_mach_h8300sxn)
4838 h8300_normal_mode = 1;
dc5c3759
MS
4839}
4840
27b97b40
MF
4841static sim_cia
4842h8300_pc_get (sim_cpu *cpu)
4843{
4844 return cpu->pc;
4845}
4846
4847static void
4848h8300_pc_set (sim_cpu *cpu, sim_cia pc)
4849{
4850 cpu->pc = pc;
4851}
4852
dc5c3759
MS
4853/* Cover function of sim_state_free to free the cpu buffers as well. */
4854
4855static void
4856free_state (SIM_DESC sd)
4857{
4858 if (STATE_MODULES (sd) != NULL)
4859 sim_module_uninstall (sd);
4860
4861 /* Fixme: free buffers in _sim_cpu. */
4862 sim_state_free (sd);
c906108c
SS
4863}
4864
4865SIM_DESC
a4f27e3e 4866sim_open (SIM_OPEN_KIND kind,
dc5c3759 4867 struct host_callback_struct *callback,
6b4a8935 4868 struct bfd *abfd,
a4f27e3e 4869 char **argv)
c906108c 4870{
27b97b40 4871 int i;
dc5c3759
MS
4872 SIM_DESC sd;
4873 sim_cpu *cpu;
4874
4875 sd = sim_state_alloc (kind, callback);
f95f4ed2
MF
4876
4877 /* The cpu data is kept in a separately allocated chunk of memory. */
4878 if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
4879 {
4880 free_state (sd);
4881 return 0;
4882 }
4883
dc5c3759
MS
4884 cpu = STATE_CPU (sd, 0);
4885 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
4886 sim_state_initialize (sd, cpu);
4887 /* sim_cpu object is new, so some initialization is needed. */
4888 init_pointers_needed = 1;
4889
4890 /* For compatibility (FIXME: is this right?). */
4891 current_alignment = NONSTRICT_ALIGNMENT;
4892 current_target_byte_order = BIG_ENDIAN;
4893
4894 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
4895 {
4896 free_state (sd);
4897 return 0;
4898 }
4899
4900 /* getopt will print the error message so we just have to exit if
4901 this fails. FIXME: Hmmm... in the case of gdb we need getopt
4902 to call print_filtered. */
4903 if (sim_parse_args (sd, argv) != SIM_RC_OK)
4904 {
4905 /* Uninstall the modules to avoid memory leaks,
4906 file descriptor leaks, etc. */
4907 free_state (sd);
4908 return 0;
4909 }
4910
4911 /* Check for/establish the a reference program image. */
4912 if (sim_analyze_program (sd,
4913 (STATE_PROG_ARGV (sd) != NULL
4914 ? *STATE_PROG_ARGV (sd)
4915 : NULL), abfd) != SIM_RC_OK)
4916 {
4917 free_state (sd);
4918 return 0;
4919 }
4920
4921 /* Establish any remaining configuration options. */
4922 if (sim_config (sd) != SIM_RC_OK)
4923 {
4924 free_state (sd);
4925 return 0;
4926 }
4927
4928 if (sim_post_argv_init (sd) != SIM_RC_OK)
4929 {
4930 /* Uninstall the modules to avoid memory leaks,
4931 file descriptor leaks, etc. */
4932 free_state (sd);
4933 return 0;
4934 }
4935
27b97b40
MF
4936 /* CPU specific initialization. */
4937 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
4938 {
4939 SIM_CPU *cpu = STATE_CPU (sd, i);
4940
4941 CPU_PC_FETCH (cpu) = h8300_pc_get;
4942 CPU_PC_STORE (cpu) = h8300_pc_set;
4943 }
4944
dc5c3759
MS
4945 /* sim_hw_configure (sd); */
4946
2ea716f6 4947 /* FIXME: Much of the code in sim_load can be moved here. */
c906108c
SS
4948
4949 sim_kind = kind;
4950 myname = argv[0];
dc5c3759
MS
4951 sim_callback = callback;
4952 return sd;
c906108c
SS
4953}
4954
c906108c
SS
4955/* Called by gdb to load a program into memory. */
4956
4957SIM_RC
b2b255bd 4958sim_load (SIM_DESC sd, const char *prog, bfd *abfd, int from_tty)
c906108c
SS
4959{
4960 bfd *prog_bfd;
4961
2ea716f6
KH
4962 /* FIXME: The code below that sets a specific variant of the H8/300
4963 being simulated should be moved to sim_open(). */
c906108c 4964
2ea716f6 4965 /* See if the file is for the H8/300 or H8/300H. */
c906108c
SS
4966 /* ??? This may not be the most efficient way. The z8k simulator
4967 does this via a different mechanism (INIT_EXTRA_SYMTAB_INFO). */
4968 if (abfd != NULL)
4969 prog_bfd = abfd;
4970 else
3d29fdb4 4971 prog_bfd = bfd_openr (prog, NULL);
c906108c
SS
4972 if (prog_bfd != NULL)
4973 {
4974 /* Set the cpu type. We ignore failure from bfd_check_format
4975 and bfd_openr as sim_load_file checks too. */
de9b1892 4976 if (bfd_check_format (prog_bfd, bfd_object))
c906108c 4977 {
27ebfdf4 4978 set_h8300h (bfd_get_mach (prog_bfd));
c906108c
SS
4979 }
4980 }
4981
4982 /* If we're using gdb attached to the simulator, then we have to
4983 reallocate memory for the simulator.
4984
4985 When gdb first starts, it calls fetch_registers (among other
4986 functions), which in turn calls init_pointers, which allocates
4987 simulator memory.
4988
4989 The problem is when we do that, we don't know whether we're
2ea716f6 4990 debugging an H8/300 or H8/300H program.
c906108c
SS
4991
4992 This is the first point at which we can make that determination,
4993 so we just reallocate memory now; this will also allow us to handle
2ea716f6 4994 switching between H8/300 and H8/300H programs without exiting
c906108c 4995 gdb. */
a8cdafbd 4996
59768597 4997 if (h8300smode && !h8300_normal_mode)
a8cdafbd 4998 memory_size = H8300S_MSIZE;
59768597 4999 else if (h8300hmode && !h8300_normal_mode)
c906108c
SS
5000 memory_size = H8300H_MSIZE;
5001 else
5002 memory_size = H8300_MSIZE;
5003
dc5c3759
MS
5004 if (h8_get_memory_buf (sd))
5005 free (h8_get_memory_buf (sd));
5006 if (h8_get_cache_idx_buf (sd))
5007 free (h8_get_cache_idx_buf (sd));
5008 if (h8_get_eightbit_buf (sd))
5009 free (h8_get_eightbit_buf (sd));
c906108c 5010
dc5c3759
MS
5011 h8_set_memory_buf (sd, (unsigned char *)
5012 calloc (sizeof (char), memory_size));
5013 h8_set_cache_idx_buf (sd, (unsigned short *)
5014 calloc (sizeof (short), memory_size));
e4d3c499 5015 sd->memory_size = memory_size;
dc5c3759 5016 h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256));
c906108c 5017
2ea716f6 5018 /* `msize' must be a power of two. */
c906108c 5019 if ((memory_size & (memory_size - 1)) != 0)
dc5c3759
MS
5020 {
5021 (*sim_callback->printf_filtered) (sim_callback,
5022 "sim_load: bad memory size.\n");
5023 return SIM_RC_FAIL;
5024 }
5025 h8_set_mask (sd, memory_size - 1);
c906108c
SS
5026
5027 if (sim_load_file (sd, myname, sim_callback, prog, prog_bfd,
5028 sim_kind == SIM_OPEN_DEBUG,
5029 0, sim_write)
5030 == NULL)
5031 {
5032 /* Close the bfd if we opened it. */
5033 if (abfd == NULL && prog_bfd != NULL)
5034 bfd_close (prog_bfd);
5035 return SIM_RC_FAIL;
5036 }
5037
5038 /* Close the bfd if we opened it. */
5039 if (abfd == NULL && prog_bfd != NULL)
5040 bfd_close (prog_bfd);
5041 return SIM_RC_OK;
5042}
5043
5044SIM_RC
6b4a8935 5045sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
c906108c 5046{
d1360fb0
V
5047 int i = 0;
5048 int len_arg = 0;
5049 int no_of_args = 0;
dc5c3759 5050
c906108c 5051 if (abfd != NULL)
dc5c3759 5052 h8_set_pc (sd, bfd_get_start_address (abfd));
c906108c 5053 else
dc5c3759 5054 h8_set_pc (sd, 0);
d1360fb0
V
5055
5056 /* Command Line support. */
5057 if (argv != NULL)
5058 {
5059 /* Counting the no. of commandline arguments. */
5060 for (no_of_args = 0; argv[no_of_args] != NULL; no_of_args++)
5061 continue;
5062
5063 /* Allocating memory for the argv pointers. */
dc5c3759
MS
5064 h8_set_command_line (sd, (char **) malloc ((sizeof (char *))
5065 * (no_of_args + 1)));
d1360fb0
V
5066
5067 for (i = 0; i < no_of_args; i++)
5068 {
d1360fb0 5069 /* Copying the argument string. */
dc5c3759 5070 h8_set_cmdline_arg (sd, i, (char *) strdup (argv[i]));
d1360fb0 5071 }
dc5c3759 5072 h8_set_cmdline_arg (sd, i, NULL);
d1360fb0
V
5073 }
5074
c906108c
SS
5075 return SIM_RC_OK;
5076}