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