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