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