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