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