]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/h8300/compile.c
* readelf.c (print_symbol): Handle symbol characters as unsigned.
[thirdparty/binutils-gdb.git] / sim / h8300 / compile.c
CommitLineData
c906108c 1/*
9f70f8ec 2 * Simulator for the Renesas (formerly Hitachi) H8/300 architecture.
c906108c
SS
3 *
4 * Written by Steve Chamberlain of Cygnus Support. sac@cygnus.com
5 *
6 * This file is part of H8/300 sim
7 *
8 *
9 * THIS SOFTWARE IS NOT COPYRIGHTED
10 *
11 * Cygnus offers the following for use in the public domain. Cygnus makes no
12 * warranty with regard to the software or its performance and the user
13 * accepts the software "AS IS" with all faults.
14 *
15 * CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS
16 * SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
17 * AND FITNESS FOR A PARTICULAR PURPOSE.
18 */
19
c906108c
SS
20#include <signal.h>
21#ifdef HAVE_TIME_H
22#include <time.h>
23#endif
24#ifdef HAVE_STDLIB_H
25#include <stdlib.h>
26#endif
27#ifdef HAVE_SYS_PARAM_H
28#include <sys/param.h>
29#endif
dc5c3759 30
c906108c 31#include "bfd.h"
dc5c3759 32#include "sim-main.h"
a64bfde3 33#include "gdb/sim-h8300.h"
bf174226
V
34#include "sys/stat.h"
35#include "sys/types.h"
c906108c
SS
36
37#ifndef SIGTRAP
38# define SIGTRAP 5
39#endif
40
41int debug;
42
43host_callback *sim_callback;
44
45static SIM_OPEN_KIND sim_kind;
46static char *myname;
47
48/* FIXME: Needs to live in header file.
49 This header should also include the things in remote-sim.h.
50 One could move this to remote-sim.h but this function isn't needed
51 by gdb. */
dc5c3759 52static void set_simcache_size (SIM_DESC, int);
c906108c 53
dc5c3759 54#define X(op, size) (op * 4 + size)
c906108c 55
59768597 56#define SP (h8300hmode && !h8300_normal_mode ? SL : SW)
dc5c3759 57
c906108c
SS
58#define h8_opcodes ops
59#define DEFINE_TABLE
60#include "opcode/h8300.h"
61
dc5c3759 62/* CPU data object: */
c906108c 63
dc5c3759
MS
64static int
65sim_state_initialize (SIM_DESC sd, sim_cpu *cpu)
66{
67 /* FIXME: not really necessary, since sim_cpu_alloc calls zalloc. */
68
69 memset (&cpu->regs, 0, sizeof(cpu->regs));
70 cpu->regs[SBR_REGNUM] = 0xFFFFFF00;
71 cpu->pc = 0;
72 cpu->delayed_branch = 0;
73 cpu->memory = NULL;
74 cpu->eightbit = NULL;
75 cpu->mask = 0;
76
77 /* Initialize local simulator state. */
78 sd->sim_cache = NULL;
79 sd->sim_cache_size = 0;
80 sd->cache_idx = NULL;
81 sd->cache_top = 0;
82 sd->memory_size = 0;
83 sd->compiles = 0;
84#ifdef ADEBUG
85 memset (&cpu->stats, 0, sizeof (cpu->stats));
86#endif
87 return 0;
88}
7a292a7a 89
dc5c3759
MS
90static unsigned int
91h8_get_pc (SIM_DESC sd)
92{
93 return (STATE_CPU (sd, 0)) -> pc;
94}
7a292a7a 95
dc5c3759
MS
96static void
97h8_set_pc (SIM_DESC sd, unsigned int val)
98{
99 (STATE_CPU (sd, 0)) -> pc = val;
100}
fc974602 101
dc5c3759
MS
102static unsigned int
103h8_get_ccr (SIM_DESC sd)
104{
105 return (STATE_CPU (sd, 0)) -> regs[CCR_REGNUM];
106}
c906108c 107
dc5c3759
MS
108static void
109h8_set_ccr (SIM_DESC sd, unsigned int val)
110{
111 (STATE_CPU (sd, 0)) -> regs[CCR_REGNUM] = val;
112}
c906108c 113
dc5c3759
MS
114static unsigned int
115h8_get_exr (SIM_DESC sd)
116{
117 return (STATE_CPU (sd, 0)) -> regs[EXR_REGNUM];
118}
c906108c 119
dc5c3759
MS
120static void
121h8_set_exr (SIM_DESC sd, unsigned int val)
122{
123 (STATE_CPU (sd, 0)) -> regs[EXR_REGNUM] = val;
124}
c906108c 125
dc5c3759
MS
126static int
127h8_get_sbr (SIM_DESC sd)
128{
129 return (STATE_CPU (sd, 0)) -> regs[SBR_REGNUM];
130}
c906108c 131
dc5c3759
MS
132static void
133h8_set_sbr (SIM_DESC sd, int val)
134{
135 (STATE_CPU (sd, 0)) -> regs[SBR_REGNUM] = val;
136}
c906108c 137
c906108c 138static int
dc5c3759
MS
139h8_get_vbr (SIM_DESC sd)
140{
141 return (STATE_CPU (sd, 0)) -> regs[VBR_REGNUM];
142}
143
144static void
145h8_set_vbr (SIM_DESC sd, int val)
c906108c 146{
dc5c3759 147 (STATE_CPU (sd, 0)) -> regs[VBR_REGNUM] = val;
c906108c
SS
148}
149
150static int
dc5c3759 151h8_get_cache_top (SIM_DESC sd)
c906108c 152{
dc5c3759
MS
153 return sd -> cache_top;
154}
155
156static void
157h8_set_cache_top (SIM_DESC sd, int val)
158{
159 sd -> cache_top = val;
c906108c
SS
160}
161
c906108c 162static int
dc5c3759 163h8_get_mask (SIM_DESC sd)
c906108c 164{
dc5c3759 165 return (STATE_CPU (sd, 0)) -> mask;
c906108c
SS
166}
167
dc5c3759
MS
168static void
169h8_set_mask (SIM_DESC sd, int val)
c906108c 170{
dc5c3759
MS
171 (STATE_CPU (sd, 0)) -> mask = val;
172}
173#if 0
174static int
175h8_get_exception (SIM_DESC sd)
176{
177 return (STATE_CPU (sd, 0)) -> exception;
178}
c906108c 179
dc5c3759
MS
180static void
181h8_set_exception (SIM_DESC sd, int val)
182{
183 (STATE_CPU (sd, 0)) -> exception = val;
184}
0ef9643e 185
dc5c3759
MS
186static enum h8300_sim_state
187h8_get_state (SIM_DESC sd)
188{
189 return sd -> state;
c906108c
SS
190}
191
dc5c3759
MS
192static void
193h8_set_state (SIM_DESC sd, enum h8300_sim_state val)
d1360fb0 194{
dc5c3759
MS
195 sd -> state = val;
196}
197#endif
198static unsigned int
199h8_get_cycles (SIM_DESC sd)
200{
201 return (STATE_CPU (sd, 0)) -> regs[CYCLE_REGNUM];
202}
203
204static void
205h8_set_cycles (SIM_DESC sd, unsigned int val)
206{
207 (STATE_CPU (sd, 0)) -> regs[CYCLE_REGNUM] = val;
d1360fb0
V
208}
209
c906108c 210static unsigned int
dc5c3759 211h8_get_insts (SIM_DESC sd)
c906108c 212{
dc5c3759
MS
213 return (STATE_CPU (sd, 0)) -> regs[INST_REGNUM];
214}
0ef9643e 215
dc5c3759
MS
216static void
217h8_set_insts (SIM_DESC sd, unsigned int val)
218{
219 (STATE_CPU (sd, 0)) -> regs[INST_REGNUM] = val;
220}
0ef9643e 221
dc5c3759
MS
222static unsigned int
223h8_get_ticks (SIM_DESC sd)
224{
225 return (STATE_CPU (sd, 0)) -> regs[TICK_REGNUM];
226}
c906108c 227
dc5c3759
MS
228static void
229h8_set_ticks (SIM_DESC sd, unsigned int val)
230{
231 (STATE_CPU (sd, 0)) -> regs[TICK_REGNUM] = val;
232}
c906108c 233
dc5c3759
MS
234static unsigned int
235h8_get_mach (SIM_DESC sd)
236{
237 return (STATE_CPU (sd, 0)) -> regs[MACH_REGNUM];
238}
c906108c 239
dc5c3759
MS
240static void
241h8_set_mach (SIM_DESC sd, unsigned int val)
242{
243 (STATE_CPU (sd, 0)) -> regs[MACH_REGNUM] = val;
244}
0ef9643e 245
dc5c3759
MS
246static unsigned int
247h8_get_macl (SIM_DESC sd)
248{
249 return (STATE_CPU (sd, 0)) -> regs[MACL_REGNUM];
250}
0ef9643e 251
dc5c3759
MS
252static void
253h8_set_macl (SIM_DESC sd, unsigned int val)
254{
255 (STATE_CPU (sd, 0)) -> regs[MACL_REGNUM] = val;
256}
0ef9643e 257
dc5c3759
MS
258static int
259h8_get_compiles (SIM_DESC sd)
260{
261 return sd -> compiles;
262}
0ef9643e 263
dc5c3759
MS
264static void
265h8_increment_compiles (SIM_DESC sd)
266{
267 sd -> compiles ++;
268}
0ef9643e 269
dc5c3759
MS
270static unsigned int *
271h8_get_reg_buf (SIM_DESC sd)
272{
273 return &(((STATE_CPU (sd, 0)) -> regs)[0]);
274}
0ef9643e 275
dc5c3759
MS
276static unsigned int
277h8_get_reg (SIM_DESC sd, int regnum)
278{
279 return (STATE_CPU (sd, 0)) -> regs[regnum];
280}
c906108c 281
dc5c3759
MS
282static void
283h8_set_reg (SIM_DESC sd, int regnum, int val)
284{
285 (STATE_CPU (sd, 0)) -> regs[regnum] = val;
286}
0ef9643e 287
dc5c3759
MS
288#ifdef ADEBUG
289static int
290h8_get_stats (SIM_DESC sd, int idx)
291{
292 return sd -> stats[idx];
293}
c906108c 294
dc5c3759
MS
295static void
296h8_increment_stats (SIM_DESC sd, int idx)
297{
298 sd -> stats[idx] ++;
299}
300#endif /* ADEBUG */
c906108c 301
dc5c3759
MS
302static unsigned short *
303h8_get_cache_idx_buf (SIM_DESC sd)
304{
305 return sd -> cache_idx;
306}
c906108c 307
dc5c3759
MS
308static void
309h8_set_cache_idx_buf (SIM_DESC sd, unsigned short *ptr)
310{
311 sd -> cache_idx = ptr;
312}
c906108c 313
dc5c3759
MS
314static unsigned short
315h8_get_cache_idx (SIM_DESC sd, unsigned int idx)
316{
317 if (idx > sd->memory_size)
318 return (unsigned short) -1;
319 return sd -> cache_idx[idx];
320}
c906108c 321
dc5c3759
MS
322static void
323h8_set_cache_idx (SIM_DESC sd, int idx, unsigned int val)
324{
325 sd -> cache_idx[idx] = (unsigned short) val;
326}
c906108c 327
dc5c3759
MS
328static unsigned char *
329h8_get_memory_buf (SIM_DESC sd)
330{
331 return (STATE_CPU (sd, 0)) -> memory;
332}
c906108c 333
dc5c3759
MS
334static void
335h8_set_memory_buf (SIM_DESC sd, unsigned char *ptr)
336{
337 (STATE_CPU (sd, 0)) -> memory = ptr;
338}
c906108c 339
dc5c3759
MS
340static unsigned char
341h8_get_memory (SIM_DESC sd, int idx)
342{
343 return (STATE_CPU (sd, 0)) -> memory[idx];
344}
c906108c 345
dc5c3759
MS
346static void
347h8_set_memory (SIM_DESC sd, int idx, unsigned int val)
348{
349 (STATE_CPU (sd, 0)) -> memory[idx] = (unsigned char) val;
350}
c906108c 351
dc5c3759
MS
352static unsigned char *
353h8_get_eightbit_buf (SIM_DESC sd)
354{
355 return (STATE_CPU (sd, 0)) -> eightbit;
356}
c906108c 357
dc5c3759
MS
358static void
359h8_set_eightbit_buf (SIM_DESC sd, unsigned char *ptr)
360{
361 (STATE_CPU (sd, 0)) -> eightbit = ptr;
362}
c906108c 363
dc5c3759
MS
364static unsigned char
365h8_get_eightbit (SIM_DESC sd, int idx)
366{
367 return (STATE_CPU (sd, 0)) -> eightbit[idx];
368}
c906108c 369
dc5c3759
MS
370static void
371h8_set_eightbit (SIM_DESC sd, int idx, unsigned int val)
372{
373 (STATE_CPU (sd, 0)) -> eightbit[idx] = (unsigned char) val;
374}
c906108c 375
dc5c3759
MS
376static unsigned int
377h8_get_delayed_branch (SIM_DESC sd)
378{
379 return (STATE_CPU (sd, 0)) -> delayed_branch;
c906108c
SS
380}
381
c906108c 382static void
dc5c3759 383h8_set_delayed_branch (SIM_DESC sd, unsigned int dest)
c906108c 384{
dc5c3759
MS
385 (STATE_CPU (sd, 0)) -> delayed_branch = dest;
386}
c906108c 387
dc5c3759
MS
388static char **
389h8_get_command_line (SIM_DESC sd)
390{
391 return (STATE_CPU (sd, 0)) -> command_line;
392}
c906108c 393
dc5c3759
MS
394static void
395h8_set_command_line (SIM_DESC sd, char ** val)
396{
397 (STATE_CPU (sd, 0)) -> command_line = val;
398}
c906108c 399
dc5c3759
MS
400static char *
401h8_get_cmdline_arg (SIM_DESC sd, int index)
402{
403 return (STATE_CPU (sd, 0)) -> command_line[index];
404}
c906108c 405
dc5c3759
MS
406static void
407h8_set_cmdline_arg (SIM_DESC sd, int index, char * val)
408{
409 (STATE_CPU (sd, 0)) -> command_line[index] = val;
410}
c906108c 411
dc5c3759
MS
412/* MAC Saturation Mode */
413static int
414h8_get_macS (SIM_DESC sd)
415{
416 return (STATE_CPU (sd, 0)) -> macS;
c906108c
SS
417}
418
dc5c3759
MS
419static void
420h8_set_macS (SIM_DESC sd, int val)
421{
422 (STATE_CPU (sd, 0)) -> macS = (val != 0);
423}
c906108c 424
dc5c3759
MS
425/* MAC Zero Flag */
426static int
427h8_get_macZ (SIM_DESC sd)
428{
429 return (STATE_CPU (sd, 0)) -> macZ;
430}
c906108c 431
dc5c3759
MS
432static void
433h8_set_macZ (SIM_DESC sd, int val)
434{
435 (STATE_CPU (sd, 0)) -> macZ = (val != 0);
436}
c906108c 437
dc5c3759
MS
438/* MAC Negative Flag */
439static int
440h8_get_macN (SIM_DESC sd)
441{
442 return (STATE_CPU (sd, 0)) -> macN;
443}
c906108c 444
dc5c3759
MS
445static void
446h8_set_macN (SIM_DESC sd, int val)
447{
448 (STATE_CPU (sd, 0)) -> macN = (val != 0);
449}
c906108c 450
dc5c3759
MS
451/* MAC Overflow Flag */
452static int
453h8_get_macV (SIM_DESC sd)
454{
455 return (STATE_CPU (sd, 0)) -> macV;
456}
c906108c 457
dc5c3759
MS
458static void
459h8_set_macV (SIM_DESC sd, int val)
460{
461 (STATE_CPU (sd, 0)) -> macV = (val != 0);
462}
c906108c 463
dc5c3759 464/* End CPU data object. */
c906108c 465
dc5c3759 466/* The rate at which to call the host's poll_quit callback. */
c906108c 467
dc5c3759 468enum { POLL_QUIT_INTERVAL = 0x80000 };
c906108c 469
dc5c3759
MS
470#define LOW_BYTE(x) ((x) & 0xff)
471#define HIGH_BYTE(x) (((x) >> 8) & 0xff)
472#define P(X, Y) ((X << 8) | Y)
c906108c 473
dc5c3759
MS
474#define C (c != 0)
475#define Z (nz == 0)
476#define V (v != 0)
477#define N (n != 0)
478#define U (u != 0)
479#define H (h != 0)
480#define UI (ui != 0)
481#define I (intMaskBit != 0)
c906108c 482
dc5c3759
MS
483#define BUILDSR(SD) \
484 h8_set_ccr (SD, (I << 7) | (UI << 6) | (H << 5) | (U << 4) \
485 | (N << 3) | (Z << 2) | (V << 1) | C)
c906108c 486
9f70f8ec
MS
487#define GETSR(SD) \
488 /* Get Status Register (flags). */ \
489 c = (h8_get_ccr (sd) >> 0) & 1; \
490 v = (h8_get_ccr (sd) >> 1) & 1; \
491 nz = !((h8_get_ccr (sd) >> 2) & 1); \
492 n = (h8_get_ccr (sd) >> 3) & 1; \
493 u = (h8_get_ccr (sd) >> 4) & 1; \
494 h = (h8_get_ccr (sd) >> 5) & 1; \
495 ui = ((h8_get_ccr (sd) >> 6) & 1); \
496 intMaskBit = (h8_get_ccr (sd) >> 7) & 1
497
498
dc5c3759
MS
499#ifdef __CHAR_IS_SIGNED__
500#define SEXTCHAR(x) ((char) (x))
501#endif
c906108c 502
dc5c3759
MS
503#ifndef SEXTCHAR
504#define SEXTCHAR(x) ((x & 0x80) ? (x | ~0xff) : x & 0xff)
505#endif
c906108c 506
dc5c3759
MS
507#define UEXTCHAR(x) ((x) & 0xff)
508#define UEXTSHORT(x) ((x) & 0xffff)
509#define SEXTSHORT(x) ((short) (x))
c906108c 510
dc5c3759
MS
511int h8300hmode = 0;
512int h8300smode = 0;
59768597 513int h8300_normal_mode = 0;
dc5c3759 514int h8300sxmode = 0;
c906108c 515
dc5c3759 516static int memory_size;
c906108c 517
dc5c3759
MS
518static int
519get_now (void)
520{
521 return time (0); /* WinXX HAS UNIX like 'time', so why not use it? */
522}
c906108c 523
dc5c3759
MS
524static int
525now_persec (void)
526{
527 return 1;
528}
c906108c 529
dc5c3759
MS
530static int
531bitfrom (int x)
532{
533 switch (x & SIZE)
534 {
535 case L_8:
536 return SB;
537 case L_16:
538 case L_16U:
539 return SW;
540 case L_32:
541 return SL;
542 case L_P:
59768597 543 return (h8300hmode && !h8300_normal_mode)? SL : SW;
c906108c 544 }
dc5c3759 545 return 0;
c906108c
SS
546}
547
dc5c3759
MS
548/* Simulate an indirection / dereference.
549 return 0 for success, -1 for failure.
550*/
c906108c 551
dc5c3759
MS
552static unsigned int
553lvalue (SIM_DESC sd, int x, int rn, unsigned int *val)
c906108c 554{
dc5c3759
MS
555 if (val == NULL) /* Paranoia. */
556 return -1;
c906108c 557
dc5c3759 558 switch (x / 4)
c906108c 559 {
dc5c3759
MS
560 case OP_DISP:
561 if (rn == ZERO_REGNUM)
562 *val = X (OP_IMM, SP);
563 else
564 *val = X (OP_REG, SP);
c906108c 565 break;
dc5c3759
MS
566 case OP_MEM:
567 *val = X (OP_MEM, SP);
c906108c
SS
568 break;
569 default:
dc5c3759
MS
570 sim_engine_set_run_state (sd, sim_stopped, SIGSEGV);
571 return -1;
c906108c 572 }
dc5c3759 573 return 0;
c906108c
SS
574}
575
dc5c3759
MS
576static int
577cmdline_location()
c906108c 578{
59768597 579 if (h8300smode && !h8300_normal_mode)
dc5c3759 580 return 0xffff00L;
59768597 581 else if (h8300hmode && !h8300_normal_mode)
dc5c3759
MS
582 return 0x2ff00L;
583 else
584 return 0xff00L;
c906108c
SS
585}
586
de9b1892 587static void
dc5c3759 588decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
c906108c 589{
dc5c3759
MS
590 int cst[3] = {0, 0, 0};
591 int reg[3] = {0, 0, 0};
592 int rdisp[3] = {0, 0, 0};
593 int opnum;
594 const struct h8_opcode *q;
c906108c 595
dc5c3759
MS
596 dst->dst.type = -1;
597 dst->src.type = -1;
c906108c 598
dc5c3759
MS
599 /* Find the exact opcode/arg combo. */
600 for (q = h8_opcodes; q->name; q++)
601 {
c4212d37 602 const op_type *nib = q->data.nib;
dc5c3759 603 unsigned int len = 0;
c906108c 604
dc5c3759 605 if ((q->available == AV_H8SX && !h8300sxmode) ||
9f70f8ec 606 (q->available == AV_H8S && !h8300smode) ||
dc5c3759
MS
607 (q->available == AV_H8H && !h8300hmode))
608 continue;
c906108c 609
f408565c
MS
610 cst[0] = cst[1] = cst[2] = 0;
611 reg[0] = reg[1] = reg[2] = 0;
612 rdisp[0] = rdisp[1] = rdisp[2] = 0;
613
dc5c3759 614 while (1)
c906108c 615 {
dc5c3759
MS
616 op_type looking_for = *nib;
617 int thisnib = data[len / 2];
c906108c 618
dc5c3759
MS
619 thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf);
620 opnum = ((looking_for & OP3) ? 2 :
621 (looking_for & DST) ? 1 : 0);
622
623 if (looking_for < 16 && looking_for >= 0)
c906108c 624 {
dc5c3759
MS
625 if (looking_for != thisnib)
626 goto fail;
c906108c 627 }
dc5c3759 628 else
c906108c 629 {
dc5c3759 630 if (looking_for & B31)
c906108c 631 {
dc5c3759
MS
632 if (!((thisnib & 0x8) != 0))
633 goto fail;
634
635 looking_for = (op_type) (looking_for & ~B31);
636 thisnib &= 0x7;
c906108c 637 }
dc5c3759 638 else if (looking_for & B30)
c906108c 639 {
dc5c3759
MS
640 if (!((thisnib & 0x8) == 0))
641 goto fail;
642
643 looking_for = (op_type) (looking_for & ~B30);
c906108c 644 }
c906108c 645
dc5c3759
MS
646 if (looking_for & B21)
647 {
648 if (!((thisnib & 0x4) != 0))
649 goto fail;
c906108c 650
dc5c3759
MS
651 looking_for = (op_type) (looking_for & ~B21);
652 thisnib &= 0xb;
653 }
654 else if (looking_for & B20)
655 {
656 if (!((thisnib & 0x4) == 0))
657 goto fail;
c906108c 658
dc5c3759
MS
659 looking_for = (op_type) (looking_for & ~B20);
660 }
c906108c 661
dc5c3759
MS
662 if (looking_for & B11)
663 {
664 if (!((thisnib & 0x2) != 0))
665 goto fail;
c906108c 666
dc5c3759
MS
667 looking_for = (op_type) (looking_for & ~B11);
668 thisnib &= 0xd;
669 }
670 else if (looking_for & B10)
671 {
672 if (!((thisnib & 0x2) == 0))
673 goto fail;
c906108c 674
dc5c3759
MS
675 looking_for = (op_type) (looking_for & ~B10);
676 }
c906108c 677
dc5c3759
MS
678 if (looking_for & B01)
679 {
680 if (!((thisnib & 0x1) != 0))
681 goto fail;
c906108c 682
dc5c3759
MS
683 looking_for = (op_type) (looking_for & ~B01);
684 thisnib &= 0xe;
685 }
686 else if (looking_for & B00)
687 {
688 if (!((thisnib & 0x1) == 0))
689 goto fail;
c906108c 690
dc5c3759
MS
691 looking_for = (op_type) (looking_for & ~B00);
692 }
c906108c 693
dc5c3759
MS
694 if (looking_for & IGNORE)
695 {
696 /* Hitachi has declared that IGNORE must be zero. */
697 if (thisnib != 0)
698 goto fail;
699 }
700 else if ((looking_for & MODE) == DATA)
701 {
702 ; /* Skip embedded data. */
703 }
704 else if ((looking_for & MODE) == DBIT)
705 {
706 /* Exclude adds/subs by looking at bit 0 and 2, and
707 make sure the operand size, either w or l,
708 matches by looking at bit 1. */
709 if ((looking_for & 7) != (thisnib & 7))
710 goto fail;
c906108c 711
dc5c3759
MS
712 cst[opnum] = (thisnib & 0x8) ? 2 : 1;
713 }
714 else if ((looking_for & MODE) == REG ||
715 (looking_for & MODE) == LOWREG ||
716 (looking_for & MODE) == IND ||
717 (looking_for & MODE) == PREINC ||
718 (looking_for & MODE) == POSTINC ||
719 (looking_for & MODE) == PREDEC ||
720 (looking_for & MODE) == POSTDEC)
721 {
722 reg[opnum] = thisnib;
723 }
724 else if (looking_for & CTRL)
725 {
726 thisnib &= 7;
727 if (((looking_for & MODE) == CCR && (thisnib != C_CCR)) ||
728 ((looking_for & MODE) == EXR && (thisnib != C_EXR)) ||
729 ((looking_for & MODE) == MACH && (thisnib != C_MACH)) ||
730 ((looking_for & MODE) == MACL && (thisnib != C_MACL)) ||
731 ((looking_for & MODE) == VBR && (thisnib != C_VBR)) ||
732 ((looking_for & MODE) == SBR && (thisnib != C_SBR)))
733 goto fail;
734 if (((looking_for & MODE) == CCR_EXR &&
735 (thisnib != C_CCR && thisnib != C_EXR)) ||
736 ((looking_for & MODE) == VBR_SBR &&
737 (thisnib != C_VBR && thisnib != C_SBR)) ||
738 ((looking_for & MODE) == MACREG &&
739 (thisnib != C_MACH && thisnib != C_MACL)))
740 goto fail;
741 if (((looking_for & MODE) == CC_EX_VB_SB &&
742 (thisnib != C_CCR && thisnib != C_EXR &&
743 thisnib != C_VBR && thisnib != C_SBR)))
744 goto fail;
c906108c 745
dc5c3759
MS
746 reg[opnum] = thisnib;
747 }
748 else if ((looking_for & MODE) == ABS)
749 {
750 /* Absolute addresses are unsigned. */
751 switch (looking_for & SIZE)
752 {
753 case L_8:
754 cst[opnum] = UEXTCHAR (data[len / 2]);
755 break;
756 case L_16:
757 case L_16U:
758 cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
759 break;
760 case L_32:
761 cst[opnum] =
762 (data[len / 2 + 0] << 24) +
763 (data[len / 2 + 1] << 16) +
764 (data[len / 2 + 2] << 8) +
765 (data[len / 2 + 3]);
766 break;
767 default:
768 printf ("decode: bad size ABS: %d\n",
769 (looking_for & SIZE));
770 goto end;
771 }
772 }
773 else if ((looking_for & MODE) == DISP ||
774 (looking_for & MODE) == PCREL ||
775 (looking_for & MODE) == INDEXB ||
776 (looking_for & MODE) == INDEXW ||
777 (looking_for & MODE) == INDEXL)
dc5c3759
MS
778 {
779 switch (looking_for & SIZE)
780 {
781 case L_2:
782 cst[opnum] = thisnib & 3;
dc5c3759
MS
783 break;
784 case L_8:
785 cst[opnum] = SEXTCHAR (data[len / 2]);
786 break;
787 case L_16:
788 cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
789 cst[opnum] = (short) cst[opnum]; /* Sign extend. */
790 break;
791 case L_16U:
792 cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
793 break;
794 case L_32:
795 cst[opnum] =
796 (data[len / 2 + 0] << 24) +
797 (data[len / 2 + 1] << 16) +
798 (data[len / 2 + 2] << 8) +
799 (data[len / 2 + 3]);
800 break;
801 default:
802 printf ("decode: bad size DISP/PCREL/INDEX: %d\n",
803 (looking_for & SIZE));
804 goto end;
805 }
806 }
807 else if ((looking_for & SIZE) == L_16 ||
808 (looking_for & SIZE) == L_16U)
809 {
810 cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
0f42aa71
MS
811 /* Immediates are always unsigned. */
812 if ((looking_for & SIZE) != L_16U &&
813 (looking_for & MODE) != IMM)
dc5c3759
MS
814 cst[opnum] = (short) cst[opnum]; /* Sign extend. */
815 }
816 else if (looking_for & ABSJMP)
817 {
818 switch (looking_for & SIZE) {
819 case L_24:
820 cst[opnum] = (data[1] << 16) | (data[2] << 8) | (data[3]);
821 break;
822 case L_32:
823 cst[opnum] =
824 (data[len / 2 + 0] << 24) +
825 (data[len / 2 + 1] << 16) +
826 (data[len / 2 + 2] << 8) +
827 (data[len / 2 + 3]);
828 break;
829 default:
830 printf ("decode: bad size ABSJMP: %d\n",
831 (looking_for & SIZE));
832 goto end;
833 }
834 }
835 else if ((looking_for & MODE) == MEMIND)
836 {
837 cst[opnum] = data[1];
838 }
9f70f8ec
MS
839 else if ((looking_for & MODE) == VECIND)
840 {
59768597
SA
841 if(h8300_normal_mode)
842 cst[opnum] = ((data[1] & 0x7f) + 0x80) * 2;
843 else
844 cst[opnum] = ((data[1] & 0x7f) + 0x80) * 4;
9f70f8ec
MS
845 cst[opnum] += h8_get_vbr (sd); /* Add vector base reg. */
846 }
dc5c3759
MS
847 else if ((looking_for & SIZE) == L_32)
848 {
849 int i = len / 2;
6147b1f6 850
dc5c3759
MS
851 cst[opnum] =
852 (data[i + 0] << 24) |
853 (data[i + 1] << 16) |
854 (data[i + 2] << 8) |
855 (data[i + 3]);
856 }
857 else if ((looking_for & SIZE) == L_24)
858 {
859 int i = len / 2;
6147b1f6 860
dc5c3759
MS
861 cst[opnum] =
862 (data[i + 0] << 16) |
863 (data[i + 1] << 8) |
864 (data[i + 2]);
865 }
866 else if (looking_for & DISPREG)
867 {
868 rdisp[opnum] = thisnib & 0x7;
869 }
870 else if ((looking_for & MODE) == KBIT)
871 {
872 switch (thisnib)
873 {
874 case 9:
875 cst[opnum] = 4;
876 break;
877 case 8:
878 cst[opnum] = 2;
879 break;
880 case 0:
881 cst[opnum] = 1;
882 break;
883 default:
884 goto fail;
885 }
886 }
887 else if ((looking_for & SIZE) == L_8)
888 {
889 if ((looking_for & MODE) == ABS)
890 {
891 /* Will be combined with contents of SBR_REGNUM
892 by fetch (). For all modes except h8sx, this
893 will always contain the value 0xFFFFFF00. */
894 cst[opnum] = data[len / 2] & 0xff;
895 }
896 else
897 {
898 cst[opnum] = data[len / 2] & 0xff;
899 }
900 }
9f70f8ec
MS
901 else if ((looking_for & SIZE) == L_2)
902 {
903 cst[opnum] = thisnib & 3;
904 }
dc5c3759
MS
905 else if ((looking_for & SIZE) == L_3 ||
906 (looking_for & SIZE) == L_3NZ)
907 {
908 cst[opnum] = thisnib & 7;
909 if (cst[opnum] == 0 && (looking_for & SIZE) == L_3NZ)
910 goto fail;
911 }
912 else if ((looking_for & SIZE) == L_4)
913 {
914 cst[opnum] = thisnib & 15;
915 }
916 else if ((looking_for & SIZE) == L_5)
917 {
918 cst[opnum] = data[len / 2] & 0x1f;
919 }
920 else if (looking_for == E)
921 {
922#ifdef ADEBUG
923 dst->op = q;
924#endif
925 /* Fill in the args. */
926 {
c4212d37 927 const op_type *args = q->args.nib;
dc5c3759
MS
928 int hadone = 0;
929 int nargs;
6147b1f6 930
dc5c3759
MS
931 for (nargs = 0;
932 nargs < 3 && *args != E;
933 nargs++)
934 {
935 int x = *args;
936 ea_type *p;
c906108c 937
dc5c3759
MS
938 opnum = ((x & OP3) ? 2 :
939 (x & DST) ? 1 : 0);
940 if (x & DST)
941 p = &dst->dst;
942 else if (x & OP3)
943 p = &dst->op3;
944 else
945 p = &dst->src;
c906108c 946
dc5c3759
MS
947 if ((x & MODE) == IMM ||
948 (x & MODE) == KBIT ||
949 (x & MODE) == DBIT)
950 {
951 /* Use the instruction to determine
952 the operand size. */
953 p->type = X (OP_IMM, OP_SIZE (q->how));
954 p->literal = cst[opnum];
955 }
956 else if ((x & MODE) == CONST_2 ||
957 (x & MODE) == CONST_4 ||
958 (x & MODE) == CONST_8 ||
959 (x & MODE) == CONST_16)
960 {
961 /* Use the instruction to determine
962 the operand size. */
963 p->type = X (OP_IMM, OP_SIZE (q->how));
964 switch (x & MODE) {
965 case CONST_2: p->literal = 2; break;
966 case CONST_4: p->literal = 4; break;
967 case CONST_8: p->literal = 8; break;
968 case CONST_16: p->literal = 16; break;
969 }
970 }
971 else if ((x & MODE) == REG)
972 {
973 p->type = X (OP_REG, bitfrom (x));
974 p->reg = reg[opnum];
975 }
976 else if ((x & MODE) == LOWREG)
977 {
978 p->type = X (OP_LOWREG, bitfrom (x));
979 p->reg = reg[opnum];
980 }
981 else if ((x & MODE) == PREINC)
982 {
983 /* Use the instruction to determine
984 the operand size. */
985 p->type = X (OP_PREINC, OP_SIZE (q->how));
986 p->reg = reg[opnum] & 0x7;
987 }
988 else if ((x & MODE) == POSTINC)
989 {
990 /* Use the instruction to determine
991 the operand size. */
992 p->type = X (OP_POSTINC, OP_SIZE (q->how));
993 p->reg = reg[opnum] & 0x7;
994 }
995 else if ((x & MODE) == PREDEC)
996 {
997 /* Use the instruction to determine
998 the operand size. */
999 p->type = X (OP_PREDEC, OP_SIZE (q->how));
1000 p->reg = reg[opnum] & 0x7;
1001 }
1002 else if ((x & MODE) == POSTDEC)
1003 {
1004 /* Use the instruction to determine
1005 the operand size. */
1006 p->type = X (OP_POSTDEC, OP_SIZE (q->how));
1007 p->reg = reg[opnum] & 0x7;
1008 }
1009 else if ((x & MODE) == IND)
1010 {
1011 /* Note: an indirect is transformed into
1012 a displacement of zero.
1013 */
1014 /* Use the instruction to determine
1015 the operand size. */
1016 p->type = X (OP_DISP, OP_SIZE (q->how));
1017 p->reg = reg[opnum] & 0x7;
1018 p->literal = 0;
1019 if (OP_KIND (q->how) == O_JSR ||
1020 OP_KIND (q->how) == O_JMP)
b86015ea 1021 if (lvalue (sd, p->type, p->reg, (unsigned int *)&p->type))
dc5c3759
MS
1022 goto end;
1023 }
1024 else if ((x & MODE) == ABS)
1025 {
1026 /* Note: a 16 or 32 bit ABS is transformed into a
1027 displacement from pseudo-register ZERO_REGNUM,
1028 which is always zero. An 8 bit ABS becomes
1029 a displacement from SBR_REGNUM.
1030 */
1031 /* Use the instruction to determine
1032 the operand size. */
1033 p->type = X (OP_DISP, OP_SIZE (q->how));
1034 p->literal = cst[opnum];
1035
1036 /* 8-bit ABS is displacement from SBR.
1037 16 and 32-bit ABS are displacement from ZERO.
1038 (SBR will always be zero except for h8/sx)
1039 */
1040 if ((x & SIZE) == L_8)
1041 p->reg = SBR_REGNUM;
1042 else
1043 p->reg = ZERO_REGNUM;;
1044 }
9f70f8ec
MS
1045 else if ((x & MODE) == MEMIND ||
1046 (x & MODE) == VECIND)
dc5c3759
MS
1047 {
1048 /* Size doesn't matter. */
1049 p->type = X (OP_MEM, SB);
1050 p->literal = cst[opnum];
1051 if (OP_KIND (q->how) == O_JSR ||
1052 OP_KIND (q->how) == O_JMP)
b86015ea 1053 if (lvalue (sd, p->type, p->reg, (unsigned int *)&p->type))
dc5c3759
MS
1054 goto end;
1055 }
1056 else if ((x & MODE) == PCREL)
1057 {
1058 /* Size doesn't matter. */
1059 p->type = X (OP_PCREL, SB);
1060 p->literal = cst[opnum];
1061 }
1062 else if (x & ABSJMP)
1063 {
1064 p->type = X (OP_IMM, SP);
1065 p->literal = cst[opnum];
1066 }
f408565c 1067 else if ((x & MODE) == INDEXB)
dc5c3759 1068 {
f408565c
MS
1069 p->type = X (OP_INDEXB, OP_SIZE (q->how));
1070 p->literal = cst[opnum];
1071 p->reg = rdisp[opnum];
1072 }
1073 else if ((x & MODE) == INDEXW)
1074 {
1075 p->type = X (OP_INDEXW, OP_SIZE (q->how));
dc5c3759
MS
1076 p->literal = cst[opnum];
1077 p->reg = rdisp[opnum];
1078 }
f408565c
MS
1079 else if ((x & MODE) == INDEXL)
1080 {
1081 p->type = X (OP_INDEXL, OP_SIZE (q->how));
1082 p->literal = cst[opnum];
1083 p->reg = rdisp[opnum];
1084 }
1085 else if ((x & MODE) == DISP)
1086 {
1087 /* Yuck -- special for mova args. */
1088 if (strncmp (q->name, "mova", 4) == 0 &&
1089 (x & SIZE) == L_2)
1090 {
1091 /* Mova can have a DISP2 dest, with an
1092 INDEXB or INDEXW src. The multiplier
1093 for the displacement value is determined
1094 by the src operand, not by the insn. */
1095
1096 switch (OP_KIND (dst->src.type))
1097 {
1098 case OP_INDEXB:
1099 p->type = X (OP_DISP, SB);
1100 p->literal = cst[opnum];
1101 break;
1102 case OP_INDEXW:
1103 p->type = X (OP_DISP, SW);
1104 p->literal = cst[opnum] * 2;
1105 break;
1106 default:
1107 goto fail;
1108 }
1109 }
1110 else
1111 {
1112 p->type = X (OP_DISP, OP_SIZE (q->how));
1113 p->literal = cst[opnum];
1114 /* DISP2 is special. */
1115 if ((x & SIZE) == L_2)
1116 switch (OP_SIZE (q->how))
1117 {
1118 case SB: break;
1119 case SW: p->literal *= 2; break;
1120 case SL: p->literal *= 4; break;
1121 }
1122 }
1123 p->reg = rdisp[opnum];
1124 }
dc5c3759
MS
1125 else if (x & CTRL)
1126 {
1127 switch (reg[opnum])
1128 {
1129 case C_CCR:
1130 p->type = X (OP_CCR, SB);
1131 break;
1132 case C_EXR:
1133 p->type = X (OP_EXR, SB);
1134 break;
1135 case C_MACH:
1136 p->type = X (OP_MACH, SL);
1137 break;
1138 case C_MACL:
1139 p->type = X (OP_MACL, SL);
1140 break;
1141 case C_VBR:
1142 p->type = X (OP_VBR, SL);
1143 break;
1144 case C_SBR:
1145 p->type = X (OP_SBR, SL);
1146 break;
1147 }
1148 }
1149 else if ((x & MODE) == CCR)
1150 {
1151 p->type = OP_CCR;
1152 }
1153 else if ((x & MODE) == EXR)
1154 {
1155 p->type = OP_EXR;
1156 }
1157 else
9f70f8ec 1158 printf ("Hmmmm 0x%x...\n", x);
c906108c 1159
dc5c3759
MS
1160 args++;
1161 }
1162 }
c906108c 1163
dc5c3759
MS
1164 /* Unary operators: treat src and dst as equivalent. */
1165 if (dst->dst.type == -1)
1166 dst->dst = dst->src;
1167 if (dst->src.type == -1)
1168 dst->src = dst->dst;
1169
1170 dst->opcode = q->how;
1171 dst->cycles = q->time;
c906108c 1172
dc5c3759
MS
1173 /* And jsr's to these locations are turned into
1174 magic traps. */
fc974602 1175
dc5c3759
MS
1176 if (OP_KIND (dst->opcode) == O_JSR)
1177 {
1178 switch (dst->src.literal)
1179 {
1180 case 0xc5:
1181 dst->opcode = O (O_SYS_OPEN, SB);
1182 break;
1183 case 0xc6:
1184 dst->opcode = O (O_SYS_READ, SB);
1185 break;
1186 case 0xc7:
1187 dst->opcode = O (O_SYS_WRITE, SB);
1188 break;
1189 case 0xc8:
1190 dst->opcode = O (O_SYS_LSEEK, SB);
1191 break;
1192 case 0xc9:
1193 dst->opcode = O (O_SYS_CLOSE, SB);
1194 break;
1195 case 0xca:
1196 dst->opcode = O (O_SYS_STAT, SB);
1197 break;
1198 case 0xcb:
1199 dst->opcode = O (O_SYS_FSTAT, SB);
1200 break;
1201 case 0xcc:
1202 dst->opcode = O (O_SYS_CMDLINE, SB);
1203 break;
1204 }
1205 /* End of Processing for system calls. */
1206 }
1207
1208 dst->next_pc = addr + len / 2;
1209 return;
1210 }
1211 else
9f70f8ec 1212 printf ("Don't understand 0x%x \n", looking_for);
dc5c3759
MS
1213 }
1214
1215 len++;
1216 nib++;
1217 }
1218
1219 fail:
1220 ;
1221 }
1222 end:
1223 /* Fell off the end. */
1224 dst->opcode = O (O_ILL, SB);
1225}
1226
1227static void
1228compile (SIM_DESC sd, int pc)
1229{
1230 int idx;
1231
1232 /* Find the next cache entry to use. */
1233 idx = h8_get_cache_top (sd) + 1;
1234 h8_increment_compiles (sd);
1235 if (idx >= sd->sim_cache_size)
c906108c 1236 {
dc5c3759
MS
1237 idx = 1;
1238 }
1239 h8_set_cache_top (sd, idx);
c906108c 1240
dc5c3759
MS
1241 /* Throw away its old meaning. */
1242 h8_set_cache_idx (sd, sd->sim_cache[idx].oldpc, 0);
1243
1244 /* Set to new address. */
1245 sd->sim_cache[idx].oldpc = pc;
c906108c 1246
dc5c3759
MS
1247 /* Fill in instruction info. */
1248 decode (sd, pc, h8_get_memory_buf (sd) + pc, sd->sim_cache + idx);
c906108c 1249
dc5c3759
MS
1250 /* Point to new cache entry. */
1251 h8_set_cache_idx (sd, pc, idx);
1252}
c906108c
SS
1253
1254
dc5c3759
MS
1255static unsigned char *breg[32];
1256static unsigned short *wreg[16];
1257static unsigned int *lreg[18];
1258
1259#define GET_B_REG(X) *(breg[X])
1260#define SET_B_REG(X, Y) (*(breg[X])) = (Y)
1261#define GET_W_REG(X) *(wreg[X])
1262#define SET_W_REG(X, Y) (*(wreg[X])) = (Y)
1263#define GET_L_REG(X) h8_get_reg (sd, X)
1264#define SET_L_REG(X, Y) h8_set_reg (sd, X, Y)
1265
1266#define GET_MEMORY_L(X) \
1267 ((X) < memory_size \
1268 ? ((h8_get_memory (sd, (X)+0) << 24) | (h8_get_memory (sd, (X)+1) << 16) \
1269 | (h8_get_memory (sd, (X)+2) << 8) | (h8_get_memory (sd, (X)+3) << 0)) \
1270 : ((h8_get_eightbit (sd, ((X)+0) & 0xff) << 24) \
1271 | (h8_get_eightbit (sd, ((X)+1) & 0xff) << 16) \
1272 | (h8_get_eightbit (sd, ((X)+2) & 0xff) << 8) \
1273 | (h8_get_eightbit (sd, ((X)+3) & 0xff) << 0)))
1274
1275#define GET_MEMORY_W(X) \
1276 ((X) < memory_size \
1277 ? ((h8_get_memory (sd, (X)+0) << 8) \
1278 | (h8_get_memory (sd, (X)+1) << 0)) \
1279 : ((h8_get_eightbit (sd, ((X)+0) & 0xff) << 8) \
1280 | (h8_get_eightbit (sd, ((X)+1) & 0xff) << 0)))
1281
1282
1283#define GET_MEMORY_B(X) \
1284 ((X) < memory_size ? (h8_get_memory (sd, (X))) \
1285 : (h8_get_eightbit (sd, (X) & 0xff)))
1286
1287#define SET_MEMORY_L(X, Y) \
1288{ register unsigned char *_p; register int __y = (Y); \
1289 _p = ((X) < memory_size ? h8_get_memory_buf (sd) + (X) : \
1290 h8_get_eightbit_buf (sd) + ((X) & 0xff)); \
1291 _p[0] = __y >> 24; _p[1] = __y >> 16; \
1292 _p[2] = __y >> 8; _p[3] = __y >> 0; \
1293}
c906108c 1294
dc5c3759
MS
1295#define SET_MEMORY_W(X, Y) \
1296{ register unsigned char *_p; register int __y = (Y); \
1297 _p = ((X) < memory_size ? h8_get_memory_buf (sd) + (X) : \
1298 h8_get_eightbit_buf (sd) + ((X) & 0xff)); \
1299 _p[0] = __y >> 8; _p[1] = __y; \
1300}
c906108c 1301
dc5c3759
MS
1302#define SET_MEMORY_B(X, Y) \
1303 ((X) < memory_size ? (h8_set_memory (sd, (X), (Y))) \
1304 : (h8_set_eightbit (sd, (X) & 0xff, (Y))))
c906108c 1305
dc5c3759
MS
1306/* Simulate a memory fetch.
1307 Return 0 for success, -1 for failure.
1308*/
c906108c 1309
dc5c3759
MS
1310static int
1311fetch_1 (SIM_DESC sd, ea_type *arg, int *val, int twice)
1312{
1313 int rn = arg->reg;
1314 int abs = arg->literal;
1315 int r;
1316 int t;
1317
1318 if (val == NULL)
1319 return -1; /* Paranoia. */
1320
1321 switch (arg->type)
1322 {
1323 /* Indexed register plus displacement mode:
1324
1325 This new family of addressing modes are similar to OP_DISP
1326 (register plus displacement), with two differences:
1327 1) INDEXB uses only the least significant byte of the register,
1328 INDEXW uses only the least significant word, and
1329 INDEXL uses the entire register (just like OP_DISP).
1330 and
1331 2) The displacement value in abs is multiplied by two
1332 for SW-sized operations, and by four for SL-size.
1333
1334 This gives nine possible variations.
1335 */
1336
1337 case X (OP_INDEXB, SB):
1338 case X (OP_INDEXB, SW):
1339 case X (OP_INDEXB, SL):
1340 case X (OP_INDEXW, SB):
1341 case X (OP_INDEXW, SW):
1342 case X (OP_INDEXW, SL):
1343 case X (OP_INDEXL, SB):
1344 case X (OP_INDEXL, SW):
1345 case X (OP_INDEXL, SL):
1346 t = GET_L_REG (rn);
1347 switch (OP_KIND (arg->type)) {
1348 case OP_INDEXB: t &= 0xff; break;
1349 case OP_INDEXW: t &= 0xffff; break;
1350 case OP_INDEXL:
1351 default: break;
1352 }
1353 switch (OP_SIZE (arg->type)) {
1354 case SB:
1355 *val = GET_MEMORY_B ((t * 1 + abs) & h8_get_mask (sd));
1356 break;
1357 case SW:
1358 *val = GET_MEMORY_W ((t * 2 + abs) & h8_get_mask (sd));
1359 break;
1360 case SL:
1361 *val = GET_MEMORY_L ((t * 4 + abs) & h8_get_mask (sd));
1362 break;
1363 }
1364 break;
1365
1366 case X (OP_LOWREG, SB):
1367 *val = GET_L_REG (rn) & 0xff;
1368 break;
1369 case X (OP_LOWREG, SW):
1370 *val = GET_L_REG (rn) & 0xffff;
1371 break;
1372
1373 case X (OP_REG, SB): /* Register direct, byte. */
1374 *val = GET_B_REG (rn);
1375 break;
1376 case X (OP_REG, SW): /* Register direct, word. */
1377 *val = GET_W_REG (rn);
1378 break;
1379 case X (OP_REG, SL): /* Register direct, long. */
1380 *val = GET_L_REG (rn);
1381 break;
1382 case X (OP_IMM, SB): /* Immediate, byte. */
1383 case X (OP_IMM, SW): /* Immediate, word. */
1384 case X (OP_IMM, SL): /* Immediate, long. */
1385 *val = abs;
1386 break;
1387 case X (OP_POSTINC, SB): /* Register indirect w/post-incr: byte. */
1388 t = GET_L_REG (rn);
3a6c31f9 1389 r = GET_MEMORY_B (t & h8_get_mask (sd));
dc5c3759
MS
1390 if (!twice)
1391 t += 1;
dc5c3759
MS
1392 SET_L_REG (rn, t);
1393 *val = r;
1394 break;
1395 case X (OP_POSTINC, SW): /* Register indirect w/post-incr: word. */
1396 t = GET_L_REG (rn);
3a6c31f9 1397 r = GET_MEMORY_W (t & h8_get_mask (sd));
dc5c3759
MS
1398 if (!twice)
1399 t += 2;
dc5c3759
MS
1400 SET_L_REG (rn, t);
1401 *val = r;
1402 break;
1403 case X (OP_POSTINC, SL): /* Register indirect w/post-incr: long. */
1404 t = GET_L_REG (rn);
3a6c31f9 1405 r = GET_MEMORY_L (t & h8_get_mask (sd));
dc5c3759
MS
1406 if (!twice)
1407 t += 4;
dc5c3759
MS
1408 SET_L_REG (rn, t);
1409 *val = r;
1410 break;
1411
1412 case X (OP_POSTDEC, SB): /* Register indirect w/post-decr: byte. */
1413 t = GET_L_REG (rn);
3a6c31f9 1414 r = GET_MEMORY_B (t & h8_get_mask (sd));
dc5c3759
MS
1415 if (!twice)
1416 t -= 1;
dc5c3759
MS
1417 SET_L_REG (rn, t);
1418 *val = r;
1419 break;
1420 case X (OP_POSTDEC, SW): /* Register indirect w/post-decr: word. */
1421 t = GET_L_REG (rn);
3a6c31f9 1422 r = GET_MEMORY_W (t & h8_get_mask (sd));
dc5c3759
MS
1423 if (!twice)
1424 t -= 2;
dc5c3759
MS
1425 SET_L_REG (rn, t);
1426 *val = r;
1427 break;
1428 case X (OP_POSTDEC, SL): /* Register indirect w/post-decr: long. */
1429 t = GET_L_REG (rn);
3a6c31f9 1430 r = GET_MEMORY_L (t & h8_get_mask (sd));
dc5c3759
MS
1431 if (!twice)
1432 t -= 4;
dc5c3759
MS
1433 SET_L_REG (rn, t);
1434 *val = r;
1435 break;
1436
1437 case X (OP_PREDEC, SB): /* Register indirect w/pre-decr: byte. */
1438 t = GET_L_REG (rn) - 1;
dc5c3759 1439 SET_L_REG (rn, t);
3a6c31f9 1440 t &= h8_get_mask (sd);
dc5c3759
MS
1441 *val = GET_MEMORY_B (t);
1442 break;
1443
1444 case X (OP_PREDEC, SW): /* Register indirect w/pre-decr: word. */
1445 t = GET_L_REG (rn) - 2;
dc5c3759 1446 SET_L_REG (rn, t);
3a6c31f9 1447 t &= h8_get_mask (sd);
dc5c3759
MS
1448 *val = GET_MEMORY_W (t);
1449 break;
1450
1451 case X (OP_PREDEC, SL): /* Register indirect w/pre-decr: long. */
1452 t = GET_L_REG (rn) - 4;
dc5c3759 1453 SET_L_REG (rn, t);
3a6c31f9 1454 t &= h8_get_mask (sd);
dc5c3759
MS
1455 *val = GET_MEMORY_L (t);
1456 break;
1457
1458 case X (OP_PREINC, SB): /* Register indirect w/pre-incr: byte. */
1459 t = GET_L_REG (rn) + 1;
dc5c3759 1460 SET_L_REG (rn, t);
3a6c31f9 1461 t &= h8_get_mask (sd);
dc5c3759
MS
1462 *val = GET_MEMORY_B (t);
1463 break;
1464
1465 case X (OP_PREINC, SW): /* Register indirect w/pre-incr: long. */
1466 t = GET_L_REG (rn) + 2;
dc5c3759 1467 SET_L_REG (rn, t);
3a6c31f9 1468 t &= h8_get_mask (sd);
dc5c3759
MS
1469 *val = GET_MEMORY_W (t);
1470 break;
1471
1472 case X (OP_PREINC, SL): /* Register indirect w/pre-incr: long. */
1473 t = GET_L_REG (rn) + 4;
dc5c3759 1474 SET_L_REG (rn, t);
3a6c31f9 1475 t &= h8_get_mask (sd);
dc5c3759
MS
1476 *val = GET_MEMORY_L (t);
1477 break;
1478
1479 case X (OP_DISP, SB): /* Register indirect w/displacement: byte. */
1480 t = GET_L_REG (rn) + abs;
1481 t &= h8_get_mask (sd);
1482 *val = GET_MEMORY_B (t);
1483 break;
1484
1485 case X (OP_DISP, SW): /* Register indirect w/displacement: word. */
1486 t = GET_L_REG (rn) + abs;
1487 t &= h8_get_mask (sd);
1488 *val = GET_MEMORY_W (t);
1489 break;
1490
1491 case X (OP_DISP, SL): /* Register indirect w/displacement: long. */
1492 t = GET_L_REG (rn) + abs;
1493 t &= h8_get_mask (sd);
1494 *val =GET_MEMORY_L (t);
1495 break;
1496
1497 case X (OP_MEM, SL): /* Absolute memory address, long. */
1498 t = GET_MEMORY_L (abs);
1499 t &= h8_get_mask (sd);
1500 *val = t;
1501 break;
1502
1503 case X (OP_MEM, SW): /* Absolute memory address, word. */
1504 t = GET_MEMORY_W (abs);
1505 t &= h8_get_mask (sd);
1506 *val = t;
1507 break;
1508
1509 case X (OP_PCREL, SB): /* PC relative (for jump, branch etc). */
1510 case X (OP_PCREL, SW):
1511 case X (OP_PCREL, SL):
1512 case X (OP_PCREL, SN):
1513 *val = abs;
1514 break;
1515
1516 case X (OP_MEM, SB): /* Why isn't this implemented? */
1517 default:
1518 sim_engine_set_run_state (sd, sim_stopped, SIGSEGV);
1519 return -1;
1520 }
1521 return 0; /* Success. */
1522}
1523
1524/* Normal fetch. */
1525
1526static int
1527fetch (SIM_DESC sd, ea_type *arg, int *val)
1528{
1529 return fetch_1 (sd, arg, val, 0);
1530}
1531
1532/* Fetch which will be followed by a store to the same location.
1533 The difference being that we don't want to do a post-increment
1534 or post-decrement at this time: we'll do it when we store. */
1535
1536static int
1537fetch2 (SIM_DESC sd, ea_type *arg, int *val)
1538{
1539 return fetch_1 (sd, arg, val, 1);
1540}
1541
1542/* Simulate a memory store.
1543 Return 0 for success, -1 for failure.
1544*/
1545
1546static int
1547store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
1548{
1549 int rn = arg->reg;
1550 int abs = arg->literal;
1551 int t;
1552
1553 switch (arg->type)
1554 {
1555 /* Indexed register plus displacement mode:
1556
1557 This new family of addressing modes are similar to OP_DISP
1558 (register plus displacement), with two differences:
1559 1) INDEXB uses only the least significant byte of the register,
1560 INDEXW uses only the least significant word, and
1561 INDEXL uses the entire register (just like OP_DISP).
1562 and
1563 2) The displacement value in abs is multiplied by two
1564 for SW-sized operations, and by four for SL-size.
1565
1566 This gives nine possible variations.
1567 */
1568
1569 case X (OP_INDEXB, SB):
1570 case X (OP_INDEXB, SW):
1571 case X (OP_INDEXB, SL):
1572 case X (OP_INDEXW, SB):
1573 case X (OP_INDEXW, SW):
1574 case X (OP_INDEXW, SL):
1575 case X (OP_INDEXL, SB):
1576 case X (OP_INDEXL, SW):
1577 case X (OP_INDEXL, SL):
1578 t = GET_L_REG (rn);
1579 switch (OP_KIND (arg->type)) {
1580 case OP_INDEXB: t &= 0xff; break;
1581 case OP_INDEXW: t &= 0xffff; break;
1582 case OP_INDEXL:
1583 default: break;
1584 }
1585 switch (OP_SIZE (arg->type)) {
1586 case SB:
1587 SET_MEMORY_B ((t * 1 + abs) & h8_get_mask (sd), n);
1588 break;
1589 case SW:
1590 SET_MEMORY_W ((t * 2 + abs) & h8_get_mask (sd), n);
1591 break;
1592 case SL:
1593 SET_MEMORY_L ((t * 4 + abs) & h8_get_mask (sd), n);
1594 break;
1595 }
1596 break;
1597
1598 case X (OP_REG, SB): /* Register direct, byte. */
1599 SET_B_REG (rn, n);
1600 break;
1601 case X (OP_REG, SW): /* Register direct, word. */
1602 SET_W_REG (rn, n);
1603 break;
1604 case X (OP_REG, SL): /* Register direct, long. */
1605 SET_L_REG (rn, n);
1606 break;
1607
1608 case X (OP_PREDEC, SB): /* Register indirect w/pre-decr, byte. */
1609 t = GET_L_REG (rn);
1610 if (!twice)
1611 t -= 1;
dc5c3759 1612 SET_L_REG (rn, t);
3a6c31f9 1613 t &= h8_get_mask (sd);
dc5c3759
MS
1614 SET_MEMORY_B (t, n);
1615
1616 break;
1617 case X (OP_PREDEC, SW): /* Register indirect w/pre-decr, word. */
1618 t = GET_L_REG (rn);
1619 if (!twice)
1620 t -= 2;
dc5c3759 1621 SET_L_REG (rn, t);
3a6c31f9 1622 t &= h8_get_mask (sd);
dc5c3759
MS
1623 SET_MEMORY_W (t, n);
1624 break;
1625
1626 case X (OP_PREDEC, SL): /* Register indirect w/pre-decr, long. */
1627 t = GET_L_REG (rn);
1628 if (!twice)
1629 t -= 4;
dc5c3759 1630 SET_L_REG (rn, t);
3a6c31f9 1631 t &= h8_get_mask (sd);
dc5c3759
MS
1632 SET_MEMORY_L (t, n);
1633 break;
1634
1635 case X (OP_PREINC, SB): /* Register indirect w/pre-incr, byte. */
1636 t = GET_L_REG (rn);
1637 if (!twice)
1638 t += 1;
dc5c3759 1639 SET_L_REG (rn, t);
3a6c31f9 1640 t &= h8_get_mask (sd);
dc5c3759
MS
1641 SET_MEMORY_B (t, n);
1642
1643 break;
1644 case X (OP_PREINC, SW): /* Register indirect w/pre-incr, word. */
1645 t = GET_L_REG (rn);
1646 if (!twice)
1647 t += 2;
dc5c3759 1648 SET_L_REG (rn, t);
3a6c31f9 1649 t &= h8_get_mask (sd);
dc5c3759
MS
1650 SET_MEMORY_W (t, n);
1651 break;
1652
1653 case X (OP_PREINC, SL): /* Register indirect w/pre-incr, long. */
1654 t = GET_L_REG (rn);
1655 if (!twice)
1656 t += 4;
dc5c3759 1657 SET_L_REG (rn, t);
3a6c31f9 1658 t &= h8_get_mask (sd);
dc5c3759
MS
1659 SET_MEMORY_L (t, n);
1660 break;
1661
1662 case X (OP_POSTDEC, SB): /* Register indirect w/post-decr, byte. */
3a6c31f9 1663 t = GET_L_REG (rn);
dc5c3759 1664 SET_L_REG (rn, t - 1);
3a6c31f9
YS
1665 t &= h8_get_mask (sd);
1666 SET_MEMORY_B (t, n);
dc5c3759
MS
1667 break;
1668
1669 case X (OP_POSTDEC, SW): /* Register indirect w/post-decr, word. */
3a6c31f9 1670 t = GET_L_REG (rn);
dc5c3759 1671 SET_L_REG (rn, t - 2);
3a6c31f9
YS
1672 t &= h8_get_mask (sd);
1673 SET_MEMORY_W (t, n);
dc5c3759
MS
1674 break;
1675
1676 case X (OP_POSTDEC, SL): /* Register indirect w/post-decr, long. */
3a6c31f9 1677 t = GET_L_REG (rn);
dc5c3759 1678 SET_L_REG (rn, t - 4);
3a6c31f9
YS
1679 t &= h8_get_mask (sd);
1680 SET_MEMORY_L (t, n);
dc5c3759
MS
1681 break;
1682
1683 case X (OP_POSTINC, SB): /* Register indirect w/post-incr, byte. */
3a6c31f9 1684 t = GET_L_REG (rn);
dc5c3759 1685 SET_L_REG (rn, t + 1);
3a6c31f9
YS
1686 t &= h8_get_mask (sd);
1687 SET_MEMORY_B (t, n);
dc5c3759
MS
1688 break;
1689
1690 case X (OP_POSTINC, SW): /* Register indirect w/post-incr, word. */
3a6c31f9 1691 t = GET_L_REG (rn);
dc5c3759 1692 SET_L_REG (rn, t + 2);
3a6c31f9
YS
1693 t &= h8_get_mask (sd);
1694 SET_MEMORY_W (t, n);
dc5c3759
MS
1695 break;
1696
1697 case X (OP_POSTINC, SL): /* Register indirect w/post-incr, long. */
3a6c31f9 1698 t = GET_L_REG (rn);
dc5c3759 1699 SET_L_REG (rn, t + 4);
3a6c31f9
YS
1700 t &= h8_get_mask (sd);
1701 SET_MEMORY_L (t, n);
dc5c3759
MS
1702 break;
1703
1704 case X (OP_DISP, SB): /* Register indirect w/displacement, byte. */
1705 t = GET_L_REG (rn) + abs;
1706 t &= h8_get_mask (sd);
1707 SET_MEMORY_B (t, n);
1708 break;
1709
1710 case X (OP_DISP, SW): /* Register indirect w/displacement, word. */
1711 t = GET_L_REG (rn) + abs;
1712 t &= h8_get_mask (sd);
1713 SET_MEMORY_W (t, n);
1714 break;
1715
1716 case X (OP_DISP, SL): /* Register indirect w/displacement, long. */
1717 t = GET_L_REG (rn) + abs;
1718 t &= h8_get_mask (sd);
1719 SET_MEMORY_L (t, n);
1720 break;
1721
1722
1723 case X (OP_MEM, SB): /* Why isn't this implemented? */
1724 case X (OP_MEM, SW): /* Why isn't this implemented? */
1725 case X (OP_MEM, SL): /* Why isn't this implemented? */
1726 default:
1727 sim_engine_set_run_state (sd, sim_stopped, SIGSEGV);
1728 return -1;
1729 }
1730 return 0;
1731}
1732
1733/* Normal store. */
1734
1735static int
1736store (SIM_DESC sd, ea_type *arg, int n)
1737{
1738 return store_1 (sd, arg, n, 0);
1739}
1740
1741/* Store which follows a fetch from the same location.
1742 The difference being that we don't want to do a pre-increment
1743 or pre-decrement at this time: it was already done when we fetched. */
1744
1745static int
1746store2 (SIM_DESC sd, ea_type *arg, int n)
1747{
1748 return store_1 (sd, arg, n, 1);
1749}
1750
1751static union
1752{
1753 short int i;
1754 struct
1755 {
1756 char low;
1757 char high;
1758 }
1759 u;
1760} littleendian;
1761
1762/* Flag to be set whenever a new SIM_DESC object is created. */
1763static int init_pointers_needed = 1;
1764
1765static void
1766init_pointers (SIM_DESC sd)
1767{
1768 if (init_pointers_needed)
1769 {
1770 int i;
1771
1772 littleendian.i = 1;
1773
59768597 1774 if (h8300smode && !h8300_normal_mode)
dc5c3759 1775 memory_size = H8300S_MSIZE;
59768597 1776 else if (h8300hmode && !h8300_normal_mode)
dc5c3759
MS
1777 memory_size = H8300H_MSIZE;
1778 else
1779 memory_size = H8300_MSIZE;
1780 /* `msize' must be a power of two. */
1781 if ((memory_size & (memory_size - 1)) != 0)
1782 {
1783 (*sim_callback->printf_filtered)
1784 (sim_callback,
1785 "init_pointers: bad memory size %d, defaulting to %d.\n",
1786 memory_size, memory_size = H8300S_MSIZE);
1787 }
1788
1789 if (h8_get_memory_buf (sd))
1790 free (h8_get_memory_buf (sd));
1791 if (h8_get_cache_idx_buf (sd))
1792 free (h8_get_cache_idx_buf (sd));
1793 if (h8_get_eightbit_buf (sd))
1794 free (h8_get_eightbit_buf (sd));
1795
1796 h8_set_memory_buf (sd, (unsigned char *)
1797 calloc (sizeof (char), memory_size));
1798 h8_set_cache_idx_buf (sd, (unsigned short *)
1799 calloc (sizeof (short), memory_size));
1800 sd->memory_size = memory_size;
1801 h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256));
1802
1803 h8_set_mask (sd, memory_size - 1);
1804
1805 memset (h8_get_reg_buf (sd), 0, sizeof (((STATE_CPU (sd, 0))->regs)));
1806
1807 for (i = 0; i < 8; i++)
1808 {
1809 /* FIXME: rewrite using local buffer. */
1810 unsigned char *p = (unsigned char *) (h8_get_reg_buf (sd) + i);
1811 unsigned char *e = (unsigned char *) (h8_get_reg_buf (sd) + i + 1);
1812 unsigned short *q = (unsigned short *) (h8_get_reg_buf (sd) + i);
1813 unsigned short *u = (unsigned short *) (h8_get_reg_buf (sd) + i + 1);
1814 h8_set_reg (sd, i, 0x00112233);
1815
1816 while (p < e)
1817 {
1818 if (*p == 0x22)
1819 breg[i] = p;
1820 if (*p == 0x33)
1821 breg[i + 8] = p;
1822 if (*p == 0x11)
1823 breg[i + 16] = p;
1824 if (*p == 0x00)
1825 breg[i + 24] = p;
1826 p++;
1827 }
1828
1829 wreg[i] = wreg[i + 8] = 0;
1830 while (q < u)
1831 {
1832 if (*q == 0x2233)
1833 {
1834 wreg[i] = q;
1835 }
1836 if (*q == 0x0011)
1837 {
1838 wreg[i + 8] = q;
1839 }
1840 q++;
1841 }
1842
1843 if (wreg[i] == 0 || wreg[i + 8] == 0)
1844 (*sim_callback->printf_filtered) (sim_callback,
1845 "init_pointers: internal error.\n");
1846
1847 h8_set_reg (sd, i, 0);
1848 lreg[i] = h8_get_reg_buf (sd) + i;
1849 }
1850
1851 /* Note: sim uses pseudo-register ZERO as a zero register. */
1852 lreg[ZERO_REGNUM] = h8_get_reg_buf (sd) + ZERO_REGNUM;
1853 init_pointers_needed = 0;
1854
1855 /* Initialize the seg registers. */
1856 if (!sd->sim_cache)
1857 set_simcache_size (sd, CSIZE);
1858 }
1859}
1860
1861/* Grotty global variable for use by control_c signal handler. */
1862static SIM_DESC control_c_sim_desc;
1863
1864static void
1865control_c (int sig)
1866{
1867 sim_engine_set_run_state (control_c_sim_desc, sim_stopped, SIGINT);
1868}
1869
1870int
1871sim_stop (SIM_DESC sd)
1872{
1873 /* FIXME: use a real signal value. */
1874 sim_engine_set_run_state (sd, sim_stopped, SIGINT);
1875 return 1;
1876}
1877
1878#define OBITOP(name, f, s, op) \
1879case O (name, SB): \
1880{ \
1881 int m, tmp; \
1882 \
1883 if (f) \
1884 if (fetch (sd, &code->dst, &ea)) \
1885 goto end; \
1886 if (fetch (sd, &code->src, &tmp)) \
1887 goto end; \
b86015ea 1888 m = 1 << (tmp & 7); \
dc5c3759
MS
1889 op; \
1890 if (s) \
1891 if (store (sd, &code->dst,ea)) \
1892 goto end; \
1893 goto next; \
1894}
1895
1896void
1897sim_resume (SIM_DESC sd, int step, int siggnal)
1898{
1899 static int init1;
1900 int cycles = 0;
1901 int insts = 0;
1902 int tick_start = get_now ();
1903 void (*prev) ();
1904 int poll_count = 0;
1905 int res;
1906 int tmp;
1907 int rd;
1908 int ea;
1909 int bit;
1910 int pc;
1911 int c, nz, v, n, u, h, ui, intMaskBit;
1912 int trace, intMask;
1913 int oldmask;
1914 enum sim_stop reason;
1915 int sigrc;
1916
1917 init_pointers (sd);
1918
1919 control_c_sim_desc = sd;
1920 prev = signal (SIGINT, control_c);
1921
1922 if (step)
1923 {
1924 sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
1925 }
1926 else
1927 {
1928 sim_engine_set_run_state (sd, sim_running, 0);
1929 }
1930
1931 pc = h8_get_pc (sd);
1932
1933 /* The PC should never be odd. */
1934 if (pc & 0x1)
1935 {
1936 sim_engine_set_run_state (sd, sim_stopped, SIGBUS);
1937 return;
1938 }
1939
1940 /* Get Status Register (flags). */
9f70f8ec 1941 GETSR (sd);
dc5c3759
MS
1942
1943 if (h8300smode) /* Get exr. */
1944 {
1945 trace = (h8_get_exr (sd) >> 7) & 1;
1946 intMask = h8_get_exr (sd) & 7;
1947 }
1948
1949 oldmask = h8_get_mask (sd);
59768597 1950 if (!h8300hmode || h8300_normal_mode)
dc5c3759
MS
1951 h8_set_mask (sd, 0xffff);
1952 do
1953 {
1954 unsigned short cidx;
1955 decoded_inst *code;
1956
1957 top:
1958 cidx = h8_get_cache_idx (sd, pc);
1959 if (cidx == (unsigned short) -1 ||
1960 cidx >= sd->sim_cache_size)
1961 goto illegal;
1962
1963 code = sd->sim_cache + cidx;
1964
1965#if ADEBUG
1966 if (debug)
1967 {
1968 printf ("%x %d %s\n", pc, code->opcode,
1969 code->op ? code->op->name : "**");
1970 }
1971 h8_increment_stats (sd, code->opcode);
1972#endif
1973
1974 if (code->opcode)
1975 {
1976 cycles += code->cycles;
1977 insts++;
1978 }
1979
1980 switch (code->opcode)
1981 {
1982 case 0:
1983 /*
1984 * This opcode is a fake for when we get to an
1985 * instruction which hasnt been compiled
1986 */
1987 compile (sd, pc);
1988 goto top;
1989 break;
1990
1991 case O (O_MOVAB, SL):
1992 case O (O_MOVAW, SL):
1993 case O (O_MOVAL, SL):
1994 /* 1) Evaluate 2nd argument (dst).
1995 2) Mask / zero extend according to whether 1st argument (src)
1996 is INDEXB, INDEXW, or INDEXL.
1997 3) Left-shift the result by 0, 1 or 2, according to size of mova
1998 (mova/b, mova/w, mova/l).
1999 4) Add literal value of 1st argument (src).
2000 5) Store result in 3rd argument (op3).
f408565c
MS
2001 */
2002
2003 /* Alas, since this is the only instruction with 3 arguments,
2004 decode doesn't handle them very well. Some fix-up is required.
2005
2006 a) The size of dst is determined by whether src is
2007 INDEXB or INDEXW. */
dc5c3759 2008
f408565c
MS
2009 if (OP_KIND (code->src.type) == OP_INDEXB)
2010 code->dst.type = X (OP_KIND (code->dst.type), SB);
2011 else if (OP_KIND (code->src.type) == OP_INDEXW)
2012 code->dst.type = X (OP_KIND (code->dst.type), SW);
2013
2014 /* b) If op3 == null, then this is the short form of the insn.
2015 Dst is the dispreg of src, and op3 is the 32-bit form
2016 of the same register.
dc5c3759 2017 */
f408565c
MS
2018
2019 if (code->op3.type == 0)
2020 {
2021 /* Short form: src == INDEXB/INDEXW, dst == op3 == 0.
2022 We get to compose dst and op3 as follows:
2023
2024 op3 is a 32-bit register, ID == src.reg.
2025 dst is the same register, but 8 or 16 bits
2026 depending on whether src is INDEXB or INDEXW.
2027 */
2028
2029 code->op3.type = X (OP_REG, SL);
2030 code->op3.reg = code->src.reg;
2031 code->op3.literal = 0;
2032
2033 if (OP_KIND (code->src.type) == OP_INDEXB)
e073c474
AO
2034 {
2035 code->dst.type = X (OP_REG, SB);
2036 code->dst.reg = code->op3.reg + 8;
2037 }
f408565c
MS
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);
d6fd015d 2566 rd = h8_get_exr (sd);
dc5c3759
MS
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. */
59768597 2793 if ((h8300hmode || h8300smode) && !h8300_normal_mode)
dc5c3759
MS
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. */
917c78f9 2807 ind_arg_len = strlen (h8_get_cmdline_arg (sd, i)) + 1;
dc5c3759
MS
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. */
59768597 2862 if ((h8300hmode || h8300smode) && !h8300_normal_mode)
dc5c3759
MS
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. */
59768597 2878 if ((h8300hmode || h8300smode) && !h8300_normal_mode)
dc5c3759
MS
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. */
59768597 2917 if ((h8300sxmode || h8300hmode || h8300smode) && !h8300_normal_mode)
dc5c3759
MS
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
59768597
SA
2968 fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
2969 buf_size = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
dc5c3759
MS
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
59768597
SA
3003 fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
3004 char_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
3005 len = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
dc5c3759
MS
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
59768597
SA
3035 fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
3036 offset = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
3037 origin = (h8300hmode && !h8300_normal_mode) ? 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
59768597 3053 fd = (h8300hmode && !h8300_normal_mode) ? 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
59768597 3071 fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
c906108c 3072
dc5c3759 3073 /* Setting stat_ptr to second argument of stat. */
59768597 3074 stat_ptr = (h8300hmode && !h8300_normal_mode) ? 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 3122 /* Setting filename_ptr to first argument of open. */
59768597 3123 filename_ptr = (h8300hmode && !h8300_normal_mode) ? 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); */
59768597 3147 stat_ptr = (h8300hmode && !h8300_normal_mode) ? 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
59768597 3555 if (h8300hmode && !h8300_normal_mode)
9f70f8ec
MS
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 }
59768597 3587 if (h8300hmode && !h8300_normal_mode)
9f70f8ec
MS
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
59768597 3610 if (h8300hmode && !h8300_normal_mode)
9f70f8ec
MS
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))
59768597
SA
3658 goto end; /* res is vector number. */
3659
3660 tmp = h8_get_reg (sd, SP_REGNUM);
3661 if(h8300_normal_mode)
3662 {
3663 tmp -= 2;
3664 SET_MEMORY_W (tmp, code->next_pc);
3665 tmp -= 2;
3666 SET_MEMORY_W (tmp, h8_get_ccr (sd));
3667 }
3668 else
3669 {
3670 tmp -= 4;
3671 SET_MEMORY_L (tmp, code->next_pc);
3672 tmp -= 4;
3673 SET_MEMORY_L (tmp, h8_get_ccr (sd));
3674 }
3675 intMaskBit = 1;
3676 BUILDSR (sd);
3677
9f70f8ec
MS
3678 if (h8300smode)
3679 {
3680 tmp -= 4;
3681 SET_MEMORY_L (tmp, h8_get_exr (sd));
3682 }
3683
3684 h8_set_reg (sd, SP_REGNUM, tmp);
3685
59768597
SA
3686 if(h8300_normal_mode)
3687 pc = GET_MEMORY_L (0x10 + res * 2); /* Vector addresses are 0x10,0x12,0x14 and 0x16 */
3688 else
3689 pc = GET_MEMORY_L (0x20 + res * 4);
9f70f8ec
MS
3690 goto end;
3691
dc5c3759
MS
3692 case O (O_BPT, SN):
3693 sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
3694 goto end;
bf174226 3695
dc5c3759
MS
3696 case O (O_BSETEQ, SB):
3697 if (Z)
3698 goto bset;
3699 goto next;
bf174226 3700
dc5c3759
MS
3701 case O (O_BSETNE, SB):
3702 if (!Z)
3703 goto bset;
3704 goto next;
bf174226 3705
dc5c3759
MS
3706 case O (O_BCLREQ, SB):
3707 if (Z)
3708 goto bclr;
3709 goto next;
bf174226 3710
dc5c3759
MS
3711 case O (O_BCLRNE, SB):
3712 if (!Z)
3713 goto bclr;
3714 goto next;
bf174226 3715
dc5c3759
MS
3716 OBITOP (O_BNOT, 1, 1, ea ^= m); /* bnot */
3717 OBITOP (O_BTST, 1, 0, nz = ea & m); /* btst */
3718 bset:
3719 OBITOP (O_BSET, 1, 1, ea |= m); /* bset */
3720 bclr:
3721 OBITOP (O_BCLR, 1, 1, ea &= ~m); /* bclr */
3722 OBITOP (O_BLD, 1, 0, c = ea & m); /* bld */
3723 OBITOP (O_BILD, 1, 0, c = !(ea & m)); /* bild */
3724 OBITOP (O_BST, 1, 1, ea &= ~m;
3725 if (C) ea |= m); /* bst */
3726 OBITOP (O_BIST, 1, 1, ea &= ~m;
3727 if (!C) ea |= m); /* bist */
3728 OBITOP (O_BSTZ, 1, 1, ea &= ~m;
3729 if (Z) ea |= m); /* bstz */
3730 OBITOP (O_BISTZ, 1, 1, ea &= ~m;
3731 if (!Z) ea |= m); /* bistz */
3732 OBITOP (O_BAND, 1, 0, c = (ea & m) && C); /* band */
3733 OBITOP (O_BIAND, 1, 0, c = !(ea & m) && C); /* biand */
3734 OBITOP (O_BOR, 1, 0, c = (ea & m) || C); /* bor */
3735 OBITOP (O_BIOR, 1, 0, c = !(ea & m) || C); /* bior */
3736 OBITOP (O_BXOR, 1, 0, c = ((ea & m) != 0)!= C); /* bxor */
3737 OBITOP (O_BIXOR, 1, 0, c = !(ea & m) != C); /* bixor */
3738
3739 case O (O_BFLD, SB): /* bfld */
3740 /* bitfield load */
3741 ea = 0;
3742 if (fetch (sd, &code->src, &bit))
3743 goto end;
bf174226 3744
dc5c3759
MS
3745 if (bit != 0)
3746 {
3747 if (fetch (sd, &code->dst, &ea))
3748 goto end;
bf174226 3749
dc5c3759
MS
3750 ea &= bit;
3751 while (!(bit & 1))
3752 {
3753 ea >>= 1;
3754 bit >>= 1;
3755 }
3756 }
3757 if (store (sd, &code->op3, ea))
3758 goto end;
bf174226 3759
c906108c
SS
3760 goto next;
3761
dc5c3759
MS
3762 case O(O_BFST, SB): /* bfst */
3763 /* bitfield store */
3764 /* NOTE: the imm8 value is in dst, and the ea value
3765 (which is actually the destination) is in op3.
3766 It has to be that way, to avoid breaking the assembler. */
bf174226 3767
dc5c3759
MS
3768 if (fetch (sd, &code->dst, &bit)) /* imm8 */
3769 goto end;
3770 if (bit == 0) /* noop -- nothing to do. */
3771 goto next;
bf174226 3772
dc5c3759
MS
3773 if (fetch (sd, &code->src, &rd)) /* reg8 src */
3774 goto end;
bf174226 3775
dc5c3759
MS
3776 if (fetch2 (sd, &code->op3, &ea)) /* ea dst */
3777 goto end;
bf174226 3778
dc5c3759
MS
3779 /* Left-shift the register data into position. */
3780 for (tmp = bit; !(tmp & 1); tmp >>= 1)
3781 rd <<= 1;
bf174226 3782
dc5c3759
MS
3783 /* Combine it with the neighboring bits. */
3784 ea = (ea & ~bit) | (rd & bit);
bf174226 3785
dc5c3759
MS
3786 /* Put it back. */
3787 if (store2 (sd, &code->op3, ea))
3788 goto end;
3789 goto next;
3790
3791 case O (O_CLRMAC, SN): /* clrmac */
3792 h8_set_mach (sd, 0);
3793 h8_set_macl (sd, 0);
3794 h8_set_macZ (sd, 1);
3795 h8_set_macV (sd, 0);
3796 h8_set_macN (sd, 0);
3797 goto next;
3798
3799 case O (O_STMAC, SL): /* stmac, 260 */
3800 switch (code->src.type) {
3801 case X (OP_MACH, SL):
3802 res = h8_get_mach (sd);
3803 if (res & 0x200) /* sign extend */
3804 res |= 0xfffffc00;
3805 break;
3806 case X (OP_MACL, SL):
3807 res = h8_get_macl (sd);
3808 break;
3809 default: goto illegal;
bf174226 3810 }
dc5c3759
MS
3811 nz = !h8_get_macZ (sd);
3812 n = h8_get_macN (sd);
3813 v = h8_get_macV (sd);
3814
3815 if (store (sd, &code->dst, res))
3816 goto end;
3817
bf174226
V
3818 goto next;
3819
dc5c3759
MS
3820 case O (O_LDMAC, SL): /* ldmac, 179 */
3821 if (fetch (sd, &code->src, &rd))
3822 goto end;
bf174226 3823
dc5c3759
MS
3824 switch (code->dst.type) {
3825 case X (OP_MACH, SL):
3826 rd &= 0x3ff; /* Truncate to 10 bits */
3827 h8_set_mach (sd, rd);
3828 break;
3829 case X (OP_MACL, SL):
3830 h8_set_macl (sd, rd);
3831 break;
3832 default: goto illegal;
3833 }
3834 h8_set_macV (sd, 0);
3835 goto next;
bf174226 3836
dc5c3759
MS
3837 case O (O_MAC, SW):
3838 if (fetch (sd, &code->src, &rd) ||
3839 fetch (sd, &code->dst, &res))
3840 goto end;
bf174226 3841
dc5c3759
MS
3842 /* Ye gods, this is non-portable!
3843 However, the existing mul/div code is similar. */
3844 res = SEXTSHORT (res) * SEXTSHORT (rd);
bf174226 3845
dc5c3759
MS
3846 if (h8_get_macS (sd)) /* Saturating mode */
3847 {
3848 long long mac = h8_get_macl (sd);
bf174226 3849
dc5c3759
MS
3850 if (mac & 0x80000000) /* sign extend */
3851 mac |= 0xffffffff00000000LL;
bf174226 3852
dc5c3759
MS
3853 mac += res;
3854 if (mac > 0x7fffffff || mac < 0xffffffff80000000LL)
3855 h8_set_macV (sd, 1);
3856 h8_set_macZ (sd, (mac == 0));
3857 h8_set_macN (sd, (mac < 0));
3858 h8_set_macl (sd, (int) mac);
3859 }
3860 else /* "Less Saturating" mode */
3861 {
3862 long long mac = h8_get_mach (sd);
3863 mac <<= 32;
3864 mac += h8_get_macl (sd);
3865
3866 if (mac & 0x20000000000LL) /* sign extend */
3867 mac |= 0xfffffc0000000000LL;
3868
3869 mac += res;
3870 if (mac > 0x1ffffffffffLL ||
3871 mac < (long long) 0xfffffe0000000000LL)
3872 h8_set_macV (sd, 1);
3873 h8_set_macZ (sd, (mac == 0));
3874 h8_set_macN (sd, (mac < 0));
3875 h8_set_macl (sd, (int) mac);
3876 mac >>= 32;
3877 h8_set_mach (sd, (int) (mac & 0x3ff));
3878 }
bf174226
V
3879 goto next;
3880
dc5c3759
MS
3881 case O (O_MULS, SW): /* muls.w */
3882 if (fetch (sd, &code->src, &ea) ||
3883 fetch (sd, &code->dst, &rd))
3884 goto end;
bf174226 3885
e073c474 3886 ea = SEXTSHORT (ea);
dc5c3759
MS
3887 res = SEXTSHORT (ea * SEXTSHORT (rd));
3888
3889 n = res & 0x8000;
3890 nz = res & 0xffff;
3891 if (store (sd, &code->dst, res))
3892 goto end;
bf174226 3893
bf174226
V
3894 goto next;
3895
dc5c3759
MS
3896 case O (O_MULS, SL): /* muls.l */
3897 if (fetch (sd, &code->src, &ea) ||
3898 fetch (sd, &code->dst, &rd))
3899 goto end;
bf174226 3900
dc5c3759 3901 res = ea * rd;
bf174226 3902
dc5c3759
MS
3903 n = res & 0x80000000;
3904 nz = res & 0xffffffff;
3905 if (store (sd, &code->dst, res))
3906 goto end;
bf174226
V
3907 goto next;
3908
dc5c3759
MS
3909 case O (O_MULSU, SL): /* muls/u.l */
3910 if (fetch (sd, &code->src, &ea) ||
3911 fetch (sd, &code->dst, &rd))
3912 goto end;
bf174226 3913
dc5c3759
MS
3914 /* Compute upper 32 bits of the 64-bit result. */
3915 res = (((long long) ea) * ((long long) rd)) >> 32;
bf174226 3916
dc5c3759
MS
3917 n = res & 0x80000000;
3918 nz = res & 0xffffffff;
3919 if (store (sd, &code->dst, res))
3920 goto end;
3921 goto next;
bf174226 3922
dc5c3759
MS
3923 case O (O_MULU, SW): /* mulu.w */
3924 if (fetch (sd, &code->src, &ea) ||
3925 fetch (sd, &code->dst, &rd))
3926 goto end;
bf174226 3927
dc5c3759
MS
3928 res = UEXTSHORT ((UEXTSHORT (ea) * UEXTSHORT (rd)));
3929
3930 /* Don't set Z or N. */
3931 if (store (sd, &code->dst, res))
3932 goto end;
bf174226 3933
bf174226
V
3934 goto next;
3935
dc5c3759
MS
3936 case O (O_MULU, SL): /* mulu.l */
3937 if (fetch (sd, &code->src, &ea) ||
3938 fetch (sd, &code->dst, &rd))
3939 goto end;
bf174226 3940
dc5c3759 3941 res = ea * rd;
bf174226 3942
dc5c3759
MS
3943 /* Don't set Z or N. */
3944 if (store (sd, &code->dst, res))
3945 goto end;
bf174226 3946
dc5c3759 3947 goto next;
bf174226 3948
dc5c3759
MS
3949 case O (O_MULUU, SL): /* mulu/u.l */
3950 if (fetch (sd, &code->src, &ea) ||
3951 fetch (sd, &code->dst, &rd))
3952 goto end;
bf174226 3953
dc5c3759
MS
3954 /* Compute upper 32 bits of the 64-bit result. */
3955 res = (((unsigned long long) (unsigned) ea) *
3956 ((unsigned long long) (unsigned) rd)) >> 32;
bf174226 3957
dc5c3759
MS
3958 /* Don't set Z or N. */
3959 if (store (sd, &code->dst, res))
3960 goto end;
bf174226 3961
dc5c3759 3962 goto next;
bf174226 3963
dc5c3759
MS
3964 case O (O_MULXS, SB): /* mulxs.b */
3965 if (fetch (sd, &code->src, &ea) ||
3966 fetch (sd, &code->dst, &rd))
3967 goto end;
bf174226 3968
e073c474 3969 ea = SEXTCHAR (ea);
dc5c3759
MS
3970 res = ea * SEXTCHAR (rd);
3971
3972 n = res & 0x8000;
3973 nz = res & 0xffff;
3974 if (store (sd, &code->dst, res))
3975 goto end;
bf174226 3976
bf174226 3977 goto next;
bf174226 3978
dc5c3759
MS
3979 case O (O_MULXS, SW): /* mulxs.w */
3980 if (fetch (sd, &code->src, &ea) ||
3981 fetch (sd, &code->dst, &rd))
c906108c
SS
3982 goto end;
3983
e073c474 3984 ea = SEXTSHORT (ea);
dc5c3759 3985 res = ea * SEXTSHORT (rd & 0xffff);
c906108c 3986
dc5c3759
MS
3987 n = res & 0x80000000;
3988 nz = res & 0xffffffff;
3989 if (store (sd, &code->dst, res))
3990 goto end;
3991
3992 goto next;
c906108c 3993
dc5c3759
MS
3994 case O (O_MULXU, SB): /* mulxu.b */
3995 if (fetch (sd, &code->src, &ea) ||
3996 fetch (sd, &code->dst, &rd))
c906108c 3997 goto end;
c906108c 3998
dc5c3759 3999 res = UEXTCHAR (ea) * UEXTCHAR (rd);
c906108c 4000
dc5c3759
MS
4001 if (store (sd, &code->dst, res))
4002 goto end;
c906108c 4003
dc5c3759 4004 goto next;
c906108c 4005
dc5c3759
MS
4006 case O (O_MULXU, SW): /* mulxu.w */
4007 if (fetch (sd, &code->src, &ea) ||
4008 fetch (sd, &code->dst, &rd))
c906108c 4009 goto end;
c906108c 4010
dc5c3759 4011 res = UEXTSHORT (ea) * UEXTSHORT (rd);
c906108c 4012
dc5c3759
MS
4013 if (store (sd, &code->dst, res))
4014 goto end;
4015
4016 goto next;
c906108c 4017
9f70f8ec
MS
4018 case O (O_TAS, SB): /* tas (test and set) */
4019 if (!h8300sxmode) /* h8sx can use any register. */
4020 switch (code->src.reg)
4021 {
4022 case R0_REGNUM:
4023 case R1_REGNUM:
4024 case R4_REGNUM:
4025 case R5_REGNUM:
4026 break;
4027 default:
4028 goto illegal;
4029 }
4030
dc5c3759
MS
4031 if (fetch (sd, &code->src, &res))
4032 goto end;
4033 if (store (sd, &code->src, res | 0x80))
4034 goto end;
4035
6147b1f6 4036 goto just_flags_log8;
c906108c 4037
dc5c3759
MS
4038 case O (O_DIVU, SW): /* divu.w */
4039 if (fetch (sd, &code->src, &ea) ||
4040 fetch (sd, &code->dst, &rd))
4041 goto end;
c906108c 4042
dc5c3759
MS
4043 n = ea & 0x8000;
4044 nz = ea & 0xffff;
4045 if (ea)
4046 res = (unsigned) (UEXTSHORT (rd) / UEXTSHORT (ea));
4047 else
4048 res = 0;
c906108c 4049
dc5c3759
MS
4050 if (store (sd, &code->dst, res))
4051 goto end;
4052 goto next;
c906108c 4053
dc5c3759
MS
4054 case O (O_DIVU, SL): /* divu.l */
4055 if (fetch (sd, &code->src, &ea) ||
4056 fetch (sd, &code->dst, &rd))
4057 goto end;
4058
4059 n = ea & 0x80000000;
4060 nz = ea & 0xffffffff;
4061 if (ea)
4062 res = (unsigned) rd / ea;
4063 else
4064 res = 0;
4065
4066 if (store (sd, &code->dst, res))
4067 goto end;
4068 goto next;
4069
4070 case O (O_DIVS, SW): /* divs.w */
4071 if (fetch (sd, &code->src, &ea) ||
4072 fetch (sd, &code->dst, &rd))
4073 goto end;
4074
dc5c3759
MS
4075 if (ea)
4076 {
4077 res = SEXTSHORT (rd) / SEXTSHORT (ea);
4078 nz = 1;
4079 }
4080 else
4081 {
4082 res = 0;
4083 nz = 0;
4084 }
4085
4086 n = res & 0x8000;
4087 if (store (sd, &code->dst, res))
4088 goto end;
4089 goto next;
4090
4091 case O (O_DIVS, SL): /* divs.l */
4092 if (fetch (sd, &code->src, &ea) ||
4093 fetch (sd, &code->dst, &rd))
4094 goto end;
4095
dc5c3759
MS
4096 if (ea)
4097 {
4098 res = rd / ea;
4099 nz = 1;
4100 }
4101 else
4102 {
4103 res = 0;
4104 nz = 0;
4105 }
4106
4107 n = res & 0x80000000;
4108 if (store (sd, &code->dst, res))
4109 goto end;
4110 goto next;
4111
4112 case O (O_DIVXU, SB): /* divxu.b */
4113 if (fetch (sd, &code->src, &ea) ||
4114 fetch (sd, &code->dst, &rd))
4115 goto end;
4116
4117 rd = UEXTSHORT (rd);
4118 ea = UEXTCHAR (ea);
4119
4120 n = ea & 0x80;
4121 nz = ea & 0xff;
4122 if (ea)
4123 {
4124 tmp = (unsigned) rd % ea;
4125 res = (unsigned) rd / ea;
4126 }
4127 else
4128 {
4129 tmp = 0;
4130 res = 0;
4131 }
4132
9f70f8ec 4133 if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
dc5c3759
MS
4134 goto end;
4135 goto next;
4136
4137 case O (O_DIVXU, SW): /* divxu.w */
4138 if (fetch (sd, &code->src, &ea) ||
4139 fetch (sd, &code->dst, &rd))
4140 goto end;
4141
4142 ea = UEXTSHORT (ea);
4143
4144 n = ea & 0x8000;
4145 nz = ea & 0xffff;
4146 if (ea)
4147 {
4148 tmp = (unsigned) rd % ea;
4149 res = (unsigned) rd / ea;
4150 }
4151 else
4152 {
4153 tmp = 0;
4154 res = 0;
4155 }
4156
4157 if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
4158 goto end;
4159 goto next;
4160
4161 case O (O_DIVXS, SB): /* divxs.b */
4162 if (fetch (sd, &code->src, &ea) ||
4163 fetch (sd, &code->dst, &rd))
4164 goto end;
4165
4166 rd = SEXTSHORT (rd);
e073c474 4167 ea = SEXTCHAR (ea);
dc5c3759
MS
4168
4169 if (ea)
4170 {
4171 tmp = (int) rd % (int) ea;
4172 res = (int) rd / (int) ea;
4173 nz = 1;
4174 }
4175 else
4176 {
4177 tmp = 0;
4178 res = 0;
4179 nz = 0;
4180 }
4181
4182 n = res & 0x8000;
4183 if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
4184 goto end;
4185 goto next;
4186
4187 case O (O_DIVXS, SW): /* divxs.w */
4188 if (fetch (sd, &code->src, &ea) ||
4189 fetch (sd, &code->dst, &rd))
4190 goto end;
4191
e073c474 4192 ea = SEXTSHORT (ea);
dc5c3759
MS
4193
4194 if (ea)
4195 {
4196 tmp = (int) rd % (int) ea;
4197 res = (int) rd / (int) ea;
4198 nz = 1;
4199 }
4200 else
4201 {
4202 tmp = 0;
4203 res = 0;
4204 nz = 0;
4205 }
4206
4207 n = res & 0x80000000;
4208 if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
4209 goto end;
4210 goto next;
4211
4212 case O (O_EXTS, SW): /* exts.w, signed extend */
4213 if (fetch2 (sd, &code->dst, &rd))
4214 goto end;
c906108c 4215 ea = rd & 0x80 ? -256 : 0;
dc5c3759 4216 res = (rd & 0xff) + ea;
c906108c 4217 goto log16;
dc5c3759
MS
4218
4219 case O (O_EXTS, SL): /* exts.l, signed extend */
4220 if (fetch2 (sd, &code->dst, &rd))
4221 goto end;
4222 if (code->src.type == X (OP_IMM, SL))
4223 {
4224 if (fetch (sd, &code->src, &ea))
4225 goto end;
4226
4227 if (ea == 2) /* exts.l #2, nn */
4228 {
4229 /* Sign-extend from 8-bit to 32-bit. */
4230 ea = rd & 0x80 ? -256 : 0;
4231 res = (rd & 0xff) + ea;
4232 goto log32;
4233 }
4234 }
4235 /* Sign-extend from 16-bit to 32-bit. */
c906108c 4236 ea = rd & 0x8000 ? -65536 : 0;
dc5c3759 4237 res = (rd & 0xffff) + ea;
c906108c 4238 goto log32;
dc5c3759
MS
4239
4240 case O (O_EXTU, SW): /* extu.w, unsigned extend */
4241 if (fetch2 (sd, &code->dst, &rd))
4242 goto end;
c906108c 4243 ea = 0;
dc5c3759 4244 res = (rd & 0xff) + ea;
c906108c 4245 goto log16;
dc5c3759
MS
4246
4247 case O (O_EXTU, SL): /* extu.l, unsigned extend */
4248 if (fetch2 (sd, &code->dst, &rd))
4249 goto end;
4250 if (code->src.type == X (OP_IMM, SL))
4251 {
4252 if (fetch (sd, &code->src, &ea))
4253 goto end;
4254
4255 if (ea == 2) /* extu.l #2, nn */
4256 {
4257 /* Zero-extend from 8-bit to 32-bit. */
4258 ea = 0;
4259 res = (rd & 0xff) + ea;
4260 goto log32;
4261 }
4262 }
4263 /* Zero-extend from 16-bit to 32-bit. */
c906108c 4264 ea = 0;
dc5c3759 4265 res = (rd & 0xffff) + ea;
c906108c
SS
4266 goto log32;
4267
dc5c3759 4268 case O (O_NOP, SN): /* nop */
c906108c
SS
4269 goto next;
4270
dc5c3759 4271 case O (O_STM, SL): /* stm, store to memory */
c906108c
SS
4272 {
4273 int nregs, firstreg, i;
4274
4275 nregs = GET_MEMORY_B (pc + 1);
4276 nregs >>= 4;
4277 nregs &= 0xf;
dc5c3759 4278 firstreg = code->src.reg;
c906108c
SS
4279 firstreg &= 0xf;
4280 for (i = firstreg; i <= firstreg + nregs; i++)
4281 {
dc5c3759
MS
4282 h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) - 4);
4283 SET_MEMORY_L (h8_get_reg (sd, SP_REGNUM), h8_get_reg (sd, i));
c906108c
SS
4284 }
4285 }
4286 goto next;
4287
dc5c3759 4288 case O (O_LDM, SL): /* ldm, load from memory */
9f70f8ec
MS
4289 case O (O_RTEL, SN): /* rte/l, ldm plus rte */
4290 case O (O_RTSL, SN): /* rts/l, ldm plus rts */
c906108c
SS
4291 {
4292 int nregs, firstreg, i;
4293
9f70f8ec
MS
4294 nregs = ((GET_MEMORY_B (pc + 1) >> 4) & 0xf);
4295 firstreg = code->dst.reg & 0xf;
c906108c
SS
4296 for (i = firstreg; i >= firstreg - nregs; i--)
4297 {
dc5c3759
MS
4298 h8_set_reg (sd, i, GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM)));
4299 h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) + 4);
c906108c
SS
4300 }
4301 }
9f70f8ec
MS
4302 switch (code->opcode) {
4303 case O (O_RTEL, SN):
4304 goto rte;
4305 case O (O_RTSL, SN):
4306 goto rts;
4307 case O (O_LDM, SL):
4308 goto next;
4309 default:
4310 goto illegal;
4311 }
c906108c 4312
b7f97e9c
MS
4313 case O (O_DAA, SB):
4314 /* Decimal Adjust Addition. This is for BCD arithmetic. */
9f70f8ec 4315 res = GET_B_REG (code->src.reg); /* FIXME fetch? */
dc5c3759
MS
4316 if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4317 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
b7f97e9c 4318 res = res; /* Value added == 0. */
dc5c3759
MS
4319 else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8) &&
4320 !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
b7f97e9c 4321 res = res + 0x6; /* Value added == 6. */
dc5c3759
MS
4322 else if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4323 h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
b7f97e9c 4324 res = res + 0x6; /* Value added == 6. */
dc5c3759
MS
4325 else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15) &&
4326 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
4327 res = res + 0x60; /* Value added == 60. */
4328 else if (!c && (9 <= (res >> 4) && (res >> 4) <= 15) &&
4329 !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
4330 res = res + 0x66; /* Value added == 66. */
4331 else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15) &&
4332 h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
4333 res = res + 0x66; /* Value added == 66. */
4334 else if ( c && (1 <= (res >> 4) && (res >> 4) <= 2) &&
4335 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
b7f97e9c 4336 res = res + 0x60; /* Value added == 60. */
dc5c3759
MS
4337 else if ( c && (1 <= (res >> 4) && (res >> 4) <= 2) &&
4338 !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
b7f97e9c 4339 res = res + 0x66; /* Value added == 66. */
dc5c3759
MS
4340 else if (c && (1 <= (res >> 4) && (res >> 4) <= 3) &&
4341 h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
b7f97e9c 4342 res = res + 0x66; /* Value added == 66. */
b7f97e9c
MS
4343
4344 goto alu8;
4345
4346 case O (O_DAS, SB):
4347 /* Decimal Adjust Subtraction. This is for BCD arithmetic. */
4348 res = GET_B_REG (code->src.reg); /* FIXME fetch, fetch2... */
dc5c3759
MS
4349 if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4350 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
b7f97e9c 4351 res = res; /* Value added == 0. */
dc5c3759
MS
4352 else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8) &&
4353 h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
b7f97e9c 4354 res = res + 0xfa; /* Value added == 0xfa. */
dc5c3759
MS
4355 else if ( c && (7 <= (res >> 4) && (res >> 4) <= 15) &&
4356 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
b7f97e9c 4357 res = res + 0xa0; /* Value added == 0xa0. */
dc5c3759
MS
4358 else if (c && (6 <= (res >> 4) && (res >> 4) <= 15) &&
4359 h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
b7f97e9c
MS
4360 res = res + 0x9a; /* Value added == 0x9a. */
4361
4362 goto alu8;
4363
c906108c 4364 default:
d0fe2f7e 4365 illegal:
dc5c3759 4366 sim_engine_set_run_state (sd, sim_stopped, SIGILL);
c906108c
SS
4367 goto end;
4368
4369 }
dc5c3759
MS
4370
4371 (*sim_callback->printf_filtered) (sim_callback,
4372 "sim_resume: internal error.\n");
4373 sim_engine_set_run_state (sd, sim_stopped, SIGILL);
4374 goto end;
c906108c
SS
4375
4376 setc:
dc5c3759
MS
4377 if (code->dst.type == X (OP_CCR, SB) ||
4378 code->dst.type == X (OP_CCR, SW))
c3f4437e 4379 {
dc5c3759 4380 h8_set_ccr (sd, res);
9f70f8ec 4381 GETSR (sd);
c3f4437e 4382 }
dc5c3759
MS
4383 else if (h8300smode &&
4384 (code->dst.type == X (OP_EXR, SB) ||
4385 code->dst.type == X (OP_EXR, SW)))
c3f4437e 4386 {
dc5c3759
MS
4387 h8_set_exr (sd, res);
4388 if (h8300smode) /* Get exr. */
4389 {
4390 trace = (h8_get_exr (sd) >> 7) & 1;
4391 intMask = h8_get_exr (sd) & 7;
4392 }
c3f4437e 4393 }
fc974602 4394 else
c3f4437e 4395 goto illegal;
fc974602 4396
c906108c
SS
4397 goto next;
4398
4399 condtrue:
4400 /* When a branch works */
dc5c3759
MS
4401 if (fetch (sd, &code->src, &res))
4402 goto end;
4403 if (res & 1) /* bad address */
4404 goto illegal;
4405 pc = code->next_pc + res;
c906108c
SS
4406 goto end;
4407
4408 /* Set the cond codes from res */
4409 bitop:
4410
4411 /* Set the flags after an 8 bit inc/dec operation */
4412 just_flags_inc8:
4413 n = res & 0x80;
4414 nz = res & 0xff;
4415 v = (rd & 0x7f) == 0x7f;
4416 goto next;
4417
c906108c
SS
4418 /* Set the flags after an 16 bit inc/dec operation */
4419 just_flags_inc16:
4420 n = res & 0x8000;
4421 nz = res & 0xffff;
4422 v = (rd & 0x7fff) == 0x7fff;
4423 goto next;
4424
c906108c
SS
4425 /* Set the flags after an 32 bit inc/dec operation */
4426 just_flags_inc32:
4427 n = res & 0x80000000;
4428 nz = res & 0xffffffff;
4429 v = (rd & 0x7fffffff) == 0x7fffffff;
4430 goto next;
4431
c906108c
SS
4432 shift8:
4433 /* Set flags after an 8 bit shift op, carry,overflow set in insn */
4434 n = (rd & 0x80);
4435 nz = rd & 0xff;
dc5c3759
MS
4436 if (store2 (sd, &code->dst, rd))
4437 goto end;
c906108c
SS
4438 goto next;
4439
4440 shift16:
4441 /* Set flags after an 16 bit shift op, carry,overflow set in insn */
4442 n = (rd & 0x8000);
4443 nz = rd & 0xffff;
dc5c3759
MS
4444 if (store2 (sd, &code->dst, rd))
4445 goto end;
c906108c
SS
4446 goto next;
4447
4448 shift32:
4449 /* Set flags after an 32 bit shift op, carry,overflow set in insn */
4450 n = (rd & 0x80000000);
4451 nz = rd & 0xffffffff;
dc5c3759
MS
4452 if (store2 (sd, &code->dst, rd))
4453 goto end;
c906108c
SS
4454 goto next;
4455
4456 log32:
dc5c3759
MS
4457 if (store2 (sd, &code->dst, res))
4458 goto end;
4459
c906108c
SS
4460 just_flags_log32:
4461 /* flags after a 32bit logical operation */
4462 n = res & 0x80000000;
4463 nz = res & 0xffffffff;
4464 v = 0;
4465 goto next;
4466
4467 log16:
dc5c3759
MS
4468 if (store2 (sd, &code->dst, res))
4469 goto end;
4470
c906108c
SS
4471 just_flags_log16:
4472 /* flags after a 16bit logical operation */
4473 n = res & 0x8000;
4474 nz = res & 0xffff;
4475 v = 0;
4476 goto next;
4477
c906108c 4478 log8:
dc5c3759
MS
4479 if (store2 (sd, &code->dst, res))
4480 goto end;
4481
c906108c
SS
4482 just_flags_log8:
4483 n = res & 0x80;
4484 nz = res & 0xff;
4485 v = 0;
4486 goto next;
4487
4488 alu8:
dc5c3759
MS
4489 if (store2 (sd, &code->dst, res))
4490 goto end;
4491
c906108c
SS
4492 just_flags_alu8:
4493 n = res & 0x80;
4494 nz = res & 0xff;
4495 c = (res & 0x100);
4496 switch (code->opcode / 4)
4497 {
4498 case O_ADD:
dc5c3759 4499 case O_ADDX:
c906108c
SS
4500 v = ((rd & 0x80) == (ea & 0x80)
4501 && (rd & 0x80) != (res & 0x80));
4502 break;
4503 case O_SUB:
dc5c3759 4504 case O_SUBX:
c906108c
SS
4505 case O_CMP:
4506 v = ((rd & 0x80) != (-ea & 0x80)
4507 && (rd & 0x80) != (res & 0x80));
4508 break;
4509 case O_NEG:
4510 v = (rd == 0x80);
4511 break;
dc5c3759
MS
4512 case O_DAA:
4513 case O_DAS:
4514 break; /* No effect on v flag. */
c906108c
SS
4515 }
4516 goto next;
4517
4518 alu16:
dc5c3759
MS
4519 if (store2 (sd, &code->dst, res))
4520 goto end;
4521
c906108c
SS
4522 just_flags_alu16:
4523 n = res & 0x8000;
4524 nz = res & 0xffff;
4525 c = (res & 0x10000);
4526 switch (code->opcode / 4)
4527 {
4528 case O_ADD:
dc5c3759 4529 case O_ADDX:
c906108c
SS
4530 v = ((rd & 0x8000) == (ea & 0x8000)
4531 && (rd & 0x8000) != (res & 0x8000));
4532 break;
4533 case O_SUB:
dc5c3759 4534 case O_SUBX:
c906108c
SS
4535 case O_CMP:
4536 v = ((rd & 0x8000) != (-ea & 0x8000)
4537 && (rd & 0x8000) != (res & 0x8000));
4538 break;
4539 case O_NEG:
4540 v = (rd == 0x8000);
4541 break;
4542 }
4543 goto next;
4544
4545 alu32:
dc5c3759
MS
4546 if (store2 (sd, &code->dst, res))
4547 goto end;
4548
c906108c
SS
4549 just_flags_alu32:
4550 n = res & 0x80000000;
4551 nz = res & 0xffffffff;
4552 switch (code->opcode / 4)
4553 {
4554 case O_ADD:
dc5c3759 4555 case O_ADDX:
c906108c
SS
4556 v = ((rd & 0x80000000) == (ea & 0x80000000)
4557 && (rd & 0x80000000) != (res & 0x80000000));
dc5c3759
MS
4558 c = ((unsigned) res < (unsigned) rd) ||
4559 ((unsigned) res < (unsigned) ea);
c906108c
SS
4560 break;
4561 case O_SUB:
dc5c3759 4562 case O_SUBX:
c906108c
SS
4563 case O_CMP:
4564 v = ((rd & 0x80000000) != (-ea & 0x80000000)
4565 && (rd & 0x80000000) != (res & 0x80000000));
4566 c = (unsigned) rd < (unsigned) -ea;
4567 break;
4568 case O_NEG:
4569 v = (rd == 0x80000000);
4570 c = res != 0;
4571 break;
4572 }
4573 goto next;
4574
dc5c3759
MS
4575 next:
4576 if ((res = h8_get_delayed_branch (sd)) != 0)
4577 {
4578 pc = res;
4579 h8_set_delayed_branch (sd, 0);
4580 }
4581 else
4582 pc = code->next_pc;
c906108c
SS
4583
4584 end:
dc5c3759 4585
c906108c
SS
4586 if (--poll_count < 0)
4587 {
7a292a7a 4588 poll_count = POLL_QUIT_INTERVAL;
c906108c
SS
4589 if ((*sim_callback->poll_quit) != NULL
4590 && (*sim_callback->poll_quit) (sim_callback))
dc5c3759 4591 sim_engine_set_run_state (sd, sim_stopped, SIGINT);
c906108c 4592 }
dc5c3759
MS
4593 sim_engine_get_run_state (sd, &reason, &sigrc);
4594 } while (reason == sim_running);
c906108c 4595
dc5c3759
MS
4596 h8_set_ticks (sd, h8_get_ticks (sd) + get_now () - tick_start);
4597 h8_set_cycles (sd, h8_get_cycles (sd) + cycles);
4598 h8_set_insts (sd, h8_get_insts (sd) + insts);
4599 h8_set_pc (sd, pc);
4600 BUILDSR (sd);
4601
4602 if (h8300smode)
4603 h8_set_exr (sd, (trace<<7) | intMask);
4604
4605 h8_set_mask (sd, oldmask);
c906108c
SS
4606 signal (SIGINT, prev);
4607}
4608
4609int
a4f27e3e 4610sim_trace (SIM_DESC sd)
c906108c 4611{
2ea716f6 4612 /* FIXME: Unfinished. */
dc5c3759
MS
4613 (*sim_callback->printf_filtered) (sim_callback,
4614 "sim_trace: trace not supported.\n");
4615 return 1; /* Done. */
c906108c
SS
4616}
4617
4618int
5558e7e6 4619sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
c906108c
SS
4620{
4621 int i;
4622
dc5c3759 4623 init_pointers (sd);
c906108c
SS
4624 if (addr < 0)
4625 return 0;
4626 for (i = 0; i < size; i++)
4627 {
4628 if (addr < memory_size)
4629 {
dc5c3759
MS
4630 h8_set_memory (sd, addr + i, buffer[i]);
4631 h8_set_cache_idx (sd, addr + i, 0);
c906108c
SS
4632 }
4633 else
dc5c3759
MS
4634 {
4635 h8_set_eightbit (sd, (addr + i) & 0xff, buffer[i]);
4636 }
c906108c
SS
4637 }
4638 return size;
4639}
4640
4641int
a4f27e3e 4642sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
c906108c 4643{
dc5c3759 4644 init_pointers (sd);
c906108c
SS
4645 if (addr < 0)
4646 return 0;
4647 if (addr < memory_size)
dc5c3759 4648 memcpy (buffer, h8_get_memory_buf (sd) + addr, size);
c906108c 4649 else
dc5c3759 4650 memcpy (buffer, h8_get_eightbit_buf (sd) + (addr & 0xff), size);
c906108c
SS
4651 return size;
4652}
4653
4654
c906108c 4655int
a4f27e3e 4656sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length)
c906108c
SS
4657{
4658 int longval;
4659 int shortval;
4660 int intval;
4661 longval = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
4662 shortval = (value[0] << 8) | (value[1]);
4663 intval = h8300hmode ? longval : shortval;
4664
dc5c3759 4665 init_pointers (sd);
c906108c
SS
4666 switch (rn)
4667 {
9f70f8ec 4668 case PC_REGNUM:
59768597
SA
4669 if(h8300_normal_mode)
4670 h8_set_pc (sd, shortval); /* PC for Normal mode is 2 bytes */
4671 else
4672 h8_set_pc (sd, intval);
9f70f8ec 4673 break;
c906108c 4674 default:
dc5c3759
MS
4675 (*sim_callback->printf_filtered) (sim_callback,
4676 "sim_store_register: bad regnum %d.\n",
4677 rn);
c906108c
SS
4678 case R0_REGNUM:
4679 case R1_REGNUM:
4680 case R2_REGNUM:
4681 case R3_REGNUM:
4682 case R4_REGNUM:
4683 case R5_REGNUM:
4684 case R6_REGNUM:
4685 case R7_REGNUM:
dc5c3759 4686 h8_set_reg (sd, rn, intval);
c906108c
SS
4687 break;
4688 case CCR_REGNUM:
dc5c3759 4689 h8_set_ccr (sd, intval);
c906108c 4690 break;
fc974602 4691 case EXR_REGNUM:
dc5c3759 4692 h8_set_exr (sd, intval);
fc974602 4693 break;
173b1c98
MS
4694 case SBR_REGNUM:
4695 h8_set_sbr (sd, intval);
4696 break;
4697 case VBR_REGNUM:
4698 h8_set_vbr (sd, intval);
4699 break;
4700 case MACH_REGNUM:
4701 h8_set_mach (sd, intval);
4702 break;
4703 case MACL_REGNUM:
4704 h8_set_macl (sd, intval);
4705 break;
c906108c 4706 case CYCLE_REGNUM:
dc5c3759 4707 h8_set_cycles (sd, longval);
c906108c 4708 break;
9f70f8ec 4709
c906108c 4710 case INST_REGNUM:
dc5c3759 4711 h8_set_insts (sd, longval);
c906108c 4712 break;
9f70f8ec 4713
c906108c 4714 case TICK_REGNUM:
dc5c3759 4715 h8_set_ticks (sd, longval);
c906108c
SS
4716 break;
4717 }
4718 return -1;
4719}
4720
4721int
a4f27e3e 4722sim_fetch_register (SIM_DESC sd, int rn, unsigned char *buf, int length)
c906108c
SS
4723{
4724 int v;
4725 int longreg = 0;
4726
dc5c3759 4727 init_pointers (sd);
c906108c 4728
d0fe2f7e 4729 if (!h8300smode && rn >= EXR_REGNUM)
c3f4437e 4730 rn++;
c906108c
SS
4731 switch (rn)
4732 {
4733 default:
dc5c3759
MS
4734 (*sim_callback->printf_filtered) (sim_callback,
4735 "sim_fetch_register: bad regnum %d.\n",
4736 rn);
4737 v = 0;
4738 break;
3b02cf92 4739 case CCR_REGNUM:
dc5c3759 4740 v = h8_get_ccr (sd);
c906108c 4741 break;
fc974602 4742 case EXR_REGNUM:
dc5c3759 4743 v = h8_get_exr (sd);
fc974602 4744 break;
3b02cf92 4745 case PC_REGNUM:
dc5c3759 4746 v = h8_get_pc (sd);
c906108c 4747 break;
173b1c98
MS
4748 case SBR_REGNUM:
4749 v = h8_get_sbr (sd);
4750 break;
4751 case VBR_REGNUM:
4752 v = h8_get_vbr (sd);
4753 break;
4754 case MACH_REGNUM:
4755 v = h8_get_mach (sd);
4756 break;
4757 case MACL_REGNUM:
4758 v = h8_get_macl (sd);
4759 break;
c906108c
SS
4760 case R0_REGNUM:
4761 case R1_REGNUM:
4762 case R2_REGNUM:
4763 case R3_REGNUM:
4764 case R4_REGNUM:
4765 case R5_REGNUM:
4766 case R6_REGNUM:
4767 case R7_REGNUM:
dc5c3759 4768 v = h8_get_reg (sd, rn);
c906108c 4769 break;
3b02cf92 4770 case CYCLE_REGNUM:
dc5c3759 4771 v = h8_get_cycles (sd);
c906108c
SS
4772 longreg = 1;
4773 break;
3b02cf92 4774 case TICK_REGNUM:
dc5c3759 4775 v = h8_get_ticks (sd);
c906108c
SS
4776 longreg = 1;
4777 break;
3b02cf92 4778 case INST_REGNUM:
dc5c3759 4779 v = h8_get_insts (sd);
c906108c
SS
4780 longreg = 1;
4781 break;
4782 }
59768597
SA
4783 /* In Normal mode PC is 2 byte, but other registers are 4 byte */
4784 if ((h8300hmode || longreg) && !(rn == PC_REGNUM && h8300_normal_mode))
c906108c
SS
4785 {
4786 buf[0] = v >> 24;
4787 buf[1] = v >> 16;
4788 buf[2] = v >> 8;
4789 buf[3] = v >> 0;
4790 }
4791 else
4792 {
4793 buf[0] = v >> 8;
4794 buf[1] = v;
4795 }
4796 return -1;
4797}
4798
4799void
a4f27e3e 4800sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
c906108c 4801{
dc5c3759 4802 sim_engine_get_run_state (sd, reason, sigrc);
c906108c
SS
4803}
4804
4805/* FIXME: Rename to sim_set_mem_size. */
4806
4807void
a4f27e3e 4808sim_size (int n)
c906108c
SS
4809{
4810 /* Memory size is fixed. */
4811}
4812
dc5c3759
MS
4813static void
4814set_simcache_size (SIM_DESC sd, int n)
c906108c 4815{
dc5c3759
MS
4816 if (sd->sim_cache)
4817 free (sd->sim_cache);
c906108c
SS
4818 if (n < 2)
4819 n = 2;
dc5c3759
MS
4820 sd->sim_cache = (decoded_inst *) malloc (sizeof (decoded_inst) * n);
4821 memset (sd->sim_cache, 0, sizeof (decoded_inst) * n);
4822 sd->sim_cache_size = n;
c906108c
SS
4823}
4824
4825
4826void
a4f27e3e 4827sim_info (SIM_DESC sd, int verbose)
c906108c 4828{
dc5c3759
MS
4829 double timetaken = (double) h8_get_ticks (sd) / (double) now_persec ();
4830 double virttime = h8_get_cycles (sd) / 10.0e6;
c906108c
SS
4831
4832 (*sim_callback->printf_filtered) (sim_callback,
4833 "\n\n#instructions executed %10d\n",
dc5c3759 4834 h8_get_insts (sd));
c906108c
SS
4835 (*sim_callback->printf_filtered) (sim_callback,
4836 "#cycles (v approximate) %10d\n",
dc5c3759 4837 h8_get_cycles (sd));
c906108c
SS
4838 (*sim_callback->printf_filtered) (sim_callback,
4839 "#real time taken %10.4f\n",
4840 timetaken);
4841 (*sim_callback->printf_filtered) (sim_callback,
e8c1a4e7 4842 "#virtual time taken %10.4f\n",
c906108c
SS
4843 virttime);
4844 if (timetaken != 0.0)
4845 (*sim_callback->printf_filtered) (sim_callback,
4846 "#simulation ratio %10.4f\n",
4847 virttime / timetaken);
4848 (*sim_callback->printf_filtered) (sim_callback,
4849 "#compiles %10d\n",
dc5c3759 4850 h8_get_compiles (sd));
c906108c
SS
4851 (*sim_callback->printf_filtered) (sim_callback,
4852 "#cache size %10d\n",
dc5c3759 4853 sd->sim_cache_size);
c906108c
SS
4854
4855#ifdef ADEBUG
4856 /* This to be conditional on `what' (aka `verbose'),
4857 however it was never passed as non-zero. */
4858 if (1)
4859 {
4860 int i;
4861 for (i = 0; i < O_LAST; i++)
4862 {
dc5c3759
MS
4863 if (h8_get_stats (sd, i))
4864 (*sim_callback->printf_filtered) (sim_callback, "%d: %d\n",
4865 i, h8_get_stats (sd, i));
c906108c
SS
4866 }
4867 }
4868#endif
4869}
4870
2ea716f6
KH
4871/* Indicate whether the cpu is an H8/300 or H8/300H.
4872 FLAG is non-zero for the H8/300H. */
c906108c
SS
4873
4874void
27ebfdf4 4875set_h8300h (unsigned long machine)
c906108c
SS
4876{
4877 /* FIXME: Much of the code in sim_load can be moved to sim_open.
4878 This function being replaced by a sim_open:ARGV configuration
2ea716f6 4879 option. */
dc5c3759 4880
454d0511
DD
4881 h8300hmode = h8300smode = h8300sxmode = h8300_normal_mode = 0;
4882
9f70f8ec 4883 if (machine == bfd_mach_h8300sx || machine == bfd_mach_h8300sxn)
27ebfdf4
MS
4884 h8300sxmode = 1;
4885
4886 if (machine == bfd_mach_h8300s || machine == bfd_mach_h8300sn || h8300sxmode)
4887 h8300smode = 1;
4888
4889 if (machine == bfd_mach_h8300h || machine == bfd_mach_h8300hn || h8300smode)
4890 h8300hmode = 1;
59768597
SA
4891
4892 if(machine == bfd_mach_h8300hn || machine == bfd_mach_h8300sn || machine == bfd_mach_h8300sxn)
4893 h8300_normal_mode = 1;
dc5c3759
MS
4894}
4895
4896/* Cover function of sim_state_free to free the cpu buffers as well. */
4897
4898static void
4899free_state (SIM_DESC sd)
4900{
4901 if (STATE_MODULES (sd) != NULL)
4902 sim_module_uninstall (sd);
4903
4904 /* Fixme: free buffers in _sim_cpu. */
4905 sim_state_free (sd);
c906108c
SS
4906}
4907
4908SIM_DESC
a4f27e3e 4909sim_open (SIM_OPEN_KIND kind,
dc5c3759 4910 struct host_callback_struct *callback,
6b4a8935 4911 struct bfd *abfd,
a4f27e3e 4912 char **argv)
c906108c 4913{
dc5c3759
MS
4914 SIM_DESC sd;
4915 sim_cpu *cpu;
4916
4917 sd = sim_state_alloc (kind, callback);
4918 sd->cpu = sim_cpu_alloc (sd, 0);
4919 cpu = STATE_CPU (sd, 0);
4920 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
4921 sim_state_initialize (sd, cpu);
4922 /* sim_cpu object is new, so some initialization is needed. */
4923 init_pointers_needed = 1;
4924
4925 /* For compatibility (FIXME: is this right?). */
4926 current_alignment = NONSTRICT_ALIGNMENT;
4927 current_target_byte_order = BIG_ENDIAN;
4928
4929 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
4930 {
4931 free_state (sd);
4932 return 0;
4933 }
4934
4935 /* getopt will print the error message so we just have to exit if
4936 this fails. FIXME: Hmmm... in the case of gdb we need getopt
4937 to call print_filtered. */
4938 if (sim_parse_args (sd, argv) != SIM_RC_OK)
4939 {
4940 /* Uninstall the modules to avoid memory leaks,
4941 file descriptor leaks, etc. */
4942 free_state (sd);
4943 return 0;
4944 }
4945
4946 /* Check for/establish the a reference program image. */
4947 if (sim_analyze_program (sd,
4948 (STATE_PROG_ARGV (sd) != NULL
4949 ? *STATE_PROG_ARGV (sd)
4950 : NULL), abfd) != SIM_RC_OK)
4951 {
4952 free_state (sd);
4953 return 0;
4954 }
4955
4956 /* Establish any remaining configuration options. */
4957 if (sim_config (sd) != SIM_RC_OK)
4958 {
4959 free_state (sd);
4960 return 0;
4961 }
4962
4963 if (sim_post_argv_init (sd) != SIM_RC_OK)
4964 {
4965 /* Uninstall the modules to avoid memory leaks,
4966 file descriptor leaks, etc. */
4967 free_state (sd);
4968 return 0;
4969 }
4970
4971 /* sim_hw_configure (sd); */
4972
2ea716f6 4973 /* FIXME: Much of the code in sim_load can be moved here. */
c906108c
SS
4974
4975 sim_kind = kind;
4976 myname = argv[0];
dc5c3759
MS
4977 sim_callback = callback;
4978 return sd;
c906108c
SS
4979}
4980
4981void
a4f27e3e 4982sim_close (SIM_DESC sd, int quitting)
c906108c 4983{
2ea716f6 4984 /* Nothing to do. */
c906108c
SS
4985}
4986
4987/* Called by gdb to load a program into memory. */
4988
4989SIM_RC
a4f27e3e 4990sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty)
c906108c
SS
4991{
4992 bfd *prog_bfd;
4993
2ea716f6
KH
4994 /* FIXME: The code below that sets a specific variant of the H8/300
4995 being simulated should be moved to sim_open(). */
c906108c 4996
2ea716f6 4997 /* See if the file is for the H8/300 or H8/300H. */
c906108c
SS
4998 /* ??? This may not be the most efficient way. The z8k simulator
4999 does this via a different mechanism (INIT_EXTRA_SYMTAB_INFO). */
5000 if (abfd != NULL)
5001 prog_bfd = abfd;
5002 else
3d29fdb4 5003 prog_bfd = bfd_openr (prog, NULL);
c906108c
SS
5004 if (prog_bfd != NULL)
5005 {
5006 /* Set the cpu type. We ignore failure from bfd_check_format
5007 and bfd_openr as sim_load_file checks too. */
de9b1892 5008 if (bfd_check_format (prog_bfd, bfd_object))
c906108c 5009 {
27ebfdf4 5010 set_h8300h (bfd_get_mach (prog_bfd));
c906108c
SS
5011 }
5012 }
5013
5014 /* If we're using gdb attached to the simulator, then we have to
5015 reallocate memory for the simulator.
5016
5017 When gdb first starts, it calls fetch_registers (among other
5018 functions), which in turn calls init_pointers, which allocates
5019 simulator memory.
5020
5021 The problem is when we do that, we don't know whether we're
2ea716f6 5022 debugging an H8/300 or H8/300H program.
c906108c
SS
5023
5024 This is the first point at which we can make that determination,
5025 so we just reallocate memory now; this will also allow us to handle
2ea716f6 5026 switching between H8/300 and H8/300H programs without exiting
c906108c 5027 gdb. */
a8cdafbd 5028
59768597 5029 if (h8300smode && !h8300_normal_mode)
a8cdafbd 5030 memory_size = H8300S_MSIZE;
59768597 5031 else if (h8300hmode && !h8300_normal_mode)
c906108c
SS
5032 memory_size = H8300H_MSIZE;
5033 else
5034 memory_size = H8300_MSIZE;
5035
dc5c3759
MS
5036 if (h8_get_memory_buf (sd))
5037 free (h8_get_memory_buf (sd));
5038 if (h8_get_cache_idx_buf (sd))
5039 free (h8_get_cache_idx_buf (sd));
5040 if (h8_get_eightbit_buf (sd))
5041 free (h8_get_eightbit_buf (sd));
c906108c 5042
dc5c3759
MS
5043 h8_set_memory_buf (sd, (unsigned char *)
5044 calloc (sizeof (char), memory_size));
5045 h8_set_cache_idx_buf (sd, (unsigned short *)
5046 calloc (sizeof (short), memory_size));
e4d3c499 5047 sd->memory_size = memory_size;
dc5c3759 5048 h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256));
c906108c 5049
2ea716f6 5050 /* `msize' must be a power of two. */
c906108c 5051 if ((memory_size & (memory_size - 1)) != 0)
dc5c3759
MS
5052 {
5053 (*sim_callback->printf_filtered) (sim_callback,
5054 "sim_load: bad memory size.\n");
5055 return SIM_RC_FAIL;
5056 }
5057 h8_set_mask (sd, memory_size - 1);
c906108c
SS
5058
5059 if (sim_load_file (sd, myname, sim_callback, prog, prog_bfd,
5060 sim_kind == SIM_OPEN_DEBUG,
5061 0, sim_write)
5062 == NULL)
5063 {
5064 /* Close the bfd if we opened it. */
5065 if (abfd == NULL && prog_bfd != NULL)
5066 bfd_close (prog_bfd);
5067 return SIM_RC_FAIL;
5068 }
5069
5070 /* Close the bfd if we opened it. */
5071 if (abfd == NULL && prog_bfd != NULL)
5072 bfd_close (prog_bfd);
5073 return SIM_RC_OK;
5074}
5075
5076SIM_RC
6b4a8935 5077sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
c906108c 5078{
d1360fb0
V
5079 int i = 0;
5080 int len_arg = 0;
5081 int no_of_args = 0;
dc5c3759 5082
c906108c 5083 if (abfd != NULL)
dc5c3759 5084 h8_set_pc (sd, bfd_get_start_address (abfd));
c906108c 5085 else
dc5c3759 5086 h8_set_pc (sd, 0);
d1360fb0
V
5087
5088 /* Command Line support. */
5089 if (argv != NULL)
5090 {
5091 /* Counting the no. of commandline arguments. */
5092 for (no_of_args = 0; argv[no_of_args] != NULL; no_of_args++)
5093 continue;
5094
5095 /* Allocating memory for the argv pointers. */
dc5c3759
MS
5096 h8_set_command_line (sd, (char **) malloc ((sizeof (char *))
5097 * (no_of_args + 1)));
d1360fb0
V
5098
5099 for (i = 0; i < no_of_args; i++)
5100 {
d1360fb0 5101 /* Copying the argument string. */
dc5c3759 5102 h8_set_cmdline_arg (sd, i, (char *) strdup (argv[i]));
d1360fb0 5103 }
dc5c3759 5104 h8_set_cmdline_arg (sd, i, NULL);
d1360fb0
V
5105 }
5106
c906108c
SS
5107 return SIM_RC_OK;
5108}
5109
5110void
a4f27e3e 5111sim_do_command (SIM_DESC sd, char *cmd)
c906108c
SS
5112{
5113 (*sim_callback->printf_filtered) (sim_callback,
5114 "This simulator does not accept any commands.\n");
5115}
5116
5117void
a4f27e3e 5118sim_set_callbacks (struct host_callback_struct *ptr)
c906108c
SS
5119{
5120 sim_callback = ptr;
5121}