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