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