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