]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/h8300/compile.c
Remove unused variable un darwin_nat_target::resume
[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
MS
467static int
468cmdline_location()
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
MS
1626 "init_pointers: bad memory size %d, defaulting to %d.\n",
1627 memory_size, memory_size = H8300S_MSIZE);
1628 }
1629
1630 if (h8_get_memory_buf (sd))
1631 free (h8_get_memory_buf (sd));
dc5c3759
MS
1632
1633 h8_set_memory_buf (sd, (unsigned char *)
1634 calloc (sizeof (char), memory_size));
dc5c3759 1635 sd->memory_size = memory_size;
dc5c3759
MS
1636
1637 h8_set_mask (sd, memory_size - 1);
1638
1639 memset (h8_get_reg_buf (sd), 0, sizeof (((STATE_CPU (sd, 0))->regs)));
1640
1641 for (i = 0; i < 8; i++)
1642 {
1643 /* FIXME: rewrite using local buffer. */
1644 unsigned char *p = (unsigned char *) (h8_get_reg_buf (sd) + i);
1645 unsigned char *e = (unsigned char *) (h8_get_reg_buf (sd) + i + 1);
1646 unsigned short *q = (unsigned short *) (h8_get_reg_buf (sd) + i);
1647 unsigned short *u = (unsigned short *) (h8_get_reg_buf (sd) + i + 1);
1648 h8_set_reg (sd, i, 0x00112233);
1649
1650 while (p < e)
1651 {
1652 if (*p == 0x22)
1653 breg[i] = p;
1654 if (*p == 0x33)
1655 breg[i + 8] = p;
1656 if (*p == 0x11)
1657 breg[i + 16] = p;
1658 if (*p == 0x00)
1659 breg[i + 24] = p;
1660 p++;
1661 }
1662
1663 wreg[i] = wreg[i + 8] = 0;
1664 while (q < u)
1665 {
1666 if (*q == 0x2233)
1667 {
1668 wreg[i] = q;
1669 }
1670 if (*q == 0x0011)
1671 {
1672 wreg[i + 8] = q;
1673 }
1674 q++;
1675 }
1676
1677 if (wreg[i] == 0 || wreg[i + 8] == 0)
c1fc4b4d 1678 sim_io_printf (sd, "init_pointers: internal error.\n");
dc5c3759
MS
1679
1680 h8_set_reg (sd, i, 0);
dc5c3759
MS
1681 }
1682
dc5c3759 1683 init_pointers_needed = 0;
dc5c3759
MS
1684 }
1685}
1686
dc5c3759
MS
1687#define OBITOP(name, f, s, op) \
1688case O (name, SB): \
1689{ \
1690 int m, tmp; \
1691 \
1692 if (f) \
1693 if (fetch (sd, &code->dst, &ea)) \
1694 goto end; \
1695 if (fetch (sd, &code->src, &tmp)) \
1696 goto end; \
b86015ea 1697 m = 1 << (tmp & 7); \
dc5c3759
MS
1698 op; \
1699 if (s) \
1700 if (store (sd, &code->dst,ea)) \
1701 goto end; \
1702 goto next; \
1703}
1704
4ca9d09e
MF
1705static void
1706step_once (SIM_DESC sd, SIM_CPU *cpu)
dc5c3759 1707{
dc5c3759
MS
1708 int cycles = 0;
1709 int insts = 0;
1710 int tick_start = get_now ();
dc5c3759
MS
1711 int res;
1712 int tmp;
1713 int rd;
1714 int ea;
1715 int bit;
1716 int pc;
1717 int c, nz, v, n, u, h, ui, intMaskBit;
1718 int trace, intMask;
1719 int oldmask;
c1fc4b4d 1720 host_callback *sim_callback = STATE_CALLBACK (sd);
dc5c3759
MS
1721
1722 init_pointers (sd);
1723
dc5c3759
MS
1724 pc = h8_get_pc (sd);
1725
1726 /* The PC should never be odd. */
1727 if (pc & 0x1)
1728 {
4ca9d09e 1729 sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGBUS);
dc5c3759
MS
1730 return;
1731 }
1732
1733 /* Get Status Register (flags). */
9f70f8ec 1734 GETSR (sd);
dc5c3759
MS
1735
1736 if (h8300smode) /* Get exr. */
1737 {
1738 trace = (h8_get_exr (sd) >> 7) & 1;
1739 intMask = h8_get_exr (sd) & 7;
1740 }
1741
1742 oldmask = h8_get_mask (sd);
59768597 1743 if (!h8300hmode || h8300_normal_mode)
dc5c3759
MS
1744 h8_set_mask (sd, 0xffff);
1745 do
1746 {
bfc7d04a
MF
1747 decoded_inst _code, *code = &_code;
1748 memset (code, 0, sizeof (*code));
1749 decode (sd, pc, h8_get_memory_buf (sd) + pc, code);
1750 code->oldpc = pc;
dc5c3759
MS
1751
1752#if ADEBUG
1753 if (debug)
1754 {
1755 printf ("%x %d %s\n", pc, code->opcode,
1756 code->op ? code->op->name : "**");
1757 }
1758 h8_increment_stats (sd, code->opcode);
1759#endif
1760
1761 if (code->opcode)
1762 {
1763 cycles += code->cycles;
1764 insts++;
1765 }
1766
1767 switch (code->opcode)
1768 {
dc5c3759
MS
1769 case O (O_MOVAB, SL):
1770 case O (O_MOVAW, SL):
1771 case O (O_MOVAL, SL):
1772 /* 1) Evaluate 2nd argument (dst).
1773 2) Mask / zero extend according to whether 1st argument (src)
1774 is INDEXB, INDEXW, or INDEXL.
1775 3) Left-shift the result by 0, 1 or 2, according to size of mova
1776 (mova/b, mova/w, mova/l).
1777 4) Add literal value of 1st argument (src).
1778 5) Store result in 3rd argument (op3).
f408565c
MS
1779 */
1780
1781 /* Alas, since this is the only instruction with 3 arguments,
1782 decode doesn't handle them very well. Some fix-up is required.
1783
1784 a) The size of dst is determined by whether src is
1785 INDEXB or INDEXW. */
dc5c3759 1786
f408565c
MS
1787 if (OP_KIND (code->src.type) == OP_INDEXB)
1788 code->dst.type = X (OP_KIND (code->dst.type), SB);
1789 else if (OP_KIND (code->src.type) == OP_INDEXW)
1790 code->dst.type = X (OP_KIND (code->dst.type), SW);
1791
1792 /* b) If op3 == null, then this is the short form of the insn.
1793 Dst is the dispreg of src, and op3 is the 32-bit form
1794 of the same register.
dc5c3759 1795 */
f408565c
MS
1796
1797 if (code->op3.type == 0)
1798 {
1799 /* Short form: src == INDEXB/INDEXW, dst == op3 == 0.
1800 We get to compose dst and op3 as follows:
1801
1802 op3 is a 32-bit register, ID == src.reg.
1803 dst is the same register, but 8 or 16 bits
1804 depending on whether src is INDEXB or INDEXW.
1805 */
1806
1807 code->op3.type = X (OP_REG, SL);
1808 code->op3.reg = code->src.reg;
1809 code->op3.literal = 0;
1810
1811 if (OP_KIND (code->src.type) == OP_INDEXB)
e073c474
AO
1812 {
1813 code->dst.type = X (OP_REG, SB);
1814 code->dst.reg = code->op3.reg + 8;
1815 }
f408565c
MS
1816 else
1817 code->dst.type = X (OP_REG, SW);
1818 }
1819
dc5c3759
MS
1820 if (fetch (sd, &code->dst, &ea))
1821 goto end;
1822
1823 switch (OP_KIND (code->src.type)) {
1824 case OP_INDEXB: ea = ea & 0xff; break;
1825 case OP_INDEXW: ea = ea & 0xffff; break;
1826 case OP_INDEXL: break;
1827 default: goto illegal;
1828 }
1829
1830 switch (code->opcode) {
1831 case O (O_MOVAB, SL): break;
1832 case O (O_MOVAW, SL): ea = ea << 1; break;
1833 case O (O_MOVAL, SL): ea = ea << 2; break;
1834 default: goto illegal;
1835 }
1836
1837 ea = ea + code->src.literal;
1838
1839 if (store (sd, &code->op3, ea))
1840 goto end;
1841
1842 goto next;
1843
1844 case O (O_SUBX, SB): /* subx, extended sub */
1845 if (fetch2 (sd, &code->dst, &rd))
1846 goto end;
1847 if (fetch (sd, &code->src, &ea))
1848 goto end;
1849 ea = -(ea + C);
1850 res = rd + ea;
1851 goto alu8;
1852
1853 case O (O_SUBX, SW): /* subx, extended sub */
1854 if (fetch2 (sd, &code->dst, &rd))
1855 goto end;
1856 if (fetch (sd, &code->src, &ea))
1857 goto end;
1858 ea = -(ea + C);
1859 res = rd + ea;
1860 goto alu16;
1861
1862 case O (O_SUBX, SL): /* subx, extended sub */
1863 if (fetch2 (sd, &code->dst, &rd))
1864 goto end;
1865 if (fetch (sd, &code->src, &ea))
1866 goto end;
1867 ea = -(ea + C);
1868 res = rd + ea;
1869 goto alu32;
1870
1871 case O (O_ADDX, SB): /* addx, extended add */
1872 if (fetch2 (sd, &code->dst, &rd))
1873 goto end;
1874 if (fetch (sd, &code->src, &ea))
1875 goto end;
1876 ea = ea + C;
1877 res = rd + ea;
1878 goto alu8;
1879
1880 case O (O_ADDX, SW): /* addx, extended add */
1881 if (fetch2 (sd, &code->dst, &rd))
1882 goto end;
1883 if (fetch (sd, &code->src, &ea))
1884 goto end;
1885 ea = ea + C;
1886 res = rd + ea;
1887 goto alu16;
1888
1889 case O (O_ADDX, SL): /* addx, extended add */
1890 if (fetch2 (sd, &code->dst, &rd))
1891 goto end;
1892 if (fetch (sd, &code->src, &ea))
1893 goto end;
1894 ea = ea + C;
1895 res = rd + ea;
1896 goto alu32;
1897
1898 case O (O_SUB, SB): /* sub.b */
1899 /* Fetch rd and ea. */
1900 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
1901 goto end;
1902 ea = -ea;
1903 res = rd + ea;
1904 goto alu8;
1905
1906 case O (O_SUB, SW): /* sub.w */
1907 /* Fetch rd and ea. */
1908 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
1909 goto end;
1910 ea = -ea;
1911 res = rd + ea;
1912 goto alu16;
1913
1914 case O (O_SUB, SL): /* sub.l */
1915 /* Fetch rd and ea. */
1916 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
1917 goto end;
1918 ea = -ea;
1919 res = rd + ea;
1920 goto alu32;
1921
1922 case O (O_NEG, SB): /* neg.b */
1923 /* Fetch ea. */
1924 if (fetch2 (sd, &code->src, &ea))
1925 goto end;
1926 ea = -ea;
1927 rd = 0;
1928 res = rd + ea;
1929 goto alu8;
1930
1931 case O (O_NEG, SW): /* neg.w */
1932 /* Fetch ea. */
1933 if (fetch2 (sd, &code->src, &ea))
1934 goto end;
1935 ea = -ea;
1936 rd = 0;
1937 res = rd + ea;
1938 goto alu16;
1939
1940 case O (O_NEG, SL): /* neg.l */
1941 /* Fetch ea. */
1942 if (fetch2 (sd, &code->src, &ea))
1943 goto end;
1944 ea = -ea;
1945 rd = 0;
1946 res = rd + ea;
1947 goto alu32;
1948
1949 case O (O_ADD, SB): /* add.b */
1950 if (fetch2 (sd, &code->dst, &rd))
1951 goto end;
1952 if (fetch (sd, &code->src, &ea))
1953 goto end;
1954 res = rd + ea;
1955 goto alu8;
1956
1957 case O (O_ADD, SW): /* add.w */
1958 if (fetch2 (sd, &code->dst, &rd))
1959 goto end;
1960 if (fetch (sd, &code->src, &ea))
1961 goto end;
1962 res = rd + ea;
1963 goto alu16;
1964
1965 case O (O_ADD, SL): /* add.l */
1966 if (fetch2 (sd, &code->dst, &rd))
1967 goto end;
1968 if (fetch (sd, &code->src, &ea))
1969 goto end;
1970 res = rd + ea;
1971 goto alu32;
1972
1973 case O (O_AND, SB): /* and.b */
1974 /* Fetch rd and ea. */
1975 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
1976 goto end;
1977 res = rd & ea;
1978 goto log8;
1979
1980 case O (O_AND, SW): /* and.w */
1981 /* Fetch rd and ea. */
1982 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
1983 goto end;
1984 res = rd & ea;
1985 goto log16;
1986
1987 case O (O_AND, SL): /* and.l */
1988 /* Fetch rd and ea. */
1989 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
1990 goto end;
1991 res = rd & ea;
1992 goto log32;
1993
1994 case O (O_OR, SB): /* or.b */
1995 /* Fetch rd and ea. */
1996 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
1997 goto end;
1998 res = rd | ea;
1999 goto log8;
2000
2001 case O (O_OR, SW): /* or.w */
2002 /* Fetch rd and ea. */
2003 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2004 goto end;
2005 res = rd | ea;
2006 goto log16;
2007
2008 case O (O_OR, SL): /* or.l */
2009 /* Fetch rd and ea. */
2010 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2011 goto end;
2012 res = rd | ea;
2013 goto log32;
2014
2015 case O (O_XOR, SB): /* xor.b */
2016 /* Fetch rd and ea. */
2017 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2018 goto end;
2019 res = rd ^ ea;
2020 goto log8;
2021
2022 case O (O_XOR, SW): /* xor.w */
2023 /* Fetch rd and ea. */
2024 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2025 goto end;
2026 res = rd ^ ea;
2027 goto log16;
2028
2029 case O (O_XOR, SL): /* xor.l */
2030 /* Fetch rd and ea. */
2031 if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
2032 goto end;
2033 res = rd ^ ea;
2034 goto log32;
2035
2036 case O (O_MOV, SB):
2037 if (fetch (sd, &code->src, &res))
2038 goto end;
2039 if (store (sd, &code->dst, res))
2040 goto end;
2041 goto just_flags_log8;
2042 case O (O_MOV, SW):
2043 if (fetch (sd, &code->src, &res))
2044 goto end;
2045 if (store (sd, &code->dst, res))
2046 goto end;
2047 goto just_flags_log16;
2048 case O (O_MOV, SL):
2049 if (fetch (sd, &code->src, &res))
2050 goto end;
2051 if (store (sd, &code->dst, res))
2052 goto end;
2053 goto just_flags_log32;
2054
9f70f8ec 2055 case O (O_MOVMD, SB): /* movmd.b */
dc5c3759
MS
2056 ea = GET_W_REG (4);
2057 if (ea == 0)
2058 ea = 0x10000;
2059
2060 while (ea--)
2061 {
2062 rd = GET_MEMORY_B (GET_L_REG (5));
2063 SET_MEMORY_B (GET_L_REG (6), rd);
2064 SET_L_REG (5, GET_L_REG (5) + 1);
2065 SET_L_REG (6, GET_L_REG (6) + 1);
2066 SET_W_REG (4, ea);
2067 }
2068 goto next;
2069
9f70f8ec 2070 case O (O_MOVMD, SW): /* movmd.w */
dc5c3759
MS
2071 ea = GET_W_REG (4);
2072 if (ea == 0)
2073 ea = 0x10000;
2074
2075 while (ea--)
2076 {
2077 rd = GET_MEMORY_W (GET_L_REG (5));
2078 SET_MEMORY_W (GET_L_REG (6), rd);
2079 SET_L_REG (5, GET_L_REG (5) + 2);
2080 SET_L_REG (6, GET_L_REG (6) + 2);
2081 SET_W_REG (4, ea);
2082 }
2083 goto next;
2084
9f70f8ec 2085 case O (O_MOVMD, SL): /* movmd.l */
dc5c3759
MS
2086 ea = GET_W_REG (4);
2087 if (ea == 0)
2088 ea = 0x10000;
2089
2090 while (ea--)
2091 {
2092 rd = GET_MEMORY_L (GET_L_REG (5));
2093 SET_MEMORY_L (GET_L_REG (6), rd);
2094 SET_L_REG (5, GET_L_REG (5) + 4);
2095 SET_L_REG (6, GET_L_REG (6) + 4);
2096 SET_W_REG (4, ea);
2097 }
2098 goto next;
2099
2100 case O (O_MOVSD, SB): /* movsd.b */
2101 /* This instruction implements strncpy, with a conditional branch.
2102 r4 contains n, r5 contains src, and r6 contains dst.
2103 The 16-bit displacement operand is added to the pc
2104 if and only if the end of string is reached before
2105 n bytes are transferred. */
2106
2107 ea = GET_L_REG (4) & 0xffff;
2108 if (ea == 0)
2109 ea = 0x10000;
2110
2111 while (ea--)
2112 {
2113 rd = GET_MEMORY_B (GET_L_REG (5));
2114 SET_MEMORY_B (GET_L_REG (6), rd);
2115 SET_L_REG (5, GET_L_REG (5) + 1);
2116 SET_L_REG (6, GET_L_REG (6) + 1);
2117 SET_W_REG (4, ea);
2118 if (rd == 0)
2119 goto condtrue;
2120 }
2121 goto next;
2122
2123 case O (O_EEPMOV, SB): /* eepmov.b */
2124 case O (O_EEPMOV, SW): /* eepmov.w */
2125 if (h8300hmode || h8300smode)
2126 {
2127 register unsigned char *_src, *_dst;
2128 unsigned int count = ((code->opcode == O (O_EEPMOV, SW))
2129 ? h8_get_reg (sd, R4_REGNUM) & 0xffff
2130 : h8_get_reg (sd, R4_REGNUM) & 0xff);
2131
54780889 2132 _src = h8_get_memory_buf (sd) + h8_get_reg (sd, R5_REGNUM);
dc5c3759 2133 if ((_src + count) >= (h8_get_memory_buf (sd) + memory_size))
54780889
MF
2134 goto illegal;
2135 _dst = h8_get_memory_buf (sd) + h8_get_reg (sd, R6_REGNUM);
dc5c3759 2136 if ((_dst + count) >= (h8_get_memory_buf (sd) + memory_size))
54780889 2137 goto illegal;
dc5c3759
MS
2138 memcpy (_dst, _src, count);
2139
2140 h8_set_reg (sd, R5_REGNUM, h8_get_reg (sd, R5_REGNUM) + count);
2141 h8_set_reg (sd, R6_REGNUM, h8_get_reg (sd, R6_REGNUM) + count);
2142 h8_set_reg (sd, R4_REGNUM, h8_get_reg (sd, R4_REGNUM) &
2143 ((code->opcode == O (O_EEPMOV, SW))
2144 ? (~0xffff) : (~0xff)));
2145 cycles += 2 * count;
2146 goto next;
2147 }
2148 goto illegal;
2149
2150 case O (O_ADDS, SL): /* adds (.l) */
2151 /* FIXME fetch.
2152 * This insn only uses register operands, but still
2153 * it would be cleaner to use fetch and store... */
2154 SET_L_REG (code->dst.reg,
2155 GET_L_REG (code->dst.reg)
2156 + code->src.literal);
2157
2158 goto next;
2159
2160 case O (O_SUBS, SL): /* subs (.l) */
2161 /* FIXME fetch.
2162 * This insn only uses register operands, but still
2163 * it would be cleaner to use fetch and store... */
2164 SET_L_REG (code->dst.reg,
2165 GET_L_REG (code->dst.reg)
2166 - code->src.literal);
2167 goto next;
2168
2169 case O (O_CMP, SB): /* cmp.b */
2170 if (fetch (sd, &code->dst, &rd))
2171 goto end;
2172 if (fetch (sd, &code->src, &ea))
2173 goto end;
2174 ea = -ea;
2175 res = rd + ea;
2176 goto just_flags_alu8;
2177
2178 case O (O_CMP, SW): /* cmp.w */
2179 if (fetch (sd, &code->dst, &rd))
2180 goto end;
2181 if (fetch (sd, &code->src, &ea))
2182 goto end;
2183 ea = -ea;
2184 res = rd + ea;
2185 goto just_flags_alu16;
2186
2187 case O (O_CMP, SL): /* cmp.l */
2188 if (fetch (sd, &code->dst, &rd))
2189 goto end;
2190 if (fetch (sd, &code->src, &ea))
2191 goto end;
2192 ea = -ea;
2193 res = rd + ea;
2194 goto just_flags_alu32;
2195
2196 case O (O_DEC, SB): /* dec.b */
2197 /* FIXME fetch.
2198 * This insn only uses register operands, but still
2199 * it would be cleaner to use fetch and store... */
2200 rd = GET_B_REG (code->src.reg);
2201 ea = -1;
2202 res = rd + ea;
2203 SET_B_REG (code->src.reg, res);
2204 goto just_flags_inc8;
2205
2206 case O (O_DEC, SW): /* dec.w */
2207 /* FIXME fetch.
2208 * This insn only uses register operands, but still
2209 * it would be cleaner to use fetch and store... */
2210 rd = GET_W_REG (code->dst.reg);
2211 ea = -code->src.literal;
2212 res = rd + ea;
2213 SET_W_REG (code->dst.reg, res);
2214 goto just_flags_inc16;
2215
2216 case O (O_DEC, SL): /* dec.l */
2217 /* FIXME fetch.
2218 * This insn only uses register operands, but still
2219 * it would be cleaner to use fetch and store... */
2220 rd = GET_L_REG (code->dst.reg);
2221 ea = -code->src.literal;
2222 res = rd + ea;
2223 SET_L_REG (code->dst.reg, res);
2224 goto just_flags_inc32;
2225
2226 case O (O_INC, SB): /* inc.b */
2227 /* FIXME fetch.
2228 * This insn only uses register operands, but still
2229 * it would be cleaner to use fetch and store... */
2230 rd = GET_B_REG (code->src.reg);
2231 ea = 1;
2232 res = rd + ea;
2233 SET_B_REG (code->src.reg, res);
2234 goto just_flags_inc8;
2235
2236 case O (O_INC, SW): /* inc.w */
2237 /* FIXME fetch.
2238 * This insn only uses register operands, but still
2239 * it would be cleaner to use fetch and store... */
2240 rd = GET_W_REG (code->dst.reg);
2241 ea = code->src.literal;
2242 res = rd + ea;
2243 SET_W_REG (code->dst.reg, res);
2244 goto just_flags_inc16;
2245
2246 case O (O_INC, SL): /* inc.l */
2247 /* FIXME fetch.
2248 * This insn only uses register operands, but still
2249 * it would be cleaner to use fetch and store... */
2250 rd = GET_L_REG (code->dst.reg);
2251 ea = code->src.literal;
2252 res = rd + ea;
2253 SET_L_REG (code->dst.reg, res);
2254 goto just_flags_inc32;
2255
2256 case O (O_LDC, SB): /* ldc.b */
2257 if (fetch (sd, &code->src, &res))
2258 goto end;
2259 goto setc;
2260
2261 case O (O_LDC, SW): /* ldc.w */
2262 if (fetch (sd, &code->src, &res))
2263 goto end;
2264
2265 /* Word operand, value from MSB, must be shifted. */
2266 res >>= 8;
2267 goto setc;
2268
2269 case O (O_LDC, SL): /* ldc.l */
2270 if (fetch (sd, &code->src, &res))
2271 goto end;
2272 switch (code->dst.type) {
2273 case X (OP_SBR, SL):
2274 h8_set_sbr (sd, res);
2275 break;
2276 case X (OP_VBR, SL):
2277 h8_set_vbr (sd, res);
2278 break;
2279 default:
2280 goto illegal;
2281 }
2282 goto next;
2283
2284 case O (O_STC, SW): /* stc.w */
2285 case O (O_STC, SB): /* stc.b */
2286 if (code->src.type == X (OP_CCR, SB))
2287 {
2288 BUILDSR (sd);
2289 res = h8_get_ccr (sd);
2290 }
2291 else if (code->src.type == X (OP_EXR, SB) && h8300smode)
2292 {
2293 if (h8300smode)
2294 h8_set_exr (sd, (trace << 7) | intMask);
2295 res = h8_get_exr (sd);
2296 }
2297 else
2298 goto illegal;
2299
2300 /* Word operand, value to MSB, must be shifted. */
2301 if (code->opcode == X (O_STC, SW))
2302 res <<= 8;
2303 if (store (sd, &code->dst, res))
2304 goto end;
2305 goto next;
2306 case O (O_STC, SL): /* stc.l */
2307 switch (code->src.type) {
2308 case X (OP_SBR, SL):
2309 res = h8_get_sbr (sd);
2310 break;
2311 case X (OP_VBR, SL):
2312 res = h8_get_vbr (sd);
2313 break;
2314 default:
2315 goto illegal;
2316 }
2317 if (store (sd, &code->dst, res))
2318 goto end;
2319 goto next;
2320
2321 case O (O_ANDC, SB): /* andc.b */
2322 if (code->dst.type == X (OP_CCR, SB))
2323 {
2324 BUILDSR (sd);
2325 rd = h8_get_ccr (sd);
2326 }
2327 else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
2328 {
2329 if (h8300smode)
2330 h8_set_exr (sd, (trace << 7) | intMask);
d6fd015d 2331 rd = h8_get_exr (sd);
dc5c3759
MS
2332 }
2333 else
2334 goto illegal;
2335 ea = code->src.literal;
2336 res = rd & ea;
2337 goto setc;
2338
2339 case O (O_ORC, SB): /* orc.b */
2340 if (code->dst.type == X (OP_CCR, SB))
2341 {
2342 BUILDSR (sd);
2343 rd = h8_get_ccr (sd);
2344 }
2345 else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
2346 {
2347 if (h8300smode)
2348 h8_set_exr (sd, (trace << 7) | intMask);
2349 rd = h8_get_exr (sd);
2350 }
2351 else
2352 goto illegal;
2353 ea = code->src.literal;
2354 res = rd | ea;
2355 goto setc;
2356
2357 case O (O_XORC, SB): /* xorc.b */
2358 if (code->dst.type == X (OP_CCR, SB))
2359 {
2360 BUILDSR (sd);
2361 rd = h8_get_ccr (sd);
2362 }
2363 else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
2364 {
2365 if (h8300smode)
2366 h8_set_exr (sd, (trace << 7) | intMask);
2367 rd = h8_get_exr (sd);
2368 }
2369 else
2370 goto illegal;
2371 ea = code->src.literal;
2372 res = rd ^ ea;
2373 goto setc;
2374
2375 case O (O_BRAS, SB): /* bra/s */
2376 /* This is basically an ordinary branch, with a delay slot. */
2377 if (fetch (sd, &code->src, &res))
2378 goto end;
2379
2380 if ((res & 1) == 0)
2381 goto illegal;
2382
2383 res -= 1;
2384
2385 /* Execution continues at next instruction, but
2386 delayed_branch is set up for next cycle. */
2387 h8_set_delayed_branch (sd, code->next_pc + res);
2388 pc = code->next_pc;
2389 goto end;
2390
2391 case O (O_BRAB, SB): /* bra rd.b */
2392 case O (O_BRAW, SW): /* bra rd.w */
2393 case O (O_BRAL, SL): /* bra erd.l */
2394 if (fetch (sd, &code->src, &rd))
2395 goto end;
2396 switch (OP_SIZE (code->opcode)) {
2397 case SB: rd &= 0xff; break;
2398 case SW: rd &= 0xffff; break;
2399 case SL: rd &= 0xffffffff; break;
2400 }
2401 pc = code->next_pc + rd;
2402 goto end;
2403
2404 case O (O_BRABC, SB): /* bra/bc, branch if bit clear */
2405 case O (O_BRABS, SB): /* bra/bs, branch if bit set */
2406 case O (O_BSRBC, SB): /* bsr/bc, call if bit clear */
2407 case O (O_BSRBS, SB): /* bsr/bs, call if bit set */
2408 if (fetch (sd, &code->dst, &rd) ||
2409 fetch (sd, &code->src, &bit))
2410 goto end;
2411
2412 if (code->opcode == O (O_BRABC, SB) || /* branch if clear */
2413 code->opcode == O (O_BSRBC, SB)) /* call if clear */
2414 {
2415 if ((rd & (1 << bit))) /* no branch */
2416 goto next;
2417 }
2418 else /* branch/call if set */
2419 {
2420 if (!(rd & (1 << bit))) /* no branch */
2421 goto next;
2422 }
2423
2424 if (fetch (sd, &code->op3, &res)) /* branch */
2425 goto end;
2426 pc = code->next_pc + res;
2427
2428 if (code->opcode == O (O_BRABC, SB) ||
2429 code->opcode == O (O_BRABS, SB)) /* branch */
2430 goto end;
2431 else /* call */
2432 goto call;
2433
2434 case O (O_BRA, SN):
2435 case O (O_BRA, SL):
2436 case O (O_BRA, SW):
2437 case O (O_BRA, SB): /* bra, branch always */
2438 if (1)
2439 goto condtrue;
2440 goto next;
2441
2442 case O (O_BRN, SB): /* brn, ;-/ branch never? */
2443 if (0)
2444 goto condtrue;
2445 goto next;
2446
2447 case O (O_BHI, SB): /* bhi */
2448 if ((C || Z) == 0)
2449 goto condtrue;
2450 goto next;
2451
2452
2453 case O (O_BLS, SB): /* bls */
2454 if ((C || Z))
2455 goto condtrue;
2456 goto next;
2457
2458 case O (O_BCS, SB): /* bcs, branch if carry set */
2459 if ((C == 1))
2460 goto condtrue;
2461 goto next;
2462
2463 case O (O_BCC, SB): /* bcc, branch if carry clear */
2464 if ((C == 0))
2465 goto condtrue;
2466 goto next;
2467
2468 case O (O_BEQ, SB): /* beq, branch if zero set */
2469 if (Z)
2470 goto condtrue;
2471 goto next;
2472 case O (O_BGT, SB): /* bgt */
2473 if (((Z || (N ^ V)) == 0))
2474 goto condtrue;
2475 goto next;
2476
2477 case O (O_BLE, SB): /* ble */
2478 if (((Z || (N ^ V)) == 1))
2479 goto condtrue;
2480 goto next;
2481
2482 case O (O_BGE, SB): /* bge */
2483 if ((N ^ V) == 0)
2484 goto condtrue;
2485 goto next;
2486 case O (O_BLT, SB): /* blt */
2487 if ((N ^ V))
2488 goto condtrue;
2489 goto next;
2490 case O (O_BMI, SB): /* bmi */
2491 if ((N))
2492 goto condtrue;
2493 goto next;
2494 case O (O_BNE, SB): /* bne, branch if zero clear */
2495 if ((Z == 0))
2496 goto condtrue;
2497 goto next;
2498
2499 case O (O_BPL, SB): /* bpl */
2500 if (N == 0)
2501 goto condtrue;
2502 goto next;
2503 case O (O_BVC, SB): /* bvc */
2504 if ((V == 0))
2505 goto condtrue;
2506 goto next;
2507 case O (O_BVS, SB): /* bvs */
2508 if ((V == 1))
2509 goto condtrue;
2510 goto next;
2511
2512 /* Trap for Command Line setup. */
2513 case O (O_SYS_CMDLINE, SB):
2514 {
2515 int i = 0; /* Loop counter. */
2516 int j = 0; /* Loop counter. */
2517 int ind_arg_len = 0; /* Length of each argument. */
2518 int no_of_args = 0; /* The no. or cmdline args. */
2519 int current_location = 0; /* Location of string. */
2520 int old_sp = 0; /* The Initial Stack Pointer. */
2521 int no_of_slots = 0; /* No. of slots required on the stack
2522 for storing cmdline args. */
2523 int sp_move = 0; /* No. of locations by which the stack needs
2524 to grow. */
2525 int new_sp = 0; /* The final stack pointer location passed
2526 back. */
2527 int *argv_ptrs; /* Pointers of argv strings to be stored. */
2528 int argv_ptrs_location = 0; /* Location of pointers to cmdline
2529 args on the stack. */
2530 int char_ptr_size = 0; /* Size of a character pointer on
2531 target machine. */
2532 int addr_cmdline = 0; /* Memory location where cmdline has
2533 to be stored. */
2534 int size_cmdline = 0; /* Size of cmdline. */
2535
2536 /* Set the address of 256 free locations where command line is
2537 stored. */
2538 addr_cmdline = cmdline_location();
2539 h8_set_reg (sd, 0, addr_cmdline);
2540
2541 /* Counting the no. of commandline arguments. */
2542 for (i = 0; h8_get_cmdline_arg (sd, i) != NULL; i++)
2543 continue;
2544
2545 /* No. of arguments in the command line. */
2546 no_of_args = i;
2547
2548 /* Current location is just a temporary variable,which we are
2549 setting to the point to the start of our commandline string. */
2550 current_location = addr_cmdline;
2551
2552 /* Allocating space for storing pointers of the command line
2553 arguments. */
2554 argv_ptrs = (int *) malloc (sizeof (int) * no_of_args);
2555
2556 /* Setting char_ptr_size to the sizeof (char *) on the different
2557 architectures. */
59768597 2558 if ((h8300hmode || h8300smode) && !h8300_normal_mode)
dc5c3759
MS
2559 {
2560 char_ptr_size = 4;
2561 }
2562 else
2563 {
2564 char_ptr_size = 2;
2565 }
2566
2567 for (i = 0; i < no_of_args; i++)
2568 {
2569 ind_arg_len = 0;
2570
2571 /* The size of the commandline argument. */
917c78f9 2572 ind_arg_len = strlen (h8_get_cmdline_arg (sd, i)) + 1;
dc5c3759
MS
2573
2574 /* The total size of the command line string. */
2575 size_cmdline += ind_arg_len;
2576
2577 /* As we have only 256 bytes, we need to provide a graceful
2578 exit. Anyways, a program using command line arguments
2579 where we cannot store all the command line arguments
2580 given may behave unpredictably. */
2581 if (size_cmdline >= 256)
2582 {
2583 h8_set_reg (sd, 0, 0);
2584 goto next;
2585 }
2586 else
2587 {
2588 /* current_location points to the memory where the next
2589 commandline argument is stored. */
2590 argv_ptrs[i] = current_location;
2591 for (j = 0; j < ind_arg_len; j++)
2592 {
2593 SET_MEMORY_B ((current_location +
2594 (sizeof (char) * j)),
2595 *(h8_get_cmdline_arg (sd, i) +
2596 sizeof (char) * j));
2597 }
2598
2599 /* Setting current_location to the starting of next
2600 argument. */
2601 current_location += ind_arg_len;
2602 }
2603 }
2604
2605 /* This is the original position of the stack pointer. */
2606 old_sp = h8_get_reg (sd, SP_REGNUM);
2607
2608 /* We need space from the stack to store the pointers to argvs. */
2609 /* As we will infringe on the stack, we need to shift the stack
2610 pointer so that the data is not overwritten. We calculate how
2611 much space is required. */
2612 sp_move = (no_of_args) * (char_ptr_size);
2613
2614 /* The final position of stack pointer, we have thus taken some
2615 space from the stack. */
2616 new_sp = old_sp - sp_move;
2617
2618 /* Temporary variable holding value where the argv pointers need
2619 to be stored. */
2620 argv_ptrs_location = new_sp;
2621
2622 /* The argv pointers are stored at sequential locations. As per
2623 the H8300 ABI. */
2624 for (i = 0; i < no_of_args; i++)
2625 {
2626 /* Saving the argv pointer. */
59768597 2627 if ((h8300hmode || h8300smode) && !h8300_normal_mode)
dc5c3759
MS
2628 {
2629 SET_MEMORY_L (argv_ptrs_location, argv_ptrs[i]);
2630 }
2631 else
2632 {
2633 SET_MEMORY_W (argv_ptrs_location, argv_ptrs[i]);
2634 }
2635
2636 /* The next location where the pointer to the next argv
2637 string has to be stored. */
2638 argv_ptrs_location += char_ptr_size;
2639 }
2640
2641 /* Required by POSIX, Setting 0x0 at the end of the list of argv
2642 pointers. */
59768597 2643 if ((h8300hmode || h8300smode) && !h8300_normal_mode)
dc5c3759
MS
2644 {
2645 SET_MEMORY_L (old_sp, 0x0);
2646 }
2647 else
2648 {
2649 SET_MEMORY_W (old_sp, 0x0);
2650 }
2651
2652 /* Freeing allocated memory. */
2653 free (argv_ptrs);
2654 for (i = 0; i <= no_of_args; i++)
2655 {
2656 free (h8_get_cmdline_arg (sd, i));
2657 }
2658 free (h8_get_command_line (sd));
2659
2660 /* The no. of argv arguments are returned in Reg 0. */
2661 h8_set_reg (sd, 0, no_of_args);
2662 /* The Pointer to argv in Register 1. */
2663 h8_set_reg (sd, 1, new_sp);
2664 /* Setting the stack pointer to the new value. */
2665 h8_set_reg (sd, SP_REGNUM, new_sp);
2666 }
2667 goto next;
2668
2669 /* System call processing starts. */
2670 case O (O_SYS_OPEN, SB):
2671 {
2672 int len = 0; /* Length of filename. */
2673 char *filename; /* Filename would go here. */
2674 char temp_char; /* Temporary character */
2675 int mode = 0; /* Mode bits for the file. */
2676 int open_return; /* Return value of open, file descriptor. */
2677 int i; /* Loop counter */
2678 int filename_ptr; /* Pointer to filename in cpu memory. */
2679
2680 /* Setting filename_ptr to first argument of open, */
2681 /* and trying to get mode. */
59768597 2682 if ((h8300sxmode || h8300hmode || h8300smode) && !h8300_normal_mode)
dc5c3759
MS
2683 {
2684 filename_ptr = GET_L_REG (0);
2685 mode = GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM) + 4);
2686 }
2687 else
2688 {
2689 filename_ptr = GET_W_REG (0);
2690 mode = GET_MEMORY_W (h8_get_reg (sd, SP_REGNUM) + 2);
2691 }
2692
2693 /* Trying to find the length of the filename. */
2694 temp_char = GET_MEMORY_B (h8_get_reg (sd, 0));
2695
2696 len = 1;
2697 while (temp_char != '\0')
2698 {
2699 temp_char = GET_MEMORY_B (filename_ptr + len);
2700 len++;
2701 }
2702
2703 /* Allocating space for the filename. */
2704 filename = (char *) malloc (sizeof (char) * len);
2705
2706 /* String copying the filename from memory. */
2707 for (i = 0; i < len; i++)
2708 {
2709 temp_char = GET_MEMORY_B (filename_ptr + i);
2710 filename[i] = temp_char;
2711 }
2712
2713 /* Callback to open and return the file descriptor. */
2714 open_return = sim_callback->open (sim_callback, filename, mode);
2715
2716 /* Return value in register 0. */
2717 h8_set_reg (sd, 0, open_return);
2718
2719 /* Freeing memory used for filename. */
2720 free (filename);
2721 }
2722 goto next;
2723
2724 case O (O_SYS_READ, SB):
2725 {
2726 char *char_ptr; /* Where characters read would be stored. */
2727 int fd; /* File descriptor */
2728 int buf_size; /* BUF_SIZE parameter in read. */
2729 int i = 0; /* Temporary Loop counter */
2730 int read_return = 0; /* Return value from callback to
2731 read. */
2732
59768597
SA
2733 fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
2734 buf_size = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
dc5c3759
MS
2735
2736 char_ptr = (char *) malloc (sizeof (char) * buf_size);
2737
2738 /* Callback to read and return the no. of characters read. */
2739 read_return =
2740 sim_callback->read (sim_callback, fd, char_ptr, buf_size);
2741
2742 /* The characters read are stored in cpu memory. */
2743 for (i = 0; i < buf_size; i++)
2744 {
2745 SET_MEMORY_B ((h8_get_reg (sd, 1) + (sizeof (char) * i)),
2746 *(char_ptr + (sizeof (char) * i)));
2747 }
2748
2749 /* Return value in Register 0. */
2750 h8_set_reg (sd, 0, read_return);
2751
2752 /* Freeing memory used as buffer. */
2753 free (char_ptr);
2754 }
2755 goto next;
2756
2757 case O (O_SYS_WRITE, SB):
2758 {
2759 int fd; /* File descriptor */
2760 char temp_char; /* Temporary character */
2761 int len; /* Length of write, Parameter II to write. */
2762 int char_ptr; /* Character Pointer, Parameter I of write. */
2763 char *ptr; /* Where characters to be written are stored.
2764 */
2765 int write_return; /* Return value from callback to write. */
2766 int i = 0; /* Loop counter */
2767
59768597
SA
2768 fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
2769 char_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
2770 len = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
dc5c3759
MS
2771
2772 /* Allocating space for the characters to be written. */
2773 ptr = (char *) malloc (sizeof (char) * len);
2774
2775 /* Fetching the characters from cpu memory. */
2776 for (i = 0; i < len; i++)
2777 {
2778 temp_char = GET_MEMORY_B (char_ptr + i);
2779 ptr[i] = temp_char;
2780 }
2781
2782 /* Callback write and return the no. of characters written. */
2783 write_return = sim_callback->write (sim_callback, fd, ptr, len);
2784
2785 /* Return value in Register 0. */
2786 h8_set_reg (sd, 0, write_return);
2787
2788 /* Freeing memory used as buffer. */
2789 free (ptr);
2790 }
2791 goto next;
2792
2793 case O (O_SYS_LSEEK, SB):
2794 {
2795 int fd; /* File descriptor */
2796 int offset; /* Offset */
2797 int origin; /* Origin */
2798 int lseek_return; /* Return value from callback to lseek. */
2799
59768597
SA
2800 fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
2801 offset = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
2802 origin = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
c906108c 2803
dc5c3759
MS
2804 /* Callback lseek and return offset. */
2805 lseek_return =
2806 sim_callback->lseek (sim_callback, fd, offset, origin);
3b02cf92 2807
dc5c3759
MS
2808 /* Return value in register 0. */
2809 h8_set_reg (sd, 0, lseek_return);
2810 }
2811 goto next;
c906108c 2812
dc5c3759
MS
2813 case O (O_SYS_CLOSE, SB):
2814 {
2815 int fd; /* File descriptor */
2816 int close_return; /* Return value from callback to close. */
c906108c 2817
59768597 2818 fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
c906108c 2819
dc5c3759
MS
2820 /* Callback close and return. */
2821 close_return = sim_callback->close (sim_callback, fd);
c906108c 2822
dc5c3759
MS
2823 /* Return value in register 0. */
2824 h8_set_reg (sd, 0, close_return);
2825 }
2826 goto next;
c906108c 2827
dc5c3759
MS
2828 case O (O_SYS_FSTAT, SB):
2829 {
2830 int fd; /* File descriptor */
2831 struct stat stat_rec; /* Stat record */
2832 int fstat_return; /* Return value from callback to stat. */
2833 int stat_ptr; /* Pointer to stat record. */
2834 char *temp_stat_ptr; /* Temporary stat_rec pointer. */
c906108c 2835
59768597 2836 fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
c906108c 2837
dc5c3759 2838 /* Setting stat_ptr to second argument of stat. */
59768597 2839 stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
c906108c 2840
dc5c3759 2841 /* Callback stat and return. */
2d7bb758
JB
2842 fstat_return = sim_callback->to_fstat (sim_callback, fd,
2843 &stat_rec);
c906108c 2844
dc5c3759
MS
2845 /* Have stat_ptr point to starting of stat_rec. */
2846 temp_stat_ptr = (char *) (&stat_rec);
c906108c 2847
dc5c3759
MS
2848 /* Setting up the stat structure returned. */
2849 SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
2850 stat_ptr += 2;
2851 SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
2852 stat_ptr += 2;
2853 SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
2854 stat_ptr += 4;
2855 SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
2856 stat_ptr += 2;
2857 SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
2858 stat_ptr += 2;
2859 SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
2860 stat_ptr += 2;
2861 SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
2862 stat_ptr += 2;
2863 SET_MEMORY_L (stat_ptr, stat_rec.st_size);
2864 stat_ptr += 4;
2865 SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
2866 stat_ptr += 8;
2867 SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
2868 stat_ptr += 8;
2869 SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
c906108c 2870
dc5c3759
MS
2871 /* Return value in register 0. */
2872 h8_set_reg (sd, 0, fstat_return);
2873 }
2874 goto next;
c906108c 2875
dc5c3759
MS
2876 case O (O_SYS_STAT, SB):
2877 {
2878 int len = 0; /* Length of filename. */
2879 char *filename; /* Filename would go here. */
2880 char temp_char; /* Temporary character */
2881 int filename_ptr; /* Pointer to filename in cpu memory. */
2882 struct stat stat_rec; /* Stat record */
2883 int stat_return; /* Return value from callback to stat */
2884 int stat_ptr; /* Pointer to stat record. */
2885 char *temp_stat_ptr; /* Temporary stat_rec pointer. */
2886 int i = 0; /* Loop Counter */
c906108c 2887
dc5c3759 2888 /* Setting filename_ptr to first argument of open. */
59768597 2889 filename_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
c906108c 2890
dc5c3759
MS
2891 /* Trying to find the length of the filename. */
2892 temp_char = GET_MEMORY_B (h8_get_reg (sd, 0));
c906108c 2893
dc5c3759
MS
2894 len = 1;
2895 while (temp_char != '\0')
2896 {
2897 temp_char = GET_MEMORY_B (filename_ptr + len);
2898 len++;
2899 }
d0fe2f7e 2900
dc5c3759
MS
2901 /* Allocating space for the filename. */
2902 filename = (char *) malloc (sizeof (char) * len);
c3f4437e 2903
dc5c3759
MS
2904 /* String copying the filename from memory. */
2905 for (i = 0; i < len; i++)
2906 {
2907 temp_char = GET_MEMORY_B (filename_ptr + i);
2908 filename[i] = temp_char;
2909 }
c906108c 2910
dc5c3759
MS
2911 /* Setting stat_ptr to second argument of stat. */
2912 /* stat_ptr = h8_get_reg (sd, 1); */
59768597 2913 stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
c906108c 2914
dc5c3759
MS
2915 /* Callback stat and return. */
2916 stat_return =
2d7bb758 2917 sim_callback->to_stat (sim_callback, filename, &stat_rec);
c906108c 2918
dc5c3759
MS
2919 /* Have stat_ptr point to starting of stat_rec. */
2920 temp_stat_ptr = (char *) (&stat_rec);
2921
2922 /* Freeing memory used for filename. */
2923 free (filename);
2924
2925 /* Setting up the stat structure returned. */
2926 SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
2927 stat_ptr += 2;
2928 SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
2929 stat_ptr += 2;
2930 SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
2931 stat_ptr += 4;
2932 SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
2933 stat_ptr += 2;
2934 SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
2935 stat_ptr += 2;
2936 SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
2937 stat_ptr += 2;
2938 SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
2939 stat_ptr += 2;
2940 SET_MEMORY_L (stat_ptr, stat_rec.st_size);
2941 stat_ptr += 4;
2942 SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
2943 stat_ptr += 8;
2944 SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
2945 stat_ptr += 8;
2946 SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
2947
2948 /* Return value in register 0. */
2949 h8_set_reg (sd, 0, stat_return);
2950 }
c906108c 2951 goto next;
dc5c3759 2952 /* End of system call processing. */
c906108c 2953
dc5c3759
MS
2954 case O (O_NOT, SB): /* not.b */
2955 if (fetch2 (sd, &code->src, &rd))
2956 goto end;
2957 rd = ~rd;
2958 v = 0;
2959 goto shift8;
c906108c 2960
dc5c3759
MS
2961 case O (O_NOT, SW): /* not.w */
2962 if (fetch2 (sd, &code->src, &rd))
2963 goto end;
2964 rd = ~rd;
2965 v = 0;
2966 goto shift16;
c906108c 2967
dc5c3759
MS
2968 case O (O_NOT, SL): /* not.l */
2969 if (fetch2 (sd, &code->src, &rd))
2970 goto end;
2971 rd = ~rd;
2972 v = 0;
2973 goto shift32;
c906108c 2974
dc5c3759
MS
2975 case O (O_SHLL, SB): /* shll.b */
2976 case O (O_SHLR, SB): /* shlr.b */
2977 if (fetch2 (sd, &code->dst, &rd))
2978 goto end;
c906108c 2979
55acb21b
MS
2980 if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
2981 ea = 1; /* unary op */
2982 else /* binary op */
dc5c3759 2983 fetch (sd, &code->src, &ea);
c906108c 2984
dc5c3759
MS
2985 if (code->opcode == O (O_SHLL, SB))
2986 {
2987 v = (ea > 8);
2988 c = rd & (0x80 >> (ea - 1));
2989 rd <<= ea;
2990 }
2991 else
2992 {
2993 v = 0;
2994 c = rd & (1 << (ea - 1));
2995 rd = (unsigned char) rd >> ea;
2996 }
2997 goto shift8;
c906108c 2998
dc5c3759
MS
2999 case O (O_SHLL, SW): /* shll.w */
3000 case O (O_SHLR, SW): /* shlr.w */
3001 if (fetch2 (sd, &code->dst, &rd))
3002 goto end;
c906108c 3003
55acb21b
MS
3004 if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
3005 ea = 1; /* unary op */
dc5c3759 3006 else
55acb21b 3007 fetch (sd, &code->src, &ea);
c906108c 3008
dc5c3759
MS
3009 if (code->opcode == O (O_SHLL, SW))
3010 {
3011 v = (ea > 16);
3012 c = rd & (0x8000 >> (ea - 1));
3013 rd <<= ea;
3014 }
3015 else
3016 {
3017 v = 0;
3018 c = rd & (1 << (ea - 1));
3019 rd = (unsigned short) rd >> ea;
3020 }
3021 goto shift16;
c906108c 3022
dc5c3759
MS
3023 case O (O_SHLL, SL): /* shll.l */
3024 case O (O_SHLR, SL): /* shlr.l */
3025 if (fetch2 (sd, &code->dst, &rd))
3026 goto end;
c906108c 3027
55acb21b
MS
3028 if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
3029 ea = 1; /* unary op */
dc5c3759 3030 else
55acb21b 3031 fetch (sd, &code->src, &ea);
c906108c 3032
dc5c3759 3033 if (code->opcode == O (O_SHLL, SL))
c3f4437e 3034 {
dc5c3759
MS
3035 v = (ea > 32);
3036 c = rd & (0x80000000 >> (ea - 1));
3037 rd <<= ea;
c3f4437e 3038 }
dc5c3759 3039 else
c3f4437e 3040 {
dc5c3759
MS
3041 v = 0;
3042 c = rd & (1 << (ea - 1));
3043 rd = (unsigned int) rd >> ea;
c3f4437e 3044 }
dc5c3759
MS
3045 goto shift32;
3046
3047 case O (O_SHAL, SB):
3048 case O (O_SHAR, SB):
3049 if (fetch2 (sd, &code->dst, &rd))
3050 goto end;
3051
3052 if (code->src.type == X (OP_IMM, SB))
3053 fetch (sd, &code->src, &ea);
c3f4437e 3054 else
dc5c3759 3055 ea = 1;
6147b1f6 3056
dc5c3759 3057 if (code->opcode == O (O_SHAL, SB))
c3f4437e 3058 {
dc5c3759
MS
3059 c = rd & (0x80 >> (ea - 1));
3060 res = rd >> (7 - ea);
3061 v = ((res & 1) && !(res & 2))
3062 || (!(res & 1) && (res & 2));
3063 rd <<= ea;
c3f4437e 3064 }
dc5c3759 3065 else
c3f4437e 3066 {
dc5c3759
MS
3067 c = rd & (1 << (ea - 1));
3068 v = 0;
3069 rd = ((signed char) rd) >> ea;
c3f4437e 3070 }
dc5c3759
MS
3071 goto shift8;
3072
3073 case O (O_SHAL, SW):
3074 case O (O_SHAR, SW):
3075 if (fetch2 (sd, &code->dst, &rd))
3076 goto end;
3077
3078 if (code->src.type == X (OP_IMM, SW))
3079 fetch (sd, &code->src, &ea);
c3f4437e 3080 else
dc5c3759 3081 ea = 1;
c906108c 3082
dc5c3759 3083 if (code->opcode == O (O_SHAL, SW))
c3f4437e 3084 {
dc5c3759
MS
3085 c = rd & (0x8000 >> (ea - 1));
3086 res = rd >> (15 - ea);
3087 v = ((res & 1) && !(res & 2))
3088 || (!(res & 1) && (res & 2));
3089 rd <<= ea;
c3f4437e 3090 }
dc5c3759 3091 else
c3f4437e 3092 {
dc5c3759
MS
3093 c = rd & (1 << (ea - 1));
3094 v = 0;
3095 rd = ((signed short) rd) >> ea;
c3f4437e 3096 }
dc5c3759
MS
3097 goto shift16;
3098
3099 case O (O_SHAL, SL):
3100 case O (O_SHAR, SL):
3101 if (fetch2 (sd, &code->dst, &rd))
3102 goto end;
3103
3104 if (code->src.type == X (OP_IMM, SL))
3105 fetch (sd, &code->src, &ea);
3106 else
3107 ea = 1;
c906108c 3108
dc5c3759 3109 if (code->opcode == O (O_SHAL, SL))
c3f4437e 3110 {
dc5c3759
MS
3111 c = rd & (0x80000000 >> (ea - 1));
3112 res = rd >> (31 - ea);
3113 v = ((res & 1) && !(res & 2))
3114 || (!(res & 1) && (res & 2));
3115 rd <<= ea;
c3f4437e 3116 }
dc5c3759 3117 else
c3f4437e 3118 {
dc5c3759
MS
3119 c = rd & (1 << (ea - 1));
3120 v = 0;
3121 rd = ((signed int) rd) >> ea;
c3f4437e 3122 }
dc5c3759 3123 goto shift32;
c906108c 3124
dc5c3759
MS
3125 case O (O_ROTL, SB):
3126 case O (O_ROTR, SB):
3127 if (fetch2 (sd, &code->dst, &rd))
3128 goto end;
c906108c 3129
dc5c3759
MS
3130 if (code->src.type == X (OP_IMM, SB))
3131 fetch (sd, &code->src, &ea);
3132 else
3133 ea = 1;
c906108c 3134
dc5c3759
MS
3135 while (ea--)
3136 if (code->opcode == O (O_ROTL, SB))
3137 {
3138 c = rd & 0x80;
3139 rd <<= 1;
3140 if (c)
3141 rd |= 1;
3142 }
3143 else
3144 {
3145 c = rd & 1;
3146 rd = ((unsigned char) rd) >> 1;
3147 if (c)
3148 rd |= 0x80;
3149 }
c906108c 3150
dc5c3759
MS
3151 v = 0;
3152 goto shift8;
c906108c 3153
dc5c3759
MS
3154 case O (O_ROTL, SW):
3155 case O (O_ROTR, SW):
3156 if (fetch2 (sd, &code->dst, &rd))
3157 goto end;
c906108c 3158
dc5c3759
MS
3159 if (code->src.type == X (OP_IMM, SW))
3160 fetch (sd, &code->src, &ea);
3161 else
3162 ea = 1;
c906108c 3163
dc5c3759
MS
3164 while (ea--)
3165 if (code->opcode == O (O_ROTL, SW))
3166 {
3167 c = rd & 0x8000;
3168 rd <<= 1;
3169 if (c)
3170 rd |= 1;
3171 }
3172 else
3173 {
3174 c = rd & 1;
3175 rd = ((unsigned short) rd) >> 1;
3176 if (c)
3177 rd |= 0x8000;
3178 }
c906108c 3179
dc5c3759
MS
3180 v = 0;
3181 goto shift16;
c906108c 3182
dc5c3759
MS
3183 case O (O_ROTL, SL):
3184 case O (O_ROTR, SL):
3185 if (fetch2 (sd, &code->dst, &rd))
3186 goto end;
c906108c 3187
dc5c3759
MS
3188 if (code->src.type == X (OP_IMM, SL))
3189 fetch (sd, &code->src, &ea);
3190 else
3191 ea = 1;
c906108c 3192
dc5c3759
MS
3193 while (ea--)
3194 if (code->opcode == O (O_ROTL, SL))
3195 {
3196 c = rd & 0x80000000;
3197 rd <<= 1;
3198 if (c)
3199 rd |= 1;
3200 }
3201 else
3202 {
3203 c = rd & 1;
3204 rd = ((unsigned int) rd) >> 1;
3205 if (c)
3206 rd |= 0x80000000;
3207 }
c906108c 3208
dc5c3759
MS
3209 v = 0;
3210 goto shift32;
c906108c 3211
dc5c3759
MS
3212 case O (O_ROTXL, SB):
3213 case O (O_ROTXR, SB):
3214 if (fetch2 (sd, &code->dst, &rd))
3215 goto end;
d1360fb0 3216
dc5c3759
MS
3217 if (code->src.type == X (OP_IMM, SB))
3218 fetch (sd, &code->src, &ea);
3219 else
3220 ea = 1;
d1360fb0 3221
dc5c3759
MS
3222 while (ea--)
3223 if (code->opcode == O (O_ROTXL, SB))
3224 {
3225 res = rd & 0x80;
3226 rd <<= 1;
3227 if (C)
3228 rd |= 1;
3229 c = res;
3230 }
3231 else
3232 {
3233 res = rd & 1;
3234 rd = ((unsigned char) rd) >> 1;
3235 if (C)
3236 rd |= 0x80;
3237 c = res;
3238 }
d1360fb0 3239
dc5c3759
MS
3240 v = 0;
3241 goto shift8;
d1360fb0 3242
dc5c3759
MS
3243 case O (O_ROTXL, SW):
3244 case O (O_ROTXR, SW):
3245 if (fetch2 (sd, &code->dst, &rd))
3246 goto end;
d1360fb0 3247
dc5c3759
MS
3248 if (code->src.type == X (OP_IMM, SW))
3249 fetch (sd, &code->src, &ea);
3250 else
3251 ea = 1;
d1360fb0 3252
dc5c3759
MS
3253 while (ea--)
3254 if (code->opcode == O (O_ROTXL, SW))
d1360fb0 3255 {
dc5c3759
MS
3256 res = rd & 0x8000;
3257 rd <<= 1;
3258 if (C)
3259 rd |= 1;
3260 c = res;
d1360fb0
V
3261 }
3262 else
3263 {
dc5c3759
MS
3264 res = rd & 1;
3265 rd = ((unsigned short) rd) >> 1;
3266 if (C)
3267 rd |= 0x8000;
3268 c = res;
d1360fb0
V
3269 }
3270
dc5c3759
MS
3271 v = 0;
3272 goto shift16;
d1360fb0 3273
dc5c3759
MS
3274 case O (O_ROTXL, SL):
3275 case O (O_ROTXR, SL):
3276 if (fetch2 (sd, &code->dst, &rd))
3277 goto end;
d1360fb0 3278
dc5c3759
MS
3279 if (code->src.type == X (OP_IMM, SL))
3280 fetch (sd, &code->src, &ea);
3281 else
3282 ea = 1;
d1360fb0 3283
dc5c3759
MS
3284 while (ea--)
3285 if (code->opcode == O (O_ROTXL, SL))
3286 {
3287 res = rd & 0x80000000;
3288 rd <<= 1;
3289 if (C)
3290 rd |= 1;
3291 c = res;
3292 }
3293 else
3294 {
3295 res = rd & 1;
3296 rd = ((unsigned int) rd) >> 1;
3297 if (C)
3298 rd |= 0x80000000;
3299 c = res;
d1360fb0
V
3300 }
3301
dc5c3759
MS
3302 v = 0;
3303 goto shift32;
d1360fb0 3304
dc5c3759
MS
3305 case O (O_JMP, SN):
3306 case O (O_JMP, SL):
3307 case O (O_JMP, SB): /* jmp */
3308 case O (O_JMP, SW):
9f70f8ec
MS
3309 fetch (sd, &code->src, &pc);
3310 goto end;
d1360fb0 3311
dc5c3759
MS
3312 case O (O_JSR, SN):
3313 case O (O_JSR, SL):
3314 case O (O_JSR, SB): /* jsr, jump to subroutine */
3315 case O (O_JSR, SW):
9f70f8ec
MS
3316 if (fetch (sd, &code->src, &pc))
3317 goto end;
3318 call:
3319 tmp = h8_get_reg (sd, SP_REGNUM);
d1360fb0 3320
59768597 3321 if (h8300hmode && !h8300_normal_mode)
9f70f8ec
MS
3322 {
3323 tmp -= 4;
3324 SET_MEMORY_L (tmp, code->next_pc);
3325 }
3326 else
3327 {
3328 tmp -= 2;
3329 SET_MEMORY_W (tmp, code->next_pc);
3330 }
3331 h8_set_reg (sd, SP_REGNUM, tmp);
d1360fb0 3332
9f70f8ec 3333 goto end;
dc5c3759
MS
3334
3335 case O (O_BSR, SW):
3336 case O (O_BSR, SL):
3337 case O (O_BSR, SB): /* bsr, branch to subroutine */
3338 if (fetch (sd, &code->src, &res))
3339 goto end;
3340 pc = code->next_pc + res;
3341 goto call;
3342
9f70f8ec
MS
3343 case O (O_RTE, SN): /* rte, return from exception */
3344 rte:
3345 /* Pops exr and ccr before pc -- otherwise identical to rts. */
3346 tmp = h8_get_reg (sd, SP_REGNUM);
dc5c3759 3347
9f70f8ec
MS
3348 if (h8300smode) /* pop exr */
3349 {
3350 h8_set_exr (sd, GET_MEMORY_L (tmp));
3351 tmp += 4;
3352 }
59768597 3353 if (h8300hmode && !h8300_normal_mode)
9f70f8ec
MS
3354 {
3355 h8_set_ccr (sd, GET_MEMORY_L (tmp));
3356 tmp += 4;
3357 pc = GET_MEMORY_L (tmp);
3358 tmp += 4;
3359 }
3360 else
3361 {
3362 h8_set_ccr (sd, GET_MEMORY_W (tmp));
3363 tmp += 2;
3364 pc = GET_MEMORY_W (tmp);
3365 tmp += 2;
3366 }
dc5c3759 3367
9f70f8ec
MS
3368 GETSR (sd);
3369 h8_set_reg (sd, SP_REGNUM, tmp);
3370 goto end;
d1360fb0 3371
9f70f8ec
MS
3372 case O (O_RTS, SN): /* rts, return from subroutine */
3373 rts:
3374 tmp = h8_get_reg (sd, SP_REGNUM);
3375
59768597 3376 if (h8300hmode && !h8300_normal_mode)
9f70f8ec
MS
3377 {
3378 pc = GET_MEMORY_L (tmp);
3379 tmp += 4;
3380 }
3381 else
3382 {
3383 pc = GET_MEMORY_W (tmp);
3384 tmp += 2;
3385 }
3386
3387 h8_set_reg (sd, SP_REGNUM, tmp);
3388 goto end;
d1360fb0 3389
dc5c3759 3390 case O (O_ILL, SB): /* illegal */
4ca9d09e 3391 sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL);
dc5c3759
MS
3392 goto end;
3393
3394 case O (O_SLEEP, SN): /* sleep */
3395 /* Check for magic numbers in r1 and r2. */
3396 if ((h8_get_reg (sd, R1_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC1 &&
3397 (h8_get_reg (sd, R2_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC2 &&
3398 SIM_WIFEXITED (h8_get_reg (sd, 0)))
3399 {
3400 /* This trap comes from _exit, not from gdb. */
4ca9d09e
MF
3401 sim_engine_halt (sd, cpu, NULL, pc, sim_exited,
3402 SIM_WEXITSTATUS (h8_get_reg (sd, 0)));
dc5c3759 3403 }
e22fef83 3404#if 0
f408565c
MS
3405 /* Unfortunately this won't really work, because
3406 when we take a breakpoint trap, R0 has a "random",
3407 user-defined value. Don't see any immediate solution. */
f0861129
MS
3408 else if (SIM_WIFSTOPPED (h8_get_reg (sd, 0)))
3409 {
3410 /* Pass the stop signal up to gdb. */
4ca9d09e
MF
3411 sim_engine_halt (sd, cpu, NULL, pc, sim_stopped,
3412 SIM_WSTOPSIG (h8_get_reg (sd, 0)));
f0861129 3413 }
e22fef83 3414#endif
dc5c3759
MS
3415 else
3416 {
3417 /* Treat it as a sigtrap. */
4ca9d09e 3418 sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
dc5c3759
MS
3419 }
3420 goto end;
bf174226 3421
9f70f8ec
MS
3422 case O (O_TRAPA, SB): /* trapa */
3423 if (fetch (sd, &code->src, &res))
59768597
SA
3424 goto end; /* res is vector number. */
3425
3426 tmp = h8_get_reg (sd, SP_REGNUM);
3427 if(h8300_normal_mode)
3428 {
3429 tmp -= 2;
3430 SET_MEMORY_W (tmp, code->next_pc);
3431 tmp -= 2;
3432 SET_MEMORY_W (tmp, h8_get_ccr (sd));
3433 }
3434 else
3435 {
3436 tmp -= 4;
3437 SET_MEMORY_L (tmp, code->next_pc);
3438 tmp -= 4;
3439 SET_MEMORY_L (tmp, h8_get_ccr (sd));
3440 }
3441 intMaskBit = 1;
3442 BUILDSR (sd);
3443
9f70f8ec
MS
3444 if (h8300smode)
3445 {
3446 tmp -= 4;
3447 SET_MEMORY_L (tmp, h8_get_exr (sd));
3448 }
3449
3450 h8_set_reg (sd, SP_REGNUM, tmp);
3451
59768597
SA
3452 if(h8300_normal_mode)
3453 pc = GET_MEMORY_L (0x10 + res * 2); /* Vector addresses are 0x10,0x12,0x14 and 0x16 */
3454 else
3455 pc = GET_MEMORY_L (0x20 + res * 4);
9f70f8ec
MS
3456 goto end;
3457
dc5c3759 3458 case O (O_BPT, SN):
4ca9d09e 3459 sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
dc5c3759 3460 goto end;
bf174226 3461
dc5c3759
MS
3462 case O (O_BSETEQ, SB):
3463 if (Z)
3464 goto bset;
3465 goto next;
bf174226 3466
dc5c3759
MS
3467 case O (O_BSETNE, SB):
3468 if (!Z)
3469 goto bset;
3470 goto next;
bf174226 3471
dc5c3759
MS
3472 case O (O_BCLREQ, SB):
3473 if (Z)
3474 goto bclr;
3475 goto next;
bf174226 3476
dc5c3759
MS
3477 case O (O_BCLRNE, SB):
3478 if (!Z)
3479 goto bclr;
3480 goto next;
bf174226 3481
dc5c3759
MS
3482 OBITOP (O_BNOT, 1, 1, ea ^= m); /* bnot */
3483 OBITOP (O_BTST, 1, 0, nz = ea & m); /* btst */
3484 bset:
3485 OBITOP (O_BSET, 1, 1, ea |= m); /* bset */
3486 bclr:
3487 OBITOP (O_BCLR, 1, 1, ea &= ~m); /* bclr */
3488 OBITOP (O_BLD, 1, 0, c = ea & m); /* bld */
3489 OBITOP (O_BILD, 1, 0, c = !(ea & m)); /* bild */
3490 OBITOP (O_BST, 1, 1, ea &= ~m;
3491 if (C) ea |= m); /* bst */
3492 OBITOP (O_BIST, 1, 1, ea &= ~m;
3493 if (!C) ea |= m); /* bist */
3494 OBITOP (O_BSTZ, 1, 1, ea &= ~m;
3495 if (Z) ea |= m); /* bstz */
3496 OBITOP (O_BISTZ, 1, 1, ea &= ~m;
3497 if (!Z) ea |= m); /* bistz */
3498 OBITOP (O_BAND, 1, 0, c = (ea & m) && C); /* band */
3499 OBITOP (O_BIAND, 1, 0, c = !(ea & m) && C); /* biand */
3500 OBITOP (O_BOR, 1, 0, c = (ea & m) || C); /* bor */
3501 OBITOP (O_BIOR, 1, 0, c = !(ea & m) || C); /* bior */
3502 OBITOP (O_BXOR, 1, 0, c = ((ea & m) != 0)!= C); /* bxor */
3503 OBITOP (O_BIXOR, 1, 0, c = !(ea & m) != C); /* bixor */
3504
3505 case O (O_BFLD, SB): /* bfld */
3506 /* bitfield load */
3507 ea = 0;
3508 if (fetch (sd, &code->src, &bit))
3509 goto end;
bf174226 3510
dc5c3759
MS
3511 if (bit != 0)
3512 {
3513 if (fetch (sd, &code->dst, &ea))
3514 goto end;
bf174226 3515
dc5c3759
MS
3516 ea &= bit;
3517 while (!(bit & 1))
3518 {
3519 ea >>= 1;
3520 bit >>= 1;
3521 }
3522 }
3523 if (store (sd, &code->op3, ea))
3524 goto end;
bf174226 3525
c906108c
SS
3526 goto next;
3527
dc5c3759
MS
3528 case O(O_BFST, SB): /* bfst */
3529 /* bitfield store */
3530 /* NOTE: the imm8 value is in dst, and the ea value
3531 (which is actually the destination) is in op3.
3532 It has to be that way, to avoid breaking the assembler. */
bf174226 3533
dc5c3759
MS
3534 if (fetch (sd, &code->dst, &bit)) /* imm8 */
3535 goto end;
3536 if (bit == 0) /* noop -- nothing to do. */
3537 goto next;
bf174226 3538
dc5c3759
MS
3539 if (fetch (sd, &code->src, &rd)) /* reg8 src */
3540 goto end;
bf174226 3541
dc5c3759
MS
3542 if (fetch2 (sd, &code->op3, &ea)) /* ea dst */
3543 goto end;
bf174226 3544
dc5c3759
MS
3545 /* Left-shift the register data into position. */
3546 for (tmp = bit; !(tmp & 1); tmp >>= 1)
3547 rd <<= 1;
bf174226 3548
dc5c3759
MS
3549 /* Combine it with the neighboring bits. */
3550 ea = (ea & ~bit) | (rd & bit);
bf174226 3551
dc5c3759
MS
3552 /* Put it back. */
3553 if (store2 (sd, &code->op3, ea))
3554 goto end;
3555 goto next;
3556
3557 case O (O_CLRMAC, SN): /* clrmac */
3558 h8_set_mach (sd, 0);
3559 h8_set_macl (sd, 0);
3560 h8_set_macZ (sd, 1);
3561 h8_set_macV (sd, 0);
3562 h8_set_macN (sd, 0);
3563 goto next;
3564
3565 case O (O_STMAC, SL): /* stmac, 260 */
3566 switch (code->src.type) {
3567 case X (OP_MACH, SL):
3568 res = h8_get_mach (sd);
3569 if (res & 0x200) /* sign extend */
3570 res |= 0xfffffc00;
3571 break;
3572 case X (OP_MACL, SL):
3573 res = h8_get_macl (sd);
3574 break;
3575 default: goto illegal;
bf174226 3576 }
dc5c3759
MS
3577 nz = !h8_get_macZ (sd);
3578 n = h8_get_macN (sd);
3579 v = h8_get_macV (sd);
3580
3581 if (store (sd, &code->dst, res))
3582 goto end;
3583
bf174226
V
3584 goto next;
3585
dc5c3759
MS
3586 case O (O_LDMAC, SL): /* ldmac, 179 */
3587 if (fetch (sd, &code->src, &rd))
3588 goto end;
bf174226 3589
dc5c3759
MS
3590 switch (code->dst.type) {
3591 case X (OP_MACH, SL):
3592 rd &= 0x3ff; /* Truncate to 10 bits */
3593 h8_set_mach (sd, rd);
3594 break;
3595 case X (OP_MACL, SL):
3596 h8_set_macl (sd, rd);
3597 break;
3598 default: goto illegal;
3599 }
3600 h8_set_macV (sd, 0);
3601 goto next;
bf174226 3602
dc5c3759
MS
3603 case O (O_MAC, SW):
3604 if (fetch (sd, &code->src, &rd) ||
3605 fetch (sd, &code->dst, &res))
3606 goto end;
bf174226 3607
dc5c3759
MS
3608 /* Ye gods, this is non-portable!
3609 However, the existing mul/div code is similar. */
3610 res = SEXTSHORT (res) * SEXTSHORT (rd);
bf174226 3611
dc5c3759
MS
3612 if (h8_get_macS (sd)) /* Saturating mode */
3613 {
3614 long long mac = h8_get_macl (sd);
bf174226 3615
dc5c3759
MS
3616 if (mac & 0x80000000) /* sign extend */
3617 mac |= 0xffffffff00000000LL;
bf174226 3618
dc5c3759
MS
3619 mac += res;
3620 if (mac > 0x7fffffff || mac < 0xffffffff80000000LL)
3621 h8_set_macV (sd, 1);
3622 h8_set_macZ (sd, (mac == 0));
3623 h8_set_macN (sd, (mac < 0));
3624 h8_set_macl (sd, (int) mac);
3625 }
3626 else /* "Less Saturating" mode */
3627 {
3628 long long mac = h8_get_mach (sd);
3629 mac <<= 32;
3630 mac += h8_get_macl (sd);
3631
3632 if (mac & 0x20000000000LL) /* sign extend */
3633 mac |= 0xfffffc0000000000LL;
3634
3635 mac += res;
3636 if (mac > 0x1ffffffffffLL ||
3637 mac < (long long) 0xfffffe0000000000LL)
3638 h8_set_macV (sd, 1);
3639 h8_set_macZ (sd, (mac == 0));
3640 h8_set_macN (sd, (mac < 0));
3641 h8_set_macl (sd, (int) mac);
3642 mac >>= 32;
3643 h8_set_mach (sd, (int) (mac & 0x3ff));
3644 }
bf174226
V
3645 goto next;
3646
dc5c3759
MS
3647 case O (O_MULS, SW): /* muls.w */
3648 if (fetch (sd, &code->src, &ea) ||
3649 fetch (sd, &code->dst, &rd))
3650 goto end;
bf174226 3651
e073c474 3652 ea = SEXTSHORT (ea);
dc5c3759
MS
3653 res = SEXTSHORT (ea * SEXTSHORT (rd));
3654
3655 n = res & 0x8000;
3656 nz = res & 0xffff;
3657 if (store (sd, &code->dst, res))
3658 goto end;
bf174226 3659
bf174226
V
3660 goto next;
3661
dc5c3759
MS
3662 case O (O_MULS, SL): /* muls.l */
3663 if (fetch (sd, &code->src, &ea) ||
3664 fetch (sd, &code->dst, &rd))
3665 goto end;
bf174226 3666
dc5c3759 3667 res = ea * rd;
bf174226 3668
dc5c3759
MS
3669 n = res & 0x80000000;
3670 nz = res & 0xffffffff;
3671 if (store (sd, &code->dst, res))
3672 goto end;
bf174226
V
3673 goto next;
3674
dc5c3759
MS
3675 case O (O_MULSU, SL): /* muls/u.l */
3676 if (fetch (sd, &code->src, &ea) ||
3677 fetch (sd, &code->dst, &rd))
3678 goto end;
bf174226 3679
dc5c3759
MS
3680 /* Compute upper 32 bits of the 64-bit result. */
3681 res = (((long long) ea) * ((long long) rd)) >> 32;
bf174226 3682
dc5c3759
MS
3683 n = res & 0x80000000;
3684 nz = res & 0xffffffff;
3685 if (store (sd, &code->dst, res))
3686 goto end;
3687 goto next;
bf174226 3688
dc5c3759
MS
3689 case O (O_MULU, SW): /* mulu.w */
3690 if (fetch (sd, &code->src, &ea) ||
3691 fetch (sd, &code->dst, &rd))
3692 goto end;
bf174226 3693
dc5c3759
MS
3694 res = UEXTSHORT ((UEXTSHORT (ea) * UEXTSHORT (rd)));
3695
3696 /* Don't set Z or N. */
3697 if (store (sd, &code->dst, res))
3698 goto end;
bf174226 3699
bf174226
V
3700 goto next;
3701
dc5c3759
MS
3702 case O (O_MULU, SL): /* mulu.l */
3703 if (fetch (sd, &code->src, &ea) ||
3704 fetch (sd, &code->dst, &rd))
3705 goto end;
bf174226 3706
dc5c3759 3707 res = ea * rd;
bf174226 3708
dc5c3759
MS
3709 /* Don't set Z or N. */
3710 if (store (sd, &code->dst, res))
3711 goto end;
bf174226 3712
dc5c3759 3713 goto next;
bf174226 3714
dc5c3759
MS
3715 case O (O_MULUU, SL): /* mulu/u.l */
3716 if (fetch (sd, &code->src, &ea) ||
3717 fetch (sd, &code->dst, &rd))
3718 goto end;
bf174226 3719
dc5c3759
MS
3720 /* Compute upper 32 bits of the 64-bit result. */
3721 res = (((unsigned long long) (unsigned) ea) *
3722 ((unsigned long long) (unsigned) rd)) >> 32;
bf174226 3723
dc5c3759
MS
3724 /* Don't set Z or N. */
3725 if (store (sd, &code->dst, res))
3726 goto end;
bf174226 3727
dc5c3759 3728 goto next;
bf174226 3729
dc5c3759
MS
3730 case O (O_MULXS, SB): /* mulxs.b */
3731 if (fetch (sd, &code->src, &ea) ||
3732 fetch (sd, &code->dst, &rd))
3733 goto end;
bf174226 3734
e073c474 3735 ea = SEXTCHAR (ea);
dc5c3759
MS
3736 res = ea * SEXTCHAR (rd);
3737
3738 n = res & 0x8000;
3739 nz = res & 0xffff;
3740 if (store (sd, &code->dst, res))
3741 goto end;
bf174226 3742
bf174226 3743 goto next;
bf174226 3744
dc5c3759
MS
3745 case O (O_MULXS, SW): /* mulxs.w */
3746 if (fetch (sd, &code->src, &ea) ||
3747 fetch (sd, &code->dst, &rd))
c906108c
SS
3748 goto end;
3749
e073c474 3750 ea = SEXTSHORT (ea);
dc5c3759 3751 res = ea * SEXTSHORT (rd & 0xffff);
c906108c 3752
dc5c3759
MS
3753 n = res & 0x80000000;
3754 nz = res & 0xffffffff;
3755 if (store (sd, &code->dst, res))
3756 goto end;
3757
3758 goto next;
c906108c 3759
dc5c3759
MS
3760 case O (O_MULXU, SB): /* mulxu.b */
3761 if (fetch (sd, &code->src, &ea) ||
3762 fetch (sd, &code->dst, &rd))
c906108c 3763 goto end;
c906108c 3764
dc5c3759 3765 res = UEXTCHAR (ea) * UEXTCHAR (rd);
c906108c 3766
dc5c3759
MS
3767 if (store (sd, &code->dst, res))
3768 goto end;
c906108c 3769
dc5c3759 3770 goto next;
c906108c 3771
dc5c3759
MS
3772 case O (O_MULXU, SW): /* mulxu.w */
3773 if (fetch (sd, &code->src, &ea) ||
3774 fetch (sd, &code->dst, &rd))
c906108c 3775 goto end;
c906108c 3776
dc5c3759 3777 res = UEXTSHORT (ea) * UEXTSHORT (rd);
c906108c 3778
dc5c3759
MS
3779 if (store (sd, &code->dst, res))
3780 goto end;
3781
3782 goto next;
c906108c 3783
9f70f8ec
MS
3784 case O (O_TAS, SB): /* tas (test and set) */
3785 if (!h8300sxmode) /* h8sx can use any register. */
3786 switch (code->src.reg)
3787 {
3788 case R0_REGNUM:
3789 case R1_REGNUM:
3790 case R4_REGNUM:
3791 case R5_REGNUM:
3792 break;
3793 default:
3794 goto illegal;
3795 }
3796
dc5c3759
MS
3797 if (fetch (sd, &code->src, &res))
3798 goto end;
3799 if (store (sd, &code->src, res | 0x80))
3800 goto end;
3801
6147b1f6 3802 goto just_flags_log8;
c906108c 3803
dc5c3759
MS
3804 case O (O_DIVU, SW): /* divu.w */
3805 if (fetch (sd, &code->src, &ea) ||
3806 fetch (sd, &code->dst, &rd))
3807 goto end;
c906108c 3808
dc5c3759
MS
3809 n = ea & 0x8000;
3810 nz = ea & 0xffff;
3811 if (ea)
3812 res = (unsigned) (UEXTSHORT (rd) / UEXTSHORT (ea));
3813 else
3814 res = 0;
c906108c 3815
dc5c3759
MS
3816 if (store (sd, &code->dst, res))
3817 goto end;
3818 goto next;
c906108c 3819
dc5c3759
MS
3820 case O (O_DIVU, SL): /* divu.l */
3821 if (fetch (sd, &code->src, &ea) ||
3822 fetch (sd, &code->dst, &rd))
3823 goto end;
3824
3825 n = ea & 0x80000000;
3826 nz = ea & 0xffffffff;
3827 if (ea)
3828 res = (unsigned) rd / ea;
3829 else
3830 res = 0;
3831
3832 if (store (sd, &code->dst, res))
3833 goto end;
3834 goto next;
3835
3836 case O (O_DIVS, SW): /* divs.w */
3837 if (fetch (sd, &code->src, &ea) ||
3838 fetch (sd, &code->dst, &rd))
3839 goto end;
3840
dc5c3759
MS
3841 if (ea)
3842 {
3843 res = SEXTSHORT (rd) / SEXTSHORT (ea);
3844 nz = 1;
3845 }
3846 else
3847 {
3848 res = 0;
3849 nz = 0;
3850 }
3851
3852 n = res & 0x8000;
3853 if (store (sd, &code->dst, res))
3854 goto end;
3855 goto next;
3856
3857 case O (O_DIVS, SL): /* divs.l */
3858 if (fetch (sd, &code->src, &ea) ||
3859 fetch (sd, &code->dst, &rd))
3860 goto end;
3861
dc5c3759
MS
3862 if (ea)
3863 {
3864 res = rd / ea;
3865 nz = 1;
3866 }
3867 else
3868 {
3869 res = 0;
3870 nz = 0;
3871 }
3872
3873 n = res & 0x80000000;
3874 if (store (sd, &code->dst, res))
3875 goto end;
3876 goto next;
3877
3878 case O (O_DIVXU, SB): /* divxu.b */
3879 if (fetch (sd, &code->src, &ea) ||
3880 fetch (sd, &code->dst, &rd))
3881 goto end;
3882
3883 rd = UEXTSHORT (rd);
3884 ea = UEXTCHAR (ea);
3885
3886 n = ea & 0x80;
3887 nz = ea & 0xff;
3888 if (ea)
3889 {
3890 tmp = (unsigned) rd % ea;
3891 res = (unsigned) rd / ea;
3892 }
3893 else
3894 {
3895 tmp = 0;
3896 res = 0;
3897 }
3898
9f70f8ec 3899 if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
dc5c3759
MS
3900 goto end;
3901 goto next;
3902
3903 case O (O_DIVXU, SW): /* divxu.w */
3904 if (fetch (sd, &code->src, &ea) ||
3905 fetch (sd, &code->dst, &rd))
3906 goto end;
3907
3908 ea = UEXTSHORT (ea);
3909
3910 n = ea & 0x8000;
3911 nz = ea & 0xffff;
3912 if (ea)
3913 {
3914 tmp = (unsigned) rd % ea;
3915 res = (unsigned) rd / ea;
3916 }
3917 else
3918 {
3919 tmp = 0;
3920 res = 0;
3921 }
3922
3923 if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
3924 goto end;
3925 goto next;
3926
3927 case O (O_DIVXS, SB): /* divxs.b */
3928 if (fetch (sd, &code->src, &ea) ||
3929 fetch (sd, &code->dst, &rd))
3930 goto end;
3931
3932 rd = SEXTSHORT (rd);
e073c474 3933 ea = SEXTCHAR (ea);
dc5c3759
MS
3934
3935 if (ea)
3936 {
3937 tmp = (int) rd % (int) ea;
3938 res = (int) rd / (int) ea;
3939 nz = 1;
3940 }
3941 else
3942 {
3943 tmp = 0;
3944 res = 0;
3945 nz = 0;
3946 }
3947
3948 n = res & 0x8000;
3949 if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
3950 goto end;
3951 goto next;
3952
3953 case O (O_DIVXS, SW): /* divxs.w */
3954 if (fetch (sd, &code->src, &ea) ||
3955 fetch (sd, &code->dst, &rd))
3956 goto end;
3957
e073c474 3958 ea = SEXTSHORT (ea);
dc5c3759
MS
3959
3960 if (ea)
3961 {
3962 tmp = (int) rd % (int) ea;
3963 res = (int) rd / (int) ea;
3964 nz = 1;
3965 }
3966 else
3967 {
3968 tmp = 0;
3969 res = 0;
3970 nz = 0;
3971 }
3972
3973 n = res & 0x80000000;
3974 if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
3975 goto end;
3976 goto next;
3977
3978 case O (O_EXTS, SW): /* exts.w, signed extend */
3979 if (fetch2 (sd, &code->dst, &rd))
3980 goto end;
c906108c 3981 ea = rd & 0x80 ? -256 : 0;
dc5c3759 3982 res = (rd & 0xff) + ea;
c906108c 3983 goto log16;
dc5c3759
MS
3984
3985 case O (O_EXTS, SL): /* exts.l, signed extend */
3986 if (fetch2 (sd, &code->dst, &rd))
3987 goto end;
3988 if (code->src.type == X (OP_IMM, SL))
3989 {
3990 if (fetch (sd, &code->src, &ea))
3991 goto end;
3992
3993 if (ea == 2) /* exts.l #2, nn */
3994 {
3995 /* Sign-extend from 8-bit to 32-bit. */
3996 ea = rd & 0x80 ? -256 : 0;
3997 res = (rd & 0xff) + ea;
3998 goto log32;
3999 }
4000 }
4001 /* Sign-extend from 16-bit to 32-bit. */
c906108c 4002 ea = rd & 0x8000 ? -65536 : 0;
dc5c3759 4003 res = (rd & 0xffff) + ea;
c906108c 4004 goto log32;
dc5c3759
MS
4005
4006 case O (O_EXTU, SW): /* extu.w, unsigned extend */
4007 if (fetch2 (sd, &code->dst, &rd))
4008 goto end;
c906108c 4009 ea = 0;
dc5c3759 4010 res = (rd & 0xff) + ea;
c906108c 4011 goto log16;
dc5c3759
MS
4012
4013 case O (O_EXTU, SL): /* extu.l, unsigned extend */
4014 if (fetch2 (sd, &code->dst, &rd))
4015 goto end;
4016 if (code->src.type == X (OP_IMM, SL))
4017 {
4018 if (fetch (sd, &code->src, &ea))
4019 goto end;
4020
4021 if (ea == 2) /* extu.l #2, nn */
4022 {
4023 /* Zero-extend from 8-bit to 32-bit. */
4024 ea = 0;
4025 res = (rd & 0xff) + ea;
4026 goto log32;
4027 }
4028 }
4029 /* Zero-extend from 16-bit to 32-bit. */
c906108c 4030 ea = 0;
dc5c3759 4031 res = (rd & 0xffff) + ea;
c906108c
SS
4032 goto log32;
4033
dc5c3759 4034 case O (O_NOP, SN): /* nop */
c906108c
SS
4035 goto next;
4036
dc5c3759 4037 case O (O_STM, SL): /* stm, store to memory */
c906108c
SS
4038 {
4039 int nregs, firstreg, i;
4040
4041 nregs = GET_MEMORY_B (pc + 1);
4042 nregs >>= 4;
4043 nregs &= 0xf;
dc5c3759 4044 firstreg = code->src.reg;
c906108c
SS
4045 firstreg &= 0xf;
4046 for (i = firstreg; i <= firstreg + nregs; i++)
4047 {
dc5c3759
MS
4048 h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) - 4);
4049 SET_MEMORY_L (h8_get_reg (sd, SP_REGNUM), h8_get_reg (sd, i));
c906108c
SS
4050 }
4051 }
4052 goto next;
4053
dc5c3759 4054 case O (O_LDM, SL): /* ldm, load from memory */
9f70f8ec
MS
4055 case O (O_RTEL, SN): /* rte/l, ldm plus rte */
4056 case O (O_RTSL, SN): /* rts/l, ldm plus rts */
c906108c
SS
4057 {
4058 int nregs, firstreg, i;
4059
9f70f8ec
MS
4060 nregs = ((GET_MEMORY_B (pc + 1) >> 4) & 0xf);
4061 firstreg = code->dst.reg & 0xf;
c906108c
SS
4062 for (i = firstreg; i >= firstreg - nregs; i--)
4063 {
dc5c3759
MS
4064 h8_set_reg (sd, i, GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM)));
4065 h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) + 4);
c906108c
SS
4066 }
4067 }
9f70f8ec
MS
4068 switch (code->opcode) {
4069 case O (O_RTEL, SN):
4070 goto rte;
4071 case O (O_RTSL, SN):
4072 goto rts;
4073 case O (O_LDM, SL):
4074 goto next;
4075 default:
4076 goto illegal;
4077 }
c906108c 4078
b7f97e9c
MS
4079 case O (O_DAA, SB):
4080 /* Decimal Adjust Addition. This is for BCD arithmetic. */
9f70f8ec 4081 res = GET_B_REG (code->src.reg); /* FIXME fetch? */
dc5c3759
MS
4082 if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4083 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
b7f97e9c 4084 res = res; /* Value added == 0. */
dc5c3759
MS
4085 else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8) &&
4086 !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
b7f97e9c 4087 res = res + 0x6; /* Value added == 6. */
dc5c3759
MS
4088 else if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4089 h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
b7f97e9c 4090 res = res + 0x6; /* Value added == 6. */
dc5c3759
MS
4091 else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15) &&
4092 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
4093 res = res + 0x60; /* Value added == 60. */
4094 else if (!c && (9 <= (res >> 4) && (res >> 4) <= 15) &&
4095 !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
4096 res = res + 0x66; /* Value added == 66. */
4097 else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15) &&
4098 h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
4099 res = res + 0x66; /* Value added == 66. */
4100 else if ( c && (1 <= (res >> 4) && (res >> 4) <= 2) &&
4101 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
b7f97e9c 4102 res = res + 0x60; /* Value added == 60. */
dc5c3759
MS
4103 else if ( c && (1 <= (res >> 4) && (res >> 4) <= 2) &&
4104 !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
b7f97e9c 4105 res = res + 0x66; /* Value added == 66. */
dc5c3759
MS
4106 else if (c && (1 <= (res >> 4) && (res >> 4) <= 3) &&
4107 h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
b7f97e9c 4108 res = res + 0x66; /* Value added == 66. */
b7f97e9c
MS
4109
4110 goto alu8;
4111
4112 case O (O_DAS, SB):
4113 /* Decimal Adjust Subtraction. This is for BCD arithmetic. */
4114 res = GET_B_REG (code->src.reg); /* FIXME fetch, fetch2... */
dc5c3759
MS
4115 if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
4116 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
b7f97e9c 4117 res = res; /* Value added == 0. */
dc5c3759
MS
4118 else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8) &&
4119 h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
b7f97e9c 4120 res = res + 0xfa; /* Value added == 0xfa. */
dc5c3759
MS
4121 else if ( c && (7 <= (res >> 4) && (res >> 4) <= 15) &&
4122 !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
b7f97e9c 4123 res = res + 0xa0; /* Value added == 0xa0. */
dc5c3759
MS
4124 else if (c && (6 <= (res >> 4) && (res >> 4) <= 15) &&
4125 h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
b7f97e9c
MS
4126 res = res + 0x9a; /* Value added == 0x9a. */
4127
4128 goto alu8;
4129
c906108c 4130 default:
d0fe2f7e 4131 illegal:
4ca9d09e 4132 sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL);
c906108c
SS
4133 goto end;
4134
4135 }
dc5c3759 4136
c1fc4b4d 4137 sim_io_printf (sd, "sim_resume: internal error.\n");
4ca9d09e 4138 sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL);
dc5c3759 4139 goto end;
c906108c
SS
4140
4141 setc:
dc5c3759
MS
4142 if (code->dst.type == X (OP_CCR, SB) ||
4143 code->dst.type == X (OP_CCR, SW))
c3f4437e 4144 {
dc5c3759 4145 h8_set_ccr (sd, res);
9f70f8ec 4146 GETSR (sd);
c3f4437e 4147 }
dc5c3759
MS
4148 else if (h8300smode &&
4149 (code->dst.type == X (OP_EXR, SB) ||
4150 code->dst.type == X (OP_EXR, SW)))
c3f4437e 4151 {
dc5c3759
MS
4152 h8_set_exr (sd, res);
4153 if (h8300smode) /* Get exr. */
4154 {
4155 trace = (h8_get_exr (sd) >> 7) & 1;
4156 intMask = h8_get_exr (sd) & 7;
4157 }
c3f4437e 4158 }
fc974602 4159 else
c3f4437e 4160 goto illegal;
fc974602 4161
c906108c
SS
4162 goto next;
4163
4164 condtrue:
4165 /* When a branch works */
dc5c3759
MS
4166 if (fetch (sd, &code->src, &res))
4167 goto end;
4168 if (res & 1) /* bad address */
4169 goto illegal;
4170 pc = code->next_pc + res;
c906108c
SS
4171 goto end;
4172
4173 /* Set the cond codes from res */
4174 bitop:
4175
4176 /* Set the flags after an 8 bit inc/dec operation */
4177 just_flags_inc8:
4178 n = res & 0x80;
4179 nz = res & 0xff;
4180 v = (rd & 0x7f) == 0x7f;
4181 goto next;
4182
c906108c
SS
4183 /* Set the flags after an 16 bit inc/dec operation */
4184 just_flags_inc16:
4185 n = res & 0x8000;
4186 nz = res & 0xffff;
4187 v = (rd & 0x7fff) == 0x7fff;
4188 goto next;
4189
c906108c
SS
4190 /* Set the flags after an 32 bit inc/dec operation */
4191 just_flags_inc32:
4192 n = res & 0x80000000;
4193 nz = res & 0xffffffff;
4194 v = (rd & 0x7fffffff) == 0x7fffffff;
4195 goto next;
4196
c906108c
SS
4197 shift8:
4198 /* Set flags after an 8 bit shift op, carry,overflow set in insn */
4199 n = (rd & 0x80);
4200 nz = rd & 0xff;
dc5c3759
MS
4201 if (store2 (sd, &code->dst, rd))
4202 goto end;
c906108c
SS
4203 goto next;
4204
4205 shift16:
4206 /* Set flags after an 16 bit shift op, carry,overflow set in insn */
4207 n = (rd & 0x8000);
4208 nz = rd & 0xffff;
dc5c3759
MS
4209 if (store2 (sd, &code->dst, rd))
4210 goto end;
c906108c
SS
4211 goto next;
4212
4213 shift32:
4214 /* Set flags after an 32 bit shift op, carry,overflow set in insn */
4215 n = (rd & 0x80000000);
4216 nz = rd & 0xffffffff;
dc5c3759
MS
4217 if (store2 (sd, &code->dst, rd))
4218 goto end;
c906108c
SS
4219 goto next;
4220
4221 log32:
dc5c3759
MS
4222 if (store2 (sd, &code->dst, res))
4223 goto end;
4224
c906108c
SS
4225 just_flags_log32:
4226 /* flags after a 32bit logical operation */
4227 n = res & 0x80000000;
4228 nz = res & 0xffffffff;
4229 v = 0;
4230 goto next;
4231
4232 log16:
dc5c3759
MS
4233 if (store2 (sd, &code->dst, res))
4234 goto end;
4235
c906108c
SS
4236 just_flags_log16:
4237 /* flags after a 16bit logical operation */
4238 n = res & 0x8000;
4239 nz = res & 0xffff;
4240 v = 0;
4241 goto next;
4242
c906108c 4243 log8:
dc5c3759
MS
4244 if (store2 (sd, &code->dst, res))
4245 goto end;
4246
c906108c
SS
4247 just_flags_log8:
4248 n = res & 0x80;
4249 nz = res & 0xff;
4250 v = 0;
4251 goto next;
4252
4253 alu8:
dc5c3759
MS
4254 if (store2 (sd, &code->dst, res))
4255 goto end;
4256
c906108c
SS
4257 just_flags_alu8:
4258 n = res & 0x80;
4259 nz = res & 0xff;
4260 c = (res & 0x100);
4261 switch (code->opcode / 4)
4262 {
4263 case O_ADD:
dc5c3759 4264 case O_ADDX:
c906108c
SS
4265 v = ((rd & 0x80) == (ea & 0x80)
4266 && (rd & 0x80) != (res & 0x80));
4267 break;
4268 case O_SUB:
dc5c3759 4269 case O_SUBX:
c906108c
SS
4270 case O_CMP:
4271 v = ((rd & 0x80) != (-ea & 0x80)
4272 && (rd & 0x80) != (res & 0x80));
4273 break;
4274 case O_NEG:
4275 v = (rd == 0x80);
4276 break;
dc5c3759
MS
4277 case O_DAA:
4278 case O_DAS:
4279 break; /* No effect on v flag. */
c906108c
SS
4280 }
4281 goto next;
4282
4283 alu16:
dc5c3759
MS
4284 if (store2 (sd, &code->dst, res))
4285 goto end;
4286
c906108c
SS
4287 just_flags_alu16:
4288 n = res & 0x8000;
4289 nz = res & 0xffff;
4290 c = (res & 0x10000);
4291 switch (code->opcode / 4)
4292 {
4293 case O_ADD:
dc5c3759 4294 case O_ADDX:
c906108c
SS
4295 v = ((rd & 0x8000) == (ea & 0x8000)
4296 && (rd & 0x8000) != (res & 0x8000));
4297 break;
4298 case O_SUB:
dc5c3759 4299 case O_SUBX:
c906108c
SS
4300 case O_CMP:
4301 v = ((rd & 0x8000) != (-ea & 0x8000)
4302 && (rd & 0x8000) != (res & 0x8000));
4303 break;
4304 case O_NEG:
4305 v = (rd == 0x8000);
4306 break;
4307 }
4308 goto next;
4309
4310 alu32:
dc5c3759
MS
4311 if (store2 (sd, &code->dst, res))
4312 goto end;
4313
c906108c
SS
4314 just_flags_alu32:
4315 n = res & 0x80000000;
4316 nz = res & 0xffffffff;
4317 switch (code->opcode / 4)
4318 {
4319 case O_ADD:
dc5c3759 4320 case O_ADDX:
c906108c
SS
4321 v = ((rd & 0x80000000) == (ea & 0x80000000)
4322 && (rd & 0x80000000) != (res & 0x80000000));
dc5c3759
MS
4323 c = ((unsigned) res < (unsigned) rd) ||
4324 ((unsigned) res < (unsigned) ea);
c906108c
SS
4325 break;
4326 case O_SUB:
dc5c3759 4327 case O_SUBX:
c906108c
SS
4328 case O_CMP:
4329 v = ((rd & 0x80000000) != (-ea & 0x80000000)
4330 && (rd & 0x80000000) != (res & 0x80000000));
4331 c = (unsigned) rd < (unsigned) -ea;
4332 break;
4333 case O_NEG:
4334 v = (rd == 0x80000000);
4335 c = res != 0;
4336 break;
4337 }
4338 goto next;
4339
dc5c3759
MS
4340 next:
4341 if ((res = h8_get_delayed_branch (sd)) != 0)
4342 {
4343 pc = res;
4344 h8_set_delayed_branch (sd, 0);
4345 }
4346 else
4347 pc = code->next_pc;
c906108c 4348
4ca9d09e 4349 } while (0);
c906108c 4350
4ca9d09e 4351 end:
dc5c3759
MS
4352 h8_set_ticks (sd, h8_get_ticks (sd) + get_now () - tick_start);
4353 h8_set_cycles (sd, h8_get_cycles (sd) + cycles);
4354 h8_set_insts (sd, h8_get_insts (sd) + insts);
4355 h8_set_pc (sd, pc);
4356 BUILDSR (sd);
4357
4358 if (h8300smode)
4359 h8_set_exr (sd, (trace<<7) | intMask);
4360
4361 h8_set_mask (sd, oldmask);
c906108c
SS
4362}
4363
4ca9d09e
MF
4364void
4365sim_engine_run (SIM_DESC sd,
4366 int next_cpu_nr, /* ignore */
4367 int nr_cpus, /* ignore */
4368 int siggnal)
4369{
4370 sim_cpu *cpu;
4371
4372 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
4373
4374 cpu = STATE_CPU (sd, 0);
4375
4376 while (1)
4377 {
4378 step_once (sd, cpu);
4379 if (sim_events_tick (sd))
4380 sim_events_process (sd);
4381 }
4382}
4383
c906108c 4384int
5558e7e6 4385sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
c906108c
SS
4386{
4387 int i;
4388
dc5c3759 4389 init_pointers (sd);
c906108c
SS
4390 if (addr < 0)
4391 return 0;
4392 for (i = 0; i < size; i++)
4393 {
4394 if (addr < memory_size)
4395 {
dc5c3759 4396 h8_set_memory (sd, addr + i, buffer[i]);
c906108c
SS
4397 }
4398 else
54780889 4399 break;
c906108c 4400 }
54780889 4401 return i;
c906108c
SS
4402}
4403
4404int
a4f27e3e 4405sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
c906108c 4406{
dc5c3759 4407 init_pointers (sd);
c906108c
SS
4408 if (addr < 0)
4409 return 0;
54780889 4410 if (addr + size < memory_size)
dc5c3759 4411 memcpy (buffer, h8_get_memory_buf (sd) + addr, size);
c906108c 4412 else
54780889 4413 return 0;
c906108c
SS
4414 return size;
4415}
4416
e1211e55
MF
4417static int
4418h8300_reg_store (SIM_CPU *cpu, int rn, unsigned char *value, int length)
c906108c
SS
4419{
4420 int longval;
4421 int shortval;
4422 int intval;
4423 longval = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
4424 shortval = (value[0] << 8) | (value[1]);
4425 intval = h8300hmode ? longval : shortval;
4426
2a2757ac 4427 init_pointers (CPU_STATE (cpu));
c906108c
SS
4428 switch (rn)
4429 {
9f70f8ec 4430 case PC_REGNUM:
59768597 4431 if(h8300_normal_mode)
2a2757ac 4432 cpu->pc = shortval; /* PC for Normal mode is 2 bytes */
59768597 4433 else
2a2757ac 4434 cpu->pc = intval;
9f70f8ec 4435 break;
c906108c 4436 default:
2a2757ac 4437 return -1;
c906108c
SS
4438 case R0_REGNUM:
4439 case R1_REGNUM:
4440 case R2_REGNUM:
4441 case R3_REGNUM:
4442 case R4_REGNUM:
4443 case R5_REGNUM:
4444 case R6_REGNUM:
4445 case R7_REGNUM:
c906108c 4446 case CCR_REGNUM:
fc974602 4447 case EXR_REGNUM:
173b1c98 4448 case SBR_REGNUM:
173b1c98 4449 case VBR_REGNUM:
173b1c98 4450 case MACH_REGNUM:
173b1c98 4451 case MACL_REGNUM:
2a2757ac 4452 cpu->regs[rn] = intval;
173b1c98 4453 break;
c906108c 4454 case CYCLE_REGNUM:
c906108c 4455 case INST_REGNUM:
c906108c 4456 case TICK_REGNUM:
2a2757ac 4457 cpu->regs[rn] = longval;
c906108c
SS
4458 break;
4459 }
dae477fe 4460 return length;
c906108c
SS
4461}
4462
e1211e55
MF
4463static int
4464h8300_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *buf, int length)
c906108c
SS
4465{
4466 int v;
4467 int longreg = 0;
4468
2a2757ac 4469 init_pointers (CPU_STATE (cpu));
c906108c 4470
d0fe2f7e 4471 if (!h8300smode && rn >= EXR_REGNUM)
c3f4437e 4472 rn++;
c906108c
SS
4473 switch (rn)
4474 {
4475 default:
2a2757ac
MF
4476 return -1;
4477 case PC_REGNUM:
4478 v = cpu->pc;
dc5c3759 4479 break;
3b02cf92 4480 case CCR_REGNUM:
fc974602 4481 case EXR_REGNUM:
173b1c98 4482 case SBR_REGNUM:
173b1c98 4483 case VBR_REGNUM:
173b1c98 4484 case MACH_REGNUM:
173b1c98 4485 case MACL_REGNUM:
c906108c
SS
4486 case R0_REGNUM:
4487 case R1_REGNUM:
4488 case R2_REGNUM:
4489 case R3_REGNUM:
4490 case R4_REGNUM:
4491 case R5_REGNUM:
4492 case R6_REGNUM:
4493 case R7_REGNUM:
2a2757ac 4494 v = cpu->regs[rn];
c906108c 4495 break;
3b02cf92 4496 case CYCLE_REGNUM:
3b02cf92 4497 case TICK_REGNUM:
3b02cf92 4498 case INST_REGNUM:
2a2757ac 4499 v = cpu->regs[rn];
c906108c
SS
4500 longreg = 1;
4501 break;
2a2757ac
MF
4502 case ZERO_REGNUM:
4503 v = 0;
4504 break;
c906108c 4505 }
59768597
SA
4506 /* In Normal mode PC is 2 byte, but other registers are 4 byte */
4507 if ((h8300hmode || longreg) && !(rn == PC_REGNUM && h8300_normal_mode))
c906108c
SS
4508 {
4509 buf[0] = v >> 24;
4510 buf[1] = v >> 16;
4511 buf[2] = v >> 8;
4512 buf[3] = v >> 0;
2a2757ac 4513 return 4;
c906108c
SS
4514 }
4515 else
4516 {
4517 buf[0] = v >> 8;
4518 buf[1] = v;
2a2757ac 4519 return 2;
c906108c 4520 }
c906108c
SS
4521}
4522
c906108c 4523void
a4f27e3e 4524sim_info (SIM_DESC sd, int verbose)
c906108c 4525{
dc5c3759
MS
4526 double timetaken = (double) h8_get_ticks (sd) / (double) now_persec ();
4527 double virttime = h8_get_cycles (sd) / 10.0e6;
c906108c 4528
c1fc4b4d
MF
4529 sim_io_printf (sd, "\n\n#instructions executed %10d\n", h8_get_insts (sd));
4530 sim_io_printf (sd, "#cycles (v approximate) %10d\n", h8_get_cycles (sd));
4531 sim_io_printf (sd, "#real time taken %10.4f\n", timetaken);
4532 sim_io_printf (sd, "#virtual time taken %10.4f\n", virttime);
c906108c 4533 if (timetaken != 0.0)
c1fc4b4d 4534 sim_io_printf (sd, "#simulation ratio %10.4f\n", virttime / timetaken);
c906108c
SS
4535
4536#ifdef ADEBUG
4537 /* This to be conditional on `what' (aka `verbose'),
4538 however it was never passed as non-zero. */
4539 if (1)
4540 {
4541 int i;
4542 for (i = 0; i < O_LAST; i++)
4543 {
dc5c3759 4544 if (h8_get_stats (sd, i))
c1fc4b4d 4545 sim_io_printf (sd, "%d: %d\n", i, h8_get_stats (sd, i));
c906108c
SS
4546 }
4547 }
4548#endif
4549}
4550
2ea716f6
KH
4551/* Indicate whether the cpu is an H8/300 or H8/300H.
4552 FLAG is non-zero for the H8/300H. */
c906108c
SS
4553
4554void
27ebfdf4 4555set_h8300h (unsigned long machine)
c906108c
SS
4556{
4557 /* FIXME: Much of the code in sim_load can be moved to sim_open.
4558 This function being replaced by a sim_open:ARGV configuration
2ea716f6 4559 option. */
dc5c3759 4560
454d0511
DD
4561 h8300hmode = h8300smode = h8300sxmode = h8300_normal_mode = 0;
4562
9f70f8ec 4563 if (machine == bfd_mach_h8300sx || machine == bfd_mach_h8300sxn)
27ebfdf4
MS
4564 h8300sxmode = 1;
4565
4566 if (machine == bfd_mach_h8300s || machine == bfd_mach_h8300sn || h8300sxmode)
4567 h8300smode = 1;
4568
4569 if (machine == bfd_mach_h8300h || machine == bfd_mach_h8300hn || h8300smode)
4570 h8300hmode = 1;
59768597
SA
4571
4572 if(machine == bfd_mach_h8300hn || machine == bfd_mach_h8300sn || machine == bfd_mach_h8300sxn)
4573 h8300_normal_mode = 1;
dc5c3759
MS
4574}
4575
bd3fb5b8
MF
4576/* H8300-specific options.
4577 TODO: These really should be merged into the common model modules. */
4578typedef enum {
4579 OPTION_H8300H,
4580 OPTION_H8300S,
4581 OPTION_H8300SX
4582} H8300_OPTIONS;
4583
4584static SIM_RC
4585h8300_option_handler (SIM_DESC sd, sim_cpu *cpu ATTRIBUTE_UNUSED, int opt,
4586 char *arg, int is_command ATTRIBUTE_UNUSED)
4587{
4588 switch ((H8300_OPTIONS) opt)
4589 {
4590 case OPTION_H8300H:
4591 set_h8300h (bfd_mach_h8300h);
4592 break;
4593 case OPTION_H8300S:
4594 set_h8300h (bfd_mach_h8300s);
4595 break;
4596 case OPTION_H8300SX:
4597 set_h8300h (bfd_mach_h8300sx);
4598 break;
4599
4600 default:
4601 /* We'll actually never get here; the caller handles the error
4602 case. */
4603 sim_io_eprintf (sd, "Unknown option `%s'\n", arg);
4604 return SIM_RC_FAIL;
4605 }
4606
4607 return SIM_RC_OK;
4608}
4609
4610static const OPTION h8300_options[] =
4611{
4612 { {"h8300h", no_argument, NULL, OPTION_H8300H},
4613 'h', NULL, "Indicate the CPU is H8/300H",
4614 h8300_option_handler },
4615 { {"h8300s", no_argument, NULL, OPTION_H8300S},
4616 'S', NULL, "Indicate the CPU is H8S",
4617 h8300_option_handler },
4618 { {"h8300sx", no_argument, NULL, OPTION_H8300SX},
4619 'x', NULL, "Indicate the CPU is H8SX",
4620 h8300_option_handler },
4621 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
4622};
4623
27b97b40
MF
4624static sim_cia
4625h8300_pc_get (sim_cpu *cpu)
4626{
4627 return cpu->pc;
4628}
4629
4630static void
4631h8300_pc_set (sim_cpu *cpu, sim_cia pc)
4632{
4633 cpu->pc = pc;
4634}
4635
dc5c3759
MS
4636/* Cover function of sim_state_free to free the cpu buffers as well. */
4637
4638static void
4639free_state (SIM_DESC sd)
4640{
4641 if (STATE_MODULES (sd) != NULL)
4642 sim_module_uninstall (sd);
4643
4644 /* Fixme: free buffers in _sim_cpu. */
4645 sim_state_free (sd);
c906108c
SS
4646}
4647
4648SIM_DESC
a4f27e3e 4649sim_open (SIM_OPEN_KIND kind,
dc5c3759 4650 struct host_callback_struct *callback,
6b4a8935 4651 struct bfd *abfd,
2e3d4f4d 4652 char * const *argv)
c906108c 4653{
27b97b40 4654 int i;
dc5c3759
MS
4655 SIM_DESC sd;
4656 sim_cpu *cpu;
4657
4658 sd = sim_state_alloc (kind, callback);
f95f4ed2
MF
4659
4660 /* The cpu data is kept in a separately allocated chunk of memory. */
4661 if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
4662 {
4663 free_state (sd);
4664 return 0;
4665 }
4666
dc5c3759
MS
4667 cpu = STATE_CPU (sd, 0);
4668 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
cec99e6b 4669 cpu->regs[SBR_REGNUM] = 0xFFFFFF00;
dc5c3759
MS
4670 /* sim_cpu object is new, so some initialization is needed. */
4671 init_pointers_needed = 1;
4672
dc5c3759
MS
4673 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
4674 {
4675 free_state (sd);
4676 return 0;
4677 }
4678
bd3fb5b8
MF
4679 if (sim_add_option_table (sd, NULL, h8300_options) != SIM_RC_OK)
4680 {
4681 free_state (sd);
4682 return 0;
4683 }
4684
77cf2ef5 4685 /* The parser will print an error message for us, so we silently return. */
dc5c3759
MS
4686 if (sim_parse_args (sd, argv) != SIM_RC_OK)
4687 {
4688 /* Uninstall the modules to avoid memory leaks,
4689 file descriptor leaks, etc. */
4690 free_state (sd);
4691 return 0;
4692 }
4693
4694 /* Check for/establish the a reference program image. */
4695 if (sim_analyze_program (sd,
4696 (STATE_PROG_ARGV (sd) != NULL
4697 ? *STATE_PROG_ARGV (sd)
4698 : NULL), abfd) != SIM_RC_OK)
4699 {
4700 free_state (sd);
4701 return 0;
4702 }
4703
4704 /* Establish any remaining configuration options. */
4705 if (sim_config (sd) != SIM_RC_OK)
4706 {
4707 free_state (sd);
4708 return 0;
4709 }
4710
4711 if (sim_post_argv_init (sd) != SIM_RC_OK)
4712 {
4713 /* Uninstall the modules to avoid memory leaks,
4714 file descriptor leaks, etc. */
4715 free_state (sd);
4716 return 0;
4717 }
4718
27b97b40
MF
4719 /* CPU specific initialization. */
4720 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
4721 {
4722 SIM_CPU *cpu = STATE_CPU (sd, i);
4723
e1211e55
MF
4724 CPU_REG_FETCH (cpu) = h8300_reg_fetch;
4725 CPU_REG_STORE (cpu) = h8300_reg_store;
27b97b40
MF
4726 CPU_PC_FETCH (cpu) = h8300_pc_get;
4727 CPU_PC_STORE (cpu) = h8300_pc_set;
4728 }
4729
dc5c3759
MS
4730 /* sim_hw_configure (sd); */
4731
2ea716f6 4732 /* FIXME: Much of the code in sim_load can be moved here. */
c906108c 4733
dc5c3759 4734 return sd;
c906108c
SS
4735}
4736
c906108c
SS
4737/* Called by gdb to load a program into memory. */
4738
4739SIM_RC
b2b255bd 4740sim_load (SIM_DESC sd, const char *prog, bfd *abfd, int from_tty)
c906108c
SS
4741{
4742 bfd *prog_bfd;
4743
2ea716f6
KH
4744 /* FIXME: The code below that sets a specific variant of the H8/300
4745 being simulated should be moved to sim_open(). */
c906108c 4746
2ea716f6 4747 /* See if the file is for the H8/300 or H8/300H. */
c906108c
SS
4748 /* ??? This may not be the most efficient way. The z8k simulator
4749 does this via a different mechanism (INIT_EXTRA_SYMTAB_INFO). */
4750 if (abfd != NULL)
4751 prog_bfd = abfd;
4752 else
3d29fdb4 4753 prog_bfd = bfd_openr (prog, NULL);
c906108c
SS
4754 if (prog_bfd != NULL)
4755 {
4756 /* Set the cpu type. We ignore failure from bfd_check_format
4757 and bfd_openr as sim_load_file checks too. */
de9b1892 4758 if (bfd_check_format (prog_bfd, bfd_object))
c906108c 4759 {
27ebfdf4 4760 set_h8300h (bfd_get_mach (prog_bfd));
c906108c
SS
4761 }
4762 }
4763
4764 /* If we're using gdb attached to the simulator, then we have to
4765 reallocate memory for the simulator.
4766
4767 When gdb first starts, it calls fetch_registers (among other
4768 functions), which in turn calls init_pointers, which allocates
4769 simulator memory.
4770
4771 The problem is when we do that, we don't know whether we're
2ea716f6 4772 debugging an H8/300 or H8/300H program.
c906108c
SS
4773
4774 This is the first point at which we can make that determination,
4775 so we just reallocate memory now; this will also allow us to handle
2ea716f6 4776 switching between H8/300 and H8/300H programs without exiting
c906108c 4777 gdb. */
a8cdafbd 4778
59768597 4779 if (h8300smode && !h8300_normal_mode)
a8cdafbd 4780 memory_size = H8300S_MSIZE;
59768597 4781 else if (h8300hmode && !h8300_normal_mode)
c906108c
SS
4782 memory_size = H8300H_MSIZE;
4783 else
4784 memory_size = H8300_MSIZE;
4785
dc5c3759
MS
4786 if (h8_get_memory_buf (sd))
4787 free (h8_get_memory_buf (sd));
c906108c 4788
dc5c3759
MS
4789 h8_set_memory_buf (sd, (unsigned char *)
4790 calloc (sizeof (char), memory_size));
e4d3c499 4791 sd->memory_size = memory_size;
c906108c 4792
2ea716f6 4793 /* `msize' must be a power of two. */
c906108c 4794 if ((memory_size & (memory_size - 1)) != 0)
dc5c3759 4795 {
c1fc4b4d 4796 sim_io_printf (sd, "sim_load: bad memory size.\n");
dc5c3759
MS
4797 return SIM_RC_FAIL;
4798 }
4799 h8_set_mask (sd, memory_size - 1);
c906108c 4800
c1fc4b4d
MF
4801 if (sim_load_file (sd, STATE_MY_NAME (sd), STATE_CALLBACK (sd), prog,
4802 prog_bfd, STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG,
c906108c
SS
4803 0, sim_write)
4804 == NULL)
4805 {
4806 /* Close the bfd if we opened it. */
4807 if (abfd == NULL && prog_bfd != NULL)
4808 bfd_close (prog_bfd);
4809 return SIM_RC_FAIL;
4810 }
4811
4812 /* Close the bfd if we opened it. */
4813 if (abfd == NULL && prog_bfd != NULL)
4814 bfd_close (prog_bfd);
4815 return SIM_RC_OK;
4816}
4817
4818SIM_RC
2e3d4f4d
MF
4819sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
4820 char * const *argv, char * const *env)
c906108c 4821{
d1360fb0
V
4822 int i = 0;
4823 int len_arg = 0;
4824 int no_of_args = 0;
dc5c3759 4825
c906108c 4826 if (abfd != NULL)
dc5c3759 4827 h8_set_pc (sd, bfd_get_start_address (abfd));
c906108c 4828 else
dc5c3759 4829 h8_set_pc (sd, 0);
d1360fb0
V
4830
4831 /* Command Line support. */
4832 if (argv != NULL)
4833 {
4834 /* Counting the no. of commandline arguments. */
4835 for (no_of_args = 0; argv[no_of_args] != NULL; no_of_args++)
4836 continue;
4837
4838 /* Allocating memory for the argv pointers. */
dc5c3759
MS
4839 h8_set_command_line (sd, (char **) malloc ((sizeof (char *))
4840 * (no_of_args + 1)));
d1360fb0
V
4841
4842 for (i = 0; i < no_of_args; i++)
4843 {
d1360fb0 4844 /* Copying the argument string. */
dc5c3759 4845 h8_set_cmdline_arg (sd, i, (char *) strdup (argv[i]));
d1360fb0 4846 }
dc5c3759 4847 h8_set_cmdline_arg (sd, i, NULL);
d1360fb0
V
4848 }
4849
c906108c
SS
4850 return SIM_RC_OK;
4851}