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