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