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