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