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