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